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