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