We are currently solving the following issue within our repository. Here is the issue text:
--- BEGIN ISSUE ---
Output for semicolon-terminated lines with comments
cf https://github.com/JuliaLang/IJulia.jl/issues/109

The output of a semicolon-terminated line with comment is not suppressed in IPython.

```
b = 1
b; # foo
```

give `Out[13]: 1`

```
b = 1
b;
```

does not.

Havent found such and issue on our tracker.

 @takluyver you are the best with the input machinery and coroutines; Thoughts ?

(Because of the comment @stevengj in sus-cited issue, marking as prio-high, but won't  mind if priority decreased later, or not fixed)


--- 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/displayhook.py`
Content:
```
1 # -*- coding: utf-8 -*-
2 """Displayhook for IPython.
3 
4 This defines a callable class that IPython uses for `sys.displayhook`.
5 """
6 
7 # Copyright (c) IPython Development Team.
8 # Distributed under the terms of the Modified BSD License.
9 
10 from __future__ import print_function
11 
12 import sys
13 import io as _io
14 import tokenize
15 
16 from IPython.core.formatters import _safe_get_formatter_method
17 from traitlets.config.configurable import Configurable
18 from IPython.utils import io
19 from IPython.utils.py3compat import builtin_mod, cast_unicode_py2
20 from traitlets import Instance, Float
21 from IPython.utils.warn import warn
22 
23 # TODO: Move the various attributes (cache_size, [others now moved]). Some
24 # of these are also attributes of InteractiveShell. They should be on ONE object
25 # only and the other objects should ask that one object for their values.
26 
27 class DisplayHook(Configurable):
28     """The custom IPython displayhook to replace sys.displayhook.
29 
30     This class does many things, but the basic idea is that it is a callable
31     that gets called anytime user code returns a value.
32     """
33 
34     shell = Instance('IPython.core.interactiveshell.InteractiveShellABC',
35                      allow_none=True)
36     exec_result = Instance('IPython.core.interactiveshell.ExecutionResult',
37                            allow_none=True)
38     cull_fraction = Float(0.2)
39 
40     def __init__(self, shell=None, cache_size=1000, **kwargs):
41         super(DisplayHook, self).__init__(shell=shell, **kwargs)
42         cache_size_min = 3
43         if cache_size <= 0:
44             self.do_full_cache = 0
45             cache_size = 0
46         elif cache_size < cache_size_min:
47             self.do_full_cache = 0
48             cache_size = 0
49             warn('caching was disabled (min value for cache size is %s).' %
50                  cache_size_min,level=3)
51         else:
52             self.do_full_cache = 1
53 
54         self.cache_size = cache_size
55 
56         # we need a reference to the user-level namespace
57         self.shell = shell
58         
59         self._,self.__,self.___ = '','',''
60 
61         # these are deliberately global:
62         to_user_ns = {'_':self._,'__':self.__,'___':self.___}
63         self.shell.user_ns.update(to_user_ns)
64 
65     @property
66     def prompt_count(self):
67         return self.shell.execution_count
68 
69     #-------------------------------------------------------------------------
70     # Methods used in __call__. Override these methods to modify the behavior
71     # of the displayhook.
72     #-------------------------------------------------------------------------
73 
74     def check_for_underscore(self):
75         """Check if the user has set the '_' variable by hand."""
76         # If something injected a '_' variable in __builtin__, delete
77         # ipython's automatic one so we don't clobber that.  gettext() in
78         # particular uses _, so we need to stay away from it.
79         if '_' in builtin_mod.__dict__:
80             try:
81                 del self.shell.user_ns['_']
82             except KeyError:
83                 pass
84 
85     def quiet(self):
86         """Should we silence the display hook because of ';'?"""
87         # do not print output if input ends in ';'
88         
89         try:
90             cell = cast_unicode_py2(self.shell.history_manager.input_hist_parsed[-1])
91         except IndexError:
92             # some uses of ipshellembed may fail here
93             return False
94         
95         sio = _io.StringIO(cell)
96         tokens = list(tokenize.generate_tokens(sio.readline))
97 
98         for token in reversed(tokens):
99             if token[0] in (tokenize.ENDMARKER, tokenize.COMMENT):
100                 continue
101             if (token[0] == tokenize.OP) and (token[1] == ';'):
102                 return True
103             else:
104                 return False
105 
106     def start_displayhook(self):
107         """Start the displayhook, initializing resources."""
108         pass
109 
110     def write_output_prompt(self):
111         """Write the output prompt.
112 
113         The default implementation simply writes the prompt to
114         ``io.stdout``.
115         """
116         # Use write, not print which adds an extra space.
117         io.stdout.write(self.shell.separate_out)
118         outprompt = self.shell.prompt_manager.render('out')
119         if self.do_full_cache:
120             io.stdout.write(outprompt)
121 
122     def compute_format_data(self, result):
123         """Compute format data of the object to be displayed.
124 
125         The format data is a generalization of the :func:`repr` of an object.
126         In the default implementation the format data is a :class:`dict` of
127         key value pair where the keys are valid MIME types and the values
128         are JSON'able data structure containing the raw data for that MIME
129         type. It is up to frontends to determine pick a MIME to to use and
130         display that data in an appropriate manner.
131 
132         This method only computes the format data for the object and should
133         NOT actually print or write that to a stream.
134 
135         Parameters
136         ----------
137         result : object
138             The Python object passed to the display hook, whose format will be
139             computed.
140 
141         Returns
142         -------
143         (format_dict, md_dict) : dict
144             format_dict is a :class:`dict` whose keys are valid MIME types and values are
145             JSON'able raw data for that MIME type. It is recommended that
146             all return values of this should always include the "text/plain"
147             MIME type representation of the object.
148             md_dict is a :class:`dict` with the same MIME type keys
149             of metadata associated with each output.
150             
151         """
152         return self.shell.display_formatter.format(result)
153 
154     def write_format_data(self, format_dict, md_dict=None):
155         """Write the format data dict to the frontend.
156 
157         This default version of this method simply writes the plain text
158         representation of the object to ``io.stdout``. Subclasses should
159         override this method to send the entire `format_dict` to the
160         frontends.
161 
162         Parameters
163         ----------
164         format_dict : dict
165             The format dict for the object passed to `sys.displayhook`.
166         md_dict : dict (optional)
167             The metadata dict to be associated with the display data.
168         """
169         if 'text/plain' not in format_dict:
170             # nothing to do
171             return
172         # We want to print because we want to always make sure we have a
173         # newline, even if all the prompt separators are ''. This is the
174         # standard IPython behavior.
175         result_repr = format_dict['text/plain']
176         if '\n' in result_repr:
177             # So that multi-line strings line up with the left column of
178             # the screen, instead of having the output prompt mess up
179             # their first line.
180             # We use the prompt template instead of the expanded prompt
181             # because the expansion may add ANSI escapes that will interfere
182             # with our ability to determine whether or not we should add
183             # a newline.
184             prompt_template = self.shell.prompt_manager.out_template
185             if prompt_template and not prompt_template.endswith('\n'):
186                 # But avoid extraneous empty lines.
187                 result_repr = '\n' + result_repr
188 
189         print(result_repr, file=io.stdout)
190 
191     def update_user_ns(self, result):
192         """Update user_ns with various things like _, __, _1, etc."""
193 
194         # Avoid recursive reference when displaying _oh/Out
195         if result is not self.shell.user_ns['_oh']:
196             if len(self.shell.user_ns['_oh']) >= self.cache_size and self.do_full_cache:
197                 self.cull_cache()
198             # Don't overwrite '_' and friends if '_' is in __builtin__ (otherwise
199             # we cause buggy behavior for things like gettext).
200 
201             if '_' not in builtin_mod.__dict__:
202                 self.___ = self.__
203                 self.__ = self._
204                 self._ = result
205                 self.shell.push({'_':self._,
206                                  '__':self.__,
207                                 '___':self.___}, interactive=False)
208 
209             # hackish access to top-level  namespace to create _1,_2... dynamically
210             to_main = {}
211             if self.do_full_cache:
212                 new_result = '_'+repr(self.prompt_count)
213                 to_main[new_result] = result
214                 self.shell.push(to_main, interactive=False)
215                 self.shell.user_ns['_oh'][self.prompt_count] = result
216 
217     def fill_exec_result(self, result):
218         if self.exec_result is not None:
219             self.exec_result.result = result
220 
221     def log_output(self, format_dict):
222         """Log the output."""
223         if 'text/plain' not in format_dict:
224             # nothing to do
225             return
226         if self.shell.logger.log_output:
227             self.shell.logger.log_write(format_dict['text/plain'], 'output')
228         self.shell.history_manager.output_hist_reprs[self.prompt_count] = \
229                                                     format_dict['text/plain']
230 
231     def finish_displayhook(self):
232         """Finish up all displayhook activities."""
233         io.stdout.write(self.shell.separate_out2)
234         io.stdout.flush()
235 
236     def __call__(self, result=None):
237         """Printing with history cache management.
238 
239         This is invoked everytime the interpreter needs to print, and is
240         activated by setting the variable sys.displayhook to it.
241         """
242         self.check_for_underscore()
243         if result is not None and not self.quiet():
244             self.start_displayhook()
245             self.write_output_prompt()
246             format_dict, md_dict = self.compute_format_data(result)
247             self.update_user_ns(result)
248             self.fill_exec_result(result)
249             if format_dict:
250                 self.write_format_data(format_dict, md_dict)
251                 self.log_output(format_dict)
252             self.finish_displayhook()
253 
254     def cull_cache(self):
255         """Output cache is full, cull the oldest entries"""
256         oh = self.shell.user_ns.get('_oh', {})
257         sz = len(oh)
258         cull_count = max(int(sz * self.cull_fraction), 2)
259         warn('Output cache limit (currently {sz} entries) hit.\n'
260              'Flushing oldest {cull_count} entries.'.format(sz=sz, cull_count=cull_count))
261         
262         for i, n in enumerate(sorted(oh)):
263             if i >= cull_count:
264                 break
265             self.shell.user_ns.pop('_%i' % n, None)
266             oh.pop(n, None)
267         
268 
269     def flush(self):
270         if not self.do_full_cache:
271             raise ValueError("You shouldn't have reached the cache flush "
272                              "if full caching is not enabled!")
273         # delete auto-generated vars from global namespace
274 
275         for n in range(1,self.prompt_count + 1):
276             key = '_'+repr(n)
277             try:
278                 del self.shell.user_ns[key]
279             except: pass
280         # In some embedded circumstances, the user_ns doesn't have the
281         # '_oh' key set up.
282         oh = self.shell.user_ns.get('_oh', None)
283         if oh is not None:
284             oh.clear()
285 
286         # Release our own references to objects:
287         self._, self.__, self.___ = '', '', ''
288 
289         if '_' not in builtin_mod.__dict__:
290             self.shell.user_ns.update({'_':None,'__':None, '___':None})
291         import gc
292         # TODO: Is this really needed?
293         # IronPython blocks here forever
294         if sys.platform != "cli":
295             gc.collect()
296 
297
```
--- 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()

```

diff --git a/IPython/core/displayhook.py b/IPython/core/displayhook.py
--- a/IPython/core/displayhook.py
+++ b/IPython/core/displayhook.py
@@ -96,7 +96,7 @@
         tokens = list(tokenize.generate_tokens(sio.readline))
 
         for token in reversed(tokens):
-            if token[0] in (tokenize.ENDMARKER, tokenize.COMMENT):
+            if token[0] in (tokenize.ENDMARKER, tokenize.NL, tokenize.NEWLINE, tokenize.COMMENT):
                 continue
             if (token[0] == tokenize.OP) and (token[1] == ';'):
                 return True

{"golden_diff": "diff --git a/IPython/core/displayhook.py b/IPython/core/displayhook.py\n--- a/IPython/core/displayhook.py\n+++ b/IPython/core/displayhook.py\n@@ -96,7 +96,7 @@\n         tokens = list(tokenize.generate_tokens(sio.readline))\n \n         for token in reversed(tokens):\n-            if token[0] in (tokenize.ENDMARKER, tokenize.COMMENT):\n+            if token[0] in (tokenize.ENDMARKER, tokenize.NL, tokenize.NEWLINE, tokenize.COMMENT):\n                 continue\n             if (token[0] == tokenize.OP) and (token[1] == ';'):\n                 return True\n", "issue": "Output for semicolon-terminated lines with comments\ncf https://github.com/JuliaLang/IJulia.jl/issues/109\n\nThe output of a semicolon-terminated line with comment is not suppressed in IPython.\n\n```\nb = 1\nb; # foo\n```\n\ngive `Out[13]: 1`\n\n```\nb = 1\nb;\n```\n\ndoes not.\n\nHavent found such and issue on our tracker.\n\n @takluyver you are the best with the input machinery and coroutines; Thoughts ?\n\n(Because of the comment @stevengj in sus-cited issue, marking as prio-high, but won't  mind if priority decreased later, or not fixed)\n\n", "before_files": [{"content": "# -*- coding: utf-8 -*-\n\"\"\"Displayhook for IPython.\n\nThis defines a callable class that IPython uses for `sys.displayhook`.\n\"\"\"\n\n# Copyright (c) IPython Development Team.\n# Distributed under the terms of the Modified BSD License.\n\nfrom __future__ import print_function\n\nimport sys\nimport io as _io\nimport tokenize\n\nfrom IPython.core.formatters import _safe_get_formatter_method\nfrom traitlets.config.configurable import Configurable\nfrom IPython.utils import io\nfrom IPython.utils.py3compat import builtin_mod, cast_unicode_py2\nfrom traitlets import Instance, Float\nfrom IPython.utils.warn import warn\n\n# TODO: Move the various attributes (cache_size, [others now moved]). Some\n# of these are also attributes of InteractiveShell. They should be on ONE object\n# only and the other objects should ask that one object for their values.\n\nclass DisplayHook(Configurable):\n    \"\"\"The custom IPython displayhook to replace sys.displayhook.\n\n    This class does many things, but the basic idea is that it is a callable\n    that gets called anytime user code returns a value.\n    \"\"\"\n\n    shell = Instance('IPython.core.interactiveshell.InteractiveShellABC',\n                     allow_none=True)\n    exec_result = Instance('IPython.core.interactiveshell.ExecutionResult',\n                           allow_none=True)\n    cull_fraction = Float(0.2)\n\n    def __init__(self, shell=None, cache_size=1000, **kwargs):\n        super(DisplayHook, self).__init__(shell=shell, **kwargs)\n        cache_size_min = 3\n        if cache_size <= 0:\n            self.do_full_cache = 0\n            cache_size = 0\n        elif cache_size < cache_size_min:\n            self.do_full_cache = 0\n            cache_size = 0\n            warn('caching was disabled (min value for cache size is %s).' %\n                 cache_size_min,level=3)\n        else:\n            self.do_full_cache = 1\n\n        self.cache_size = cache_size\n\n        # we need a reference to the user-level namespace\n        self.shell = shell\n        \n        self._,self.__,self.___ = '','',''\n\n        # these are deliberately global:\n        to_user_ns = {'_':self._,'__':self.__,'___':self.___}\n        self.shell.user_ns.update(to_user_ns)\n\n    @property\n    def prompt_count(self):\n        return self.shell.execution_count\n\n    #-------------------------------------------------------------------------\n    # Methods used in __call__. Override these methods to modify the behavior\n    # of the displayhook.\n    #-------------------------------------------------------------------------\n\n    def check_for_underscore(self):\n        \"\"\"Check if the user has set the '_' variable by hand.\"\"\"\n        # If something injected a '_' variable in __builtin__, delete\n        # ipython's automatic one so we don't clobber that.  gettext() in\n        # particular uses _, so we need to stay away from it.\n        if '_' in builtin_mod.__dict__:\n            try:\n                del self.shell.user_ns['_']\n            except KeyError:\n                pass\n\n    def quiet(self):\n        \"\"\"Should we silence the display hook because of ';'?\"\"\"\n        # do not print output if input ends in ';'\n        \n        try:\n            cell = cast_unicode_py2(self.shell.history_manager.input_hist_parsed[-1])\n        except IndexError:\n            # some uses of ipshellembed may fail here\n            return False\n        \n        sio = _io.StringIO(cell)\n        tokens = list(tokenize.generate_tokens(sio.readline))\n\n        for token in reversed(tokens):\n            if token[0] in (tokenize.ENDMARKER, tokenize.COMMENT):\n                continue\n            if (token[0] == tokenize.OP) and (token[1] == ';'):\n                return True\n            else:\n                return False\n\n    def start_displayhook(self):\n        \"\"\"Start the displayhook, initializing resources.\"\"\"\n        pass\n\n    def write_output_prompt(self):\n        \"\"\"Write the output prompt.\n\n        The default implementation simply writes the prompt to\n        ``io.stdout``.\n        \"\"\"\n        # Use write, not print which adds an extra space.\n        io.stdout.write(self.shell.separate_out)\n        outprompt = self.shell.prompt_manager.render('out')\n        if self.do_full_cache:\n            io.stdout.write(outprompt)\n\n    def compute_format_data(self, result):\n        \"\"\"Compute format data of the object to be displayed.\n\n        The format data is a generalization of the :func:`repr` of an object.\n        In the default implementation the format data is a :class:`dict` of\n        key value pair where the keys are valid MIME types and the values\n        are JSON'able data structure containing the raw data for that MIME\n        type. It is up to frontends to determine pick a MIME to to use and\n        display that data in an appropriate manner.\n\n        This method only computes the format data for the object and should\n        NOT actually print or write that to a stream.\n\n        Parameters\n        ----------\n        result : object\n            The Python object passed to the display hook, whose format will be\n            computed.\n\n        Returns\n        -------\n        (format_dict, md_dict) : dict\n            format_dict is a :class:`dict` whose keys are valid MIME types and values are\n            JSON'able raw data for that MIME type. It is recommended that\n            all return values of this should always include the \"text/plain\"\n            MIME type representation of the object.\n            md_dict is a :class:`dict` with the same MIME type keys\n            of metadata associated with each output.\n            \n        \"\"\"\n        return self.shell.display_formatter.format(result)\n\n    def write_format_data(self, format_dict, md_dict=None):\n        \"\"\"Write the format data dict to the frontend.\n\n        This default version of this method simply writes the plain text\n        representation of the object to ``io.stdout``. Subclasses should\n        override this method to send the entire `format_dict` to the\n        frontends.\n\n        Parameters\n        ----------\n        format_dict : dict\n            The format dict for the object passed to `sys.displayhook`.\n        md_dict : dict (optional)\n            The metadata dict to be associated with the display data.\n        \"\"\"\n        if 'text/plain' not in format_dict:\n            # nothing to do\n            return\n        # We want to print because we want to always make sure we have a\n        # newline, even if all the prompt separators are ''. This is the\n        # standard IPython behavior.\n        result_repr = format_dict['text/plain']\n        if '\\n' in result_repr:\n            # So that multi-line strings line up with the left column of\n            # the screen, instead of having the output prompt mess up\n            # their first line.\n            # We use the prompt template instead of the expanded prompt\n            # because the expansion may add ANSI escapes that will interfere\n            # with our ability to determine whether or not we should add\n            # a newline.\n            prompt_template = self.shell.prompt_manager.out_template\n            if prompt_template and not prompt_template.endswith('\\n'):\n                # But avoid extraneous empty lines.\n                result_repr = '\\n' + result_repr\n\n        print(result_repr, file=io.stdout)\n\n    def update_user_ns(self, result):\n        \"\"\"Update user_ns with various things like _, __, _1, etc.\"\"\"\n\n        # Avoid recursive reference when displaying _oh/Out\n        if result is not self.shell.user_ns['_oh']:\n            if len(self.shell.user_ns['_oh']) >= self.cache_size and self.do_full_cache:\n                self.cull_cache()\n            # Don't overwrite '_' and friends if '_' is in __builtin__ (otherwise\n            # we cause buggy behavior for things like gettext).\n\n            if '_' not in builtin_mod.__dict__:\n                self.___ = self.__\n                self.__ = self._\n                self._ = result\n                self.shell.push({'_':self._,\n                                 '__':self.__,\n                                '___':self.___}, interactive=False)\n\n            # hackish access to top-level  namespace to create _1,_2... dynamically\n            to_main = {}\n            if self.do_full_cache:\n                new_result = '_'+repr(self.prompt_count)\n                to_main[new_result] = result\n                self.shell.push(to_main, interactive=False)\n                self.shell.user_ns['_oh'][self.prompt_count] = result\n\n    def fill_exec_result(self, result):\n        if self.exec_result is not None:\n            self.exec_result.result = result\n\n    def log_output(self, format_dict):\n        \"\"\"Log the output.\"\"\"\n        if 'text/plain' not in format_dict:\n            # nothing to do\n            return\n        if self.shell.logger.log_output:\n            self.shell.logger.log_write(format_dict['text/plain'], 'output')\n        self.shell.history_manager.output_hist_reprs[self.prompt_count] = \\\n                                                    format_dict['text/plain']\n\n    def finish_displayhook(self):\n        \"\"\"Finish up all displayhook activities.\"\"\"\n        io.stdout.write(self.shell.separate_out2)\n        io.stdout.flush()\n\n    def __call__(self, result=None):\n        \"\"\"Printing with history cache management.\n\n        This is invoked everytime the interpreter needs to print, and is\n        activated by setting the variable sys.displayhook to it.\n        \"\"\"\n        self.check_for_underscore()\n        if result is not None and not self.quiet():\n            self.start_displayhook()\n            self.write_output_prompt()\n            format_dict, md_dict = self.compute_format_data(result)\n            self.update_user_ns(result)\n            self.fill_exec_result(result)\n            if format_dict:\n                self.write_format_data(format_dict, md_dict)\n                self.log_output(format_dict)\n            self.finish_displayhook()\n\n    def cull_cache(self):\n        \"\"\"Output cache is full, cull the oldest entries\"\"\"\n        oh = self.shell.user_ns.get('_oh', {})\n        sz = len(oh)\n        cull_count = max(int(sz * self.cull_fraction), 2)\n        warn('Output cache limit (currently {sz} entries) hit.\\n'\n             'Flushing oldest {cull_count} entries.'.format(sz=sz, cull_count=cull_count))\n        \n        for i, n in enumerate(sorted(oh)):\n            if i >= cull_count:\n                break\n            self.shell.user_ns.pop('_%i' % n, None)\n            oh.pop(n, None)\n        \n\n    def flush(self):\n        if not self.do_full_cache:\n            raise ValueError(\"You shouldn't have reached the cache flush \"\n                             \"if full caching is not enabled!\")\n        # delete auto-generated vars from global namespace\n\n        for n in range(1,self.prompt_count + 1):\n            key = '_'+repr(n)\n            try:\n                del self.shell.user_ns[key]\n            except: pass\n        # In some embedded circumstances, the user_ns doesn't have the\n        # '_oh' key set up.\n        oh = self.shell.user_ns.get('_oh', None)\n        if oh is not None:\n            oh.clear()\n\n        # Release our own references to objects:\n        self._, self.__, self.___ = '', '', ''\n\n        if '_' not in builtin_mod.__dict__:\n            self.shell.user_ns.update({'_':None,'__':None, '___':None})\n        import gc\n        # TODO: Is this really needed?\n        # IronPython blocks here forever\n        if sys.platform != \"cli\":\n            gc.collect()\n\n", "path": "IPython/core/displayhook.py"}], "after_files": [{"content": "# -*- coding: utf-8 -*-\n\"\"\"Displayhook for IPython.\n\nThis defines a callable class that IPython uses for `sys.displayhook`.\n\"\"\"\n\n# Copyright (c) IPython Development Team.\n# Distributed under the terms of the Modified BSD License.\n\nfrom __future__ import print_function\n\nimport sys\nimport io as _io\nimport tokenize\n\nfrom IPython.core.formatters import _safe_get_formatter_method\nfrom traitlets.config.configurable import Configurable\nfrom IPython.utils import io\nfrom IPython.utils.py3compat import builtin_mod, cast_unicode_py2\nfrom traitlets import Instance, Float\nfrom IPython.utils.warn import warn\n\n# TODO: Move the various attributes (cache_size, [others now moved]). Some\n# of these are also attributes of InteractiveShell. They should be on ONE object\n# only and the other objects should ask that one object for their values.\n\nclass DisplayHook(Configurable):\n    \"\"\"The custom IPython displayhook to replace sys.displayhook.\n\n    This class does many things, but the basic idea is that it is a callable\n    that gets called anytime user code returns a value.\n    \"\"\"\n\n    shell = Instance('IPython.core.interactiveshell.InteractiveShellABC',\n                     allow_none=True)\n    exec_result = Instance('IPython.core.interactiveshell.ExecutionResult',\n                           allow_none=True)\n    cull_fraction = Float(0.2)\n\n    def __init__(self, shell=None, cache_size=1000, **kwargs):\n        super(DisplayHook, self).__init__(shell=shell, **kwargs)\n        cache_size_min = 3\n        if cache_size <= 0:\n            self.do_full_cache = 0\n            cache_size = 0\n        elif cache_size < cache_size_min:\n            self.do_full_cache = 0\n            cache_size = 0\n            warn('caching was disabled (min value for cache size is %s).' %\n                 cache_size_min,level=3)\n        else:\n            self.do_full_cache = 1\n\n        self.cache_size = cache_size\n\n        # we need a reference to the user-level namespace\n        self.shell = shell\n        \n        self._,self.__,self.___ = '','',''\n\n        # these are deliberately global:\n        to_user_ns = {'_':self._,'__':self.__,'___':self.___}\n        self.shell.user_ns.update(to_user_ns)\n\n    @property\n    def prompt_count(self):\n        return self.shell.execution_count\n\n    #-------------------------------------------------------------------------\n    # Methods used in __call__. Override these methods to modify the behavior\n    # of the displayhook.\n    #-------------------------------------------------------------------------\n\n    def check_for_underscore(self):\n        \"\"\"Check if the user has set the '_' variable by hand.\"\"\"\n        # If something injected a '_' variable in __builtin__, delete\n        # ipython's automatic one so we don't clobber that.  gettext() in\n        # particular uses _, so we need to stay away from it.\n        if '_' in builtin_mod.__dict__:\n            try:\n                del self.shell.user_ns['_']\n            except KeyError:\n                pass\n\n    def quiet(self):\n        \"\"\"Should we silence the display hook because of ';'?\"\"\"\n        # do not print output if input ends in ';'\n        \n        try:\n            cell = cast_unicode_py2(self.shell.history_manager.input_hist_parsed[-1])\n        except IndexError:\n            # some uses of ipshellembed may fail here\n            return False\n        \n        sio = _io.StringIO(cell)\n        tokens = list(tokenize.generate_tokens(sio.readline))\n\n        for token in reversed(tokens):\n            if token[0] in (tokenize.ENDMARKER, tokenize.NL, tokenize.NEWLINE, tokenize.COMMENT):\n                continue\n            if (token[0] == tokenize.OP) and (token[1] == ';'):\n                return True\n            else:\n                return False\n\n    def start_displayhook(self):\n        \"\"\"Start the displayhook, initializing resources.\"\"\"\n        pass\n\n    def write_output_prompt(self):\n        \"\"\"Write the output prompt.\n\n        The default implementation simply writes the prompt to\n        ``io.stdout``.\n        \"\"\"\n        # Use write, not print which adds an extra space.\n        io.stdout.write(self.shell.separate_out)\n        outprompt = self.shell.prompt_manager.render('out')\n        if self.do_full_cache:\n            io.stdout.write(outprompt)\n\n    def compute_format_data(self, result):\n        \"\"\"Compute format data of the object to be displayed.\n\n        The format data is a generalization of the :func:`repr` of an object.\n        In the default implementation the format data is a :class:`dict` of\n        key value pair where the keys are valid MIME types and the values\n        are JSON'able data structure containing the raw data for that MIME\n        type. It is up to frontends to determine pick a MIME to to use and\n        display that data in an appropriate manner.\n\n        This method only computes the format data for the object and should\n        NOT actually print or write that to a stream.\n\n        Parameters\n        ----------\n        result : object\n            The Python object passed to the display hook, whose format will be\n            computed.\n\n        Returns\n        -------\n        (format_dict, md_dict) : dict\n            format_dict is a :class:`dict` whose keys are valid MIME types and values are\n            JSON'able raw data for that MIME type. It is recommended that\n            all return values of this should always include the \"text/plain\"\n            MIME type representation of the object.\n            md_dict is a :class:`dict` with the same MIME type keys\n            of metadata associated with each output.\n            \n        \"\"\"\n        return self.shell.display_formatter.format(result)\n\n    def write_format_data(self, format_dict, md_dict=None):\n        \"\"\"Write the format data dict to the frontend.\n\n        This default version of this method simply writes the plain text\n        representation of the object to ``io.stdout``. Subclasses should\n        override this method to send the entire `format_dict` to the\n        frontends.\n\n        Parameters\n        ----------\n        format_dict : dict\n            The format dict for the object passed to `sys.displayhook`.\n        md_dict : dict (optional)\n            The metadata dict to be associated with the display data.\n        \"\"\"\n        if 'text/plain' not in format_dict:\n            # nothing to do\n            return\n        # We want to print because we want to always make sure we have a\n        # newline, even if all the prompt separators are ''. This is the\n        # standard IPython behavior.\n        result_repr = format_dict['text/plain']\n        if '\\n' in result_repr:\n            # So that multi-line strings line up with the left column of\n            # the screen, instead of having the output prompt mess up\n            # their first line.\n            # We use the prompt template instead of the expanded prompt\n            # because the expansion may add ANSI escapes that will interfere\n            # with our ability to determine whether or not we should add\n            # a newline.\n            prompt_template = self.shell.prompt_manager.out_template\n            if prompt_template and not prompt_template.endswith('\\n'):\n                # But avoid extraneous empty lines.\n                result_repr = '\\n' + result_repr\n\n        print(result_repr, file=io.stdout)\n\n    def update_user_ns(self, result):\n        \"\"\"Update user_ns with various things like _, __, _1, etc.\"\"\"\n\n        # Avoid recursive reference when displaying _oh/Out\n        if result is not self.shell.user_ns['_oh']:\n            if len(self.shell.user_ns['_oh']) >= self.cache_size and self.do_full_cache:\n                self.cull_cache()\n            # Don't overwrite '_' and friends if '_' is in __builtin__ (otherwise\n            # we cause buggy behavior for things like gettext).\n\n            if '_' not in builtin_mod.__dict__:\n                self.___ = self.__\n                self.__ = self._\n                self._ = result\n                self.shell.push({'_':self._,\n                                 '__':self.__,\n                                '___':self.___}, interactive=False)\n\n            # hackish access to top-level  namespace to create _1,_2... dynamically\n            to_main = {}\n            if self.do_full_cache:\n                new_result = '_'+repr(self.prompt_count)\n                to_main[new_result] = result\n                self.shell.push(to_main, interactive=False)\n                self.shell.user_ns['_oh'][self.prompt_count] = result\n\n    def fill_exec_result(self, result):\n        if self.exec_result is not None:\n            self.exec_result.result = result\n\n    def log_output(self, format_dict):\n        \"\"\"Log the output.\"\"\"\n        if 'text/plain' not in format_dict:\n            # nothing to do\n            return\n        if self.shell.logger.log_output:\n            self.shell.logger.log_write(format_dict['text/plain'], 'output')\n        self.shell.history_manager.output_hist_reprs[self.prompt_count] = \\\n                                                    format_dict['text/plain']\n\n    def finish_displayhook(self):\n        \"\"\"Finish up all displayhook activities.\"\"\"\n        io.stdout.write(self.shell.separate_out2)\n        io.stdout.flush()\n\n    def __call__(self, result=None):\n        \"\"\"Printing with history cache management.\n\n        This is invoked everytime the interpreter needs to print, and is\n        activated by setting the variable sys.displayhook to it.\n        \"\"\"\n        self.check_for_underscore()\n        if result is not None and not self.quiet():\n            self.start_displayhook()\n            self.write_output_prompt()\n            format_dict, md_dict = self.compute_format_data(result)\n            self.update_user_ns(result)\n            self.fill_exec_result(result)\n            if format_dict:\n                self.write_format_data(format_dict, md_dict)\n                self.log_output(format_dict)\n            self.finish_displayhook()\n\n    def cull_cache(self):\n        \"\"\"Output cache is full, cull the oldest entries\"\"\"\n        oh = self.shell.user_ns.get('_oh', {})\n        sz = len(oh)\n        cull_count = max(int(sz * self.cull_fraction), 2)\n        warn('Output cache limit (currently {sz} entries) hit.\\n'\n             'Flushing oldest {cull_count} entries.'.format(sz=sz, cull_count=cull_count))\n        \n        for i, n in enumerate(sorted(oh)):\n            if i >= cull_count:\n                break\n            self.shell.user_ns.pop('_%i' % n, None)\n            oh.pop(n, None)\n        \n\n    def flush(self):\n        if not self.do_full_cache:\n            raise ValueError(\"You shouldn't have reached the cache flush \"\n                             \"if full caching is not enabled!\")\n        # delete auto-generated vars from global namespace\n\n        for n in range(1,self.prompt_count + 1):\n            key = '_'+repr(n)\n            try:\n                del self.shell.user_ns[key]\n            except: pass\n        # In some embedded circumstances, the user_ns doesn't have the\n        # '_oh' key set up.\n        oh = self.shell.user_ns.get('_oh', None)\n        if oh is not None:\n            oh.clear()\n\n        # Release our own references to objects:\n        self._, self.__, self.___ = '', '', ''\n\n        if '_' not in builtin_mod.__dict__:\n            self.shell.user_ns.update({'_':None,'__':None, '___':None})\n        import gc\n        # TODO: Is this really needed?\n        # IronPython blocks here forever\n        if sys.platform != \"cli\":\n            gc.collect()\n\n", "path": "IPython/core/displayhook.py"}]}