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