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