prompt: We are currently solving the following issue within our repository. Here is the issue text:
  --- BEGIN ISSUE ---
  7.10 breaking tests with exception  in publish
  The new 7.10 release is breaking Bokeh unit tests with an exception coming from within ipython:
  ```
  
  self = <IPython.core.displaypub.DisplayPublisher object at 0x11883d7f0>
  data = {'text/html': '\n    <div class="bk-root">\n        <a href="https://bokeh.org" target="_blank" class="bk-logo bk-logo...version \'1.0\' from Bokeh development version \'1.0-1-abc\'. This configuration is unsupported and may not work!</p>'}
  metadata = None, source = None, transient = None, update = False, kwargs = {}
  handlers = {}
  
  << omitted >>
  
          handlers = {}
          if self.shell is not None:
  >           handlers = self.shell.mime_renderers
  E           AttributeError: 'InteractiveShell' object has no attribute 'mime_renderers'
  
  ../miniconda/envs/testenv/lib/python3.6/site-packages/IPython/core/displaypub.py:108: AttributeError
  ```
  
  Is this an intentional change (documented anwhere?) or a regression/bug?
  
  cc @Carreau 
  
  --- END ISSUE ---
  
  Below are some code segments, each from a relevant file. One or more of these files may contain bugs.
  --- BEGIN FILES ---
  Path: `IPython/core/displaypub.py`
  Content:
  ```
  1 """An interface for publishing rich data to frontends.
  2 
  3 There are two components of the display system:
  4 
  5 * Display formatters, which take a Python object and compute the
  6   representation of the object in various formats (text, HTML, SVG, etc.).
  7 * The display publisher that is used to send the representation data to the
  8   various frontends.
  9 
  10 This module defines the logic display publishing. The display publisher uses
  11 the ``display_data`` message type that is defined in the IPython messaging
  12 spec.
  13 """
  14 
  15 # Copyright (c) IPython Development Team.
  16 # Distributed under the terms of the Modified BSD License.
  17 
  18 
  19 import sys
  20 
  21 from traitlets.config.configurable import Configurable
  22 from traitlets import List, Dict
  23 
  24 # This used to be defined here - it is imported for backwards compatibility
  25 from .display import publish_display_data
  26 
  27 #-----------------------------------------------------------------------------
  28 # Main payload class
  29 #-----------------------------------------------------------------------------
  30 
  31 
  32 class DisplayPublisher(Configurable):
  33     """A traited class that publishes display data to frontends.
  34 
  35     Instances of this class are created by the main IPython object and should
  36     be accessed there.
  37     """
  38 
  39     def __init__(self, shell=None, *args, **kwargs):
  40         self.shell = shell
  41         super().__init__(*args, **kwargs)
  42 
  43     def _validate_data(self, data, metadata=None):
  44         """Validate the display data.
  45 
  46         Parameters
  47         ----------
  48         data : dict
  49             The formata data dictionary.
  50         metadata : dict
  51             Any metadata for the data.
  52         """
  53 
  54         if not isinstance(data, dict):
  55             raise TypeError('data must be a dict, got: %r' % data)
  56         if metadata is not None:
  57             if not isinstance(metadata, dict):
  58                 raise TypeError('metadata must be a dict, got: %r' % data)
  59 
  60     # use * to indicate transient, update are keyword-only
  61     def publish(self, data, metadata=None, source=None, *, transient=None, update=False, **kwargs) -> None:
  62         """Publish data and metadata to all frontends.
  63 
  64         See the ``display_data`` message in the messaging documentation for
  65         more details about this message type.
  66 
  67         The following MIME types are currently implemented:
  68 
  69         * text/plain
  70         * text/html
  71         * text/markdown
  72         * text/latex
  73         * application/json
  74         * application/javascript
  75         * image/png
  76         * image/jpeg
  77         * image/svg+xml
  78 
  79         Parameters
  80         ----------
  81         data : dict
  82             A dictionary having keys that are valid MIME types (like
  83             'text/plain' or 'image/svg+xml') and values that are the data for
  84             that MIME type. The data itself must be a JSON'able data
  85             structure. Minimally all data should have the 'text/plain' data,
  86             which can be displayed by all frontends. If more than the plain
  87             text is given, it is up to the frontend to decide which
  88             representation to use.
  89         metadata : dict
  90             A dictionary for metadata related to the data. This can contain
  91             arbitrary key, value pairs that frontends can use to interpret
  92             the data.  Metadata specific to each mime-type can be specified
  93             in the metadata dict with the same mime-type keys as
  94             the data itself.
  95         source : str, deprecated
  96             Unused.
  97         transient: dict, keyword-only
  98             A dictionary for transient data.
  99             Data in this dictionary should not be persisted as part of saving this output.
  100             Examples include 'display_id'.
  101         update: bool, keyword-only, default: False
  102             If True, only update existing outputs with the same display_id,
  103             rather than creating a new output.
  104         """
  105 
  106         handlers = {}
  107         if self.shell is not None:
  108             handlers = self.shell.mime_renderers
  109 
  110         for mime, handler in handlers.items():
  111             if mime in data:
  112                 handler(data[mime], metadata.get(mime, None))
  113                 return
  114 
  115         if 'text/plain' in data:
  116             print(data['text/plain'])
  117 
  118     def clear_output(self, wait=False):
  119         """Clear the output of the cell receiving output."""
  120         print('\033[2K\r', end='')
  121         sys.stdout.flush()
  122         print('\033[2K\r', end='')
  123         sys.stderr.flush()
  124 
  125 
  126 class CapturingDisplayPublisher(DisplayPublisher):
  127     """A DisplayPublisher that stores"""
  128     outputs = List()
  129 
  130     def publish(self, data, metadata=None, source=None, *, transient=None, update=False):
  131         self.outputs.append({'data':data, 'metadata':metadata,
  132                              'transient':transient, 'update':update})
  133 
  134     def clear_output(self, wait=False):
  135         super(CapturingDisplayPublisher, self).clear_output(wait)
  136 
  137         # empty the list, *do not* reassign a new list
  138         self.outputs.clear()
  139
  ```
  --- END FILES ---
  
  Please first localize the bug based on the issue statement, and then generate a patch according to the `git diff` format fenced by three backticks.
  
  Here is an example:
  
  ```diff
  diff --git a/examples/server_async.py b/examples/server_async.py
  --- a/examples/server_async.py
  +++ b/examples/server_async.py
  @@ -313,4 +313,4 @@
   
   
   if __name__ == "__main__":
  -    asyncio.run(run_async_server("."), debug=True)
  +    asyncio.run(run_async_server(), debug=True)
  diff --git a/examples/server_sync.py b/examples/server_sync.py
  --- a/examples/server_sync.py
  +++ b/examples/server_sync.py
  @@ -313,5 +313,5 @@
   
   
   if __name__ == "__main__":
  -    server = run_sync_server(".")
  +    server = run_sync_server()
       server.shutdown()
  
  ```
  
golden_diff: diff --git a/IPython/core/displaypub.py b/IPython/core/displaypub.py
  --- a/IPython/core/displaypub.py
  +++ b/IPython/core/displaypub.py
  @@ -105,7 +105,7 @@
   
           handlers = {}
           if self.shell is not None:
  -            handlers = self.shell.mime_renderers
  +            handlers = getattr(self.shell, 'mime_renderers', {})
   
           for mime, handler in handlers.items():
               if mime in data:
  
verification_info: {"golden_diff": "diff --git a/IPython/core/displaypub.py b/IPython/core/displaypub.py\n--- a/IPython/core/displaypub.py\n+++ b/IPython/core/displaypub.py\n@@ -105,7 +105,7 @@\n \n         handlers = {}\n         if self.shell is not None:\n-            handlers = self.shell.mime_renderers\n+            handlers = getattr(self.shell, 'mime_renderers', {})\n \n         for mime, handler in handlers.items():\n             if mime in data:\n", "issue": "7.10 breaking tests with exception  in publish\nThe new 7.10 release is breaking Bokeh unit tests with an exception coming from within ipython:\r\n```\r\n\r\nself = <IPython.core.displaypub.DisplayPublisher object at 0x11883d7f0>\r\ndata = {'text/html': '\\n    <div class=\"bk-root\">\\n        <a href=\"https://bokeh.org\" target=\"_blank\" class=\"bk-logo bk-logo...version \\'1.0\\' from Bokeh development version \\'1.0-1-abc\\'. This configuration is unsupported and may not work!</p>'}\r\nmetadata = None, source = None, transient = None, update = False, kwargs = {}\r\nhandlers = {}\r\n\r\n<< omitted >>\r\n\r\n        handlers = {}\r\n        if self.shell is not None:\r\n>           handlers = self.shell.mime_renderers\r\nE           AttributeError: 'InteractiveShell' object has no attribute 'mime_renderers'\r\n\r\n../miniconda/envs/testenv/lib/python3.6/site-packages/IPython/core/displaypub.py:108: AttributeError\r\n```\r\n\r\nIs this an intentional change (documented anwhere?) or a regression/bug?\r\n\r\ncc @Carreau \n", "before_files": [{"content": "\"\"\"An interface for publishing rich data to frontends.\n\nThere are two components of the display system:\n\n* Display formatters, which take a Python object and compute the\n  representation of the object in various formats (text, HTML, SVG, etc.).\n* The display publisher that is used to send the representation data to the\n  various frontends.\n\nThis module defines the logic display publishing. The display publisher uses\nthe ``display_data`` message type that is defined in the IPython messaging\nspec.\n\"\"\"\n\n# Copyright (c) IPython Development Team.\n# Distributed under the terms of the Modified BSD License.\n\n\nimport sys\n\nfrom traitlets.config.configurable import Configurable\nfrom traitlets import List, Dict\n\n# This used to be defined here - it is imported for backwards compatibility\nfrom .display import publish_display_data\n\n#-----------------------------------------------------------------------------\n# Main payload class\n#-----------------------------------------------------------------------------\n\n\nclass DisplayPublisher(Configurable):\n    \"\"\"A traited class that publishes display data to frontends.\n\n    Instances of this class are created by the main IPython object and should\n    be accessed there.\n    \"\"\"\n\n    def __init__(self, shell=None, *args, **kwargs):\n        self.shell = shell\n        super().__init__(*args, **kwargs)\n\n    def _validate_data(self, data, metadata=None):\n        \"\"\"Validate the display data.\n\n        Parameters\n        ----------\n        data : dict\n            The formata data dictionary.\n        metadata : dict\n            Any metadata for the data.\n        \"\"\"\n\n        if not isinstance(data, dict):\n            raise TypeError('data must be a dict, got: %r' % data)\n        if metadata is not None:\n            if not isinstance(metadata, dict):\n                raise TypeError('metadata must be a dict, got: %r' % data)\n\n    # use * to indicate transient, update are keyword-only\n    def publish(self, data, metadata=None, source=None, *, transient=None, update=False, **kwargs) -> None:\n        \"\"\"Publish data and metadata to all frontends.\n\n        See the ``display_data`` message in the messaging documentation for\n        more details about this message type.\n\n        The following MIME types are currently implemented:\n\n        * text/plain\n        * text/html\n        * text/markdown\n        * text/latex\n        * application/json\n        * application/javascript\n        * image/png\n        * image/jpeg\n        * image/svg+xml\n\n        Parameters\n        ----------\n        data : dict\n            A dictionary having keys that are valid MIME types (like\n            'text/plain' or 'image/svg+xml') and values that are the data for\n            that MIME type. The data itself must be a JSON'able data\n            structure. Minimally all data should have the 'text/plain' data,\n            which can be displayed by all frontends. If more than the plain\n            text is given, it is up to the frontend to decide which\n            representation to use.\n        metadata : dict\n            A dictionary for metadata related to the data. This can contain\n            arbitrary key, value pairs that frontends can use to interpret\n            the data.  Metadata specific to each mime-type can be specified\n            in the metadata dict with the same mime-type keys as\n            the data itself.\n        source : str, deprecated\n            Unused.\n        transient: dict, keyword-only\n            A dictionary for transient data.\n            Data in this dictionary should not be persisted as part of saving this output.\n            Examples include 'display_id'.\n        update: bool, keyword-only, default: False\n            If True, only update existing outputs with the same display_id,\n            rather than creating a new output.\n        \"\"\"\n\n        handlers = {}\n        if self.shell is not None:\n            handlers = self.shell.mime_renderers\n\n        for mime, handler in handlers.items():\n            if mime in data:\n                handler(data[mime], metadata.get(mime, None))\n                return\n\n        if 'text/plain' in data:\n            print(data['text/plain'])\n\n    def clear_output(self, wait=False):\n        \"\"\"Clear the output of the cell receiving output.\"\"\"\n        print('\\033[2K\\r', end='')\n        sys.stdout.flush()\n        print('\\033[2K\\r', end='')\n        sys.stderr.flush()\n\n\nclass CapturingDisplayPublisher(DisplayPublisher):\n    \"\"\"A DisplayPublisher that stores\"\"\"\n    outputs = List()\n\n    def publish(self, data, metadata=None, source=None, *, transient=None, update=False):\n        self.outputs.append({'data':data, 'metadata':metadata,\n                             'transient':transient, 'update':update})\n\n    def clear_output(self, wait=False):\n        super(CapturingDisplayPublisher, self).clear_output(wait)\n\n        # empty the list, *do not* reassign a new list\n        self.outputs.clear()\n", "path": "IPython/core/displaypub.py"}], "after_files": [{"content": "\"\"\"An interface for publishing rich data to frontends.\n\nThere are two components of the display system:\n\n* Display formatters, which take a Python object and compute the\n  representation of the object in various formats (text, HTML, SVG, etc.).\n* The display publisher that is used to send the representation data to the\n  various frontends.\n\nThis module defines the logic display publishing. The display publisher uses\nthe ``display_data`` message type that is defined in the IPython messaging\nspec.\n\"\"\"\n\n# Copyright (c) IPython Development Team.\n# Distributed under the terms of the Modified BSD License.\n\n\nimport sys\n\nfrom traitlets.config.configurable import Configurable\nfrom traitlets import List, Dict\n\n# This used to be defined here - it is imported for backwards compatibility\nfrom .display import publish_display_data\n\n#-----------------------------------------------------------------------------\n# Main payload class\n#-----------------------------------------------------------------------------\n\n\nclass DisplayPublisher(Configurable):\n    \"\"\"A traited class that publishes display data to frontends.\n\n    Instances of this class are created by the main IPython object and should\n    be accessed there.\n    \"\"\"\n\n    def __init__(self, shell=None, *args, **kwargs):\n        self.shell = shell\n        super().__init__(*args, **kwargs)\n\n    def _validate_data(self, data, metadata=None):\n        \"\"\"Validate the display data.\n\n        Parameters\n        ----------\n        data : dict\n            The formata data dictionary.\n        metadata : dict\n            Any metadata for the data.\n        \"\"\"\n\n        if not isinstance(data, dict):\n            raise TypeError('data must be a dict, got: %r' % data)\n        if metadata is not None:\n            if not isinstance(metadata, dict):\n                raise TypeError('metadata must be a dict, got: %r' % data)\n\n    # use * to indicate transient, update are keyword-only\n    def publish(self, data, metadata=None, source=None, *, transient=None, update=False, **kwargs) -> None:\n        \"\"\"Publish data and metadata to all frontends.\n\n        See the ``display_data`` message in the messaging documentation for\n        more details about this message type.\n\n        The following MIME types are currently implemented:\n\n        * text/plain\n        * text/html\n        * text/markdown\n        * text/latex\n        * application/json\n        * application/javascript\n        * image/png\n        * image/jpeg\n        * image/svg+xml\n\n        Parameters\n        ----------\n        data : dict\n            A dictionary having keys that are valid MIME types (like\n            'text/plain' or 'image/svg+xml') and values that are the data for\n            that MIME type. The data itself must be a JSON'able data\n            structure. Minimally all data should have the 'text/plain' data,\n            which can be displayed by all frontends. If more than the plain\n            text is given, it is up to the frontend to decide which\n            representation to use.\n        metadata : dict\n            A dictionary for metadata related to the data. This can contain\n            arbitrary key, value pairs that frontends can use to interpret\n            the data.  Metadata specific to each mime-type can be specified\n            in the metadata dict with the same mime-type keys as\n            the data itself.\n        source : str, deprecated\n            Unused.\n        transient: dict, keyword-only\n            A dictionary for transient data.\n            Data in this dictionary should not be persisted as part of saving this output.\n            Examples include 'display_id'.\n        update: bool, keyword-only, default: False\n            If True, only update existing outputs with the same display_id,\n            rather than creating a new output.\n        \"\"\"\n\n        handlers = {}\n        if self.shell is not None:\n            handlers = getattr(self.shell, 'mime_renderers', {})\n\n        for mime, handler in handlers.items():\n            if mime in data:\n                handler(data[mime], metadata.get(mime, None))\n                return\n\n        if 'text/plain' in data:\n            print(data['text/plain'])\n\n    def clear_output(self, wait=False):\n        \"\"\"Clear the output of the cell receiving output.\"\"\"\n        print('\\033[2K\\r', end='')\n        sys.stdout.flush()\n        print('\\033[2K\\r', end='')\n        sys.stderr.flush()\n\n\nclass CapturingDisplayPublisher(DisplayPublisher):\n    \"\"\"A DisplayPublisher that stores\"\"\"\n    outputs = List()\n\n    def publish(self, data, metadata=None, source=None, *, transient=None, update=False):\n        self.outputs.append({'data':data, 'metadata':metadata,\n                             'transient':transient, 'update':update})\n\n    def clear_output(self, wait=False):\n        super(CapturingDisplayPublisher, self).clear_output(wait)\n\n        # empty the list, *do not* reassign a new list\n        self.outputs.clear()\n", "path": "IPython/core/displaypub.py"}]}