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