##// END OF EJS Templates
Merge pull request #12923 from Carreau/doc-4...
Matthias Bussonnier -
r26500:5d7ef556 merge
parent child Browse files
Show More
@@ -1,325 +1,325 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 import builtins as builtin_mod
10 import builtins as builtin_mod
11 import sys
11 import sys
12 import io as _io
12 import io as _io
13 import tokenize
13 import tokenize
14
14
15 from traitlets.config.configurable import Configurable
15 from traitlets.config.configurable import Configurable
16 from traitlets import Instance, Float
16 from traitlets import Instance, Float
17 from warnings import warn
17 from warnings import warn
18
18
19 # TODO: Move the various attributes (cache_size, [others now moved]). Some
19 # TODO: Move the various attributes (cache_size, [others now moved]). Some
20 # of these are also attributes of InteractiveShell. They should be on ONE object
20 # of these are also attributes of InteractiveShell. They should be on ONE object
21 # only and the other objects should ask that one object for their values.
21 # only and the other objects should ask that one object for their values.
22
22
23 class DisplayHook(Configurable):
23 class DisplayHook(Configurable):
24 """The custom IPython displayhook to replace sys.displayhook.
24 """The custom IPython displayhook to replace sys.displayhook.
25
25
26 This class does many things, but the basic idea is that it is a callable
26 This class does many things, but the basic idea is that it is a callable
27 that gets called anytime user code returns a value.
27 that gets called anytime user code returns a value.
28 """
28 """
29
29
30 shell = Instance('IPython.core.interactiveshell.InteractiveShellABC',
30 shell = Instance('IPython.core.interactiveshell.InteractiveShellABC',
31 allow_none=True)
31 allow_none=True)
32 exec_result = Instance('IPython.core.interactiveshell.ExecutionResult',
32 exec_result = Instance('IPython.core.interactiveshell.ExecutionResult',
33 allow_none=True)
33 allow_none=True)
34 cull_fraction = Float(0.2)
34 cull_fraction = Float(0.2)
35
35
36 def __init__(self, shell=None, cache_size=1000, **kwargs):
36 def __init__(self, shell=None, cache_size=1000, **kwargs):
37 super(DisplayHook, self).__init__(shell=shell, **kwargs)
37 super(DisplayHook, self).__init__(shell=shell, **kwargs)
38 cache_size_min = 3
38 cache_size_min = 3
39 if cache_size <= 0:
39 if cache_size <= 0:
40 self.do_full_cache = 0
40 self.do_full_cache = 0
41 cache_size = 0
41 cache_size = 0
42 elif cache_size < cache_size_min:
42 elif cache_size < cache_size_min:
43 self.do_full_cache = 0
43 self.do_full_cache = 0
44 cache_size = 0
44 cache_size = 0
45 warn('caching was disabled (min value for cache size is %s).' %
45 warn('caching was disabled (min value for cache size is %s).' %
46 cache_size_min,stacklevel=3)
46 cache_size_min,stacklevel=3)
47 else:
47 else:
48 self.do_full_cache = 1
48 self.do_full_cache = 1
49
49
50 self.cache_size = cache_size
50 self.cache_size = cache_size
51
51
52 # we need a reference to the user-level namespace
52 # we need a reference to the user-level namespace
53 self.shell = shell
53 self.shell = shell
54
54
55 self._,self.__,self.___ = '','',''
55 self._,self.__,self.___ = '','',''
56
56
57 # these are deliberately global:
57 # these are deliberately global:
58 to_user_ns = {'_':self._,'__':self.__,'___':self.___}
58 to_user_ns = {'_':self._,'__':self.__,'___':self.___}
59 self.shell.user_ns.update(to_user_ns)
59 self.shell.user_ns.update(to_user_ns)
60
60
61 @property
61 @property
62 def prompt_count(self):
62 def prompt_count(self):
63 return self.shell.execution_count
63 return self.shell.execution_count
64
64
65 #-------------------------------------------------------------------------
65 #-------------------------------------------------------------------------
66 # Methods used in __call__. Override these methods to modify the behavior
66 # Methods used in __call__. Override these methods to modify the behavior
67 # of the displayhook.
67 # of the displayhook.
68 #-------------------------------------------------------------------------
68 #-------------------------------------------------------------------------
69
69
70 def check_for_underscore(self):
70 def check_for_underscore(self):
71 """Check if the user has set the '_' variable by hand."""
71 """Check if the user has set the '_' variable by hand."""
72 # If something injected a '_' variable in __builtin__, delete
72 # If something injected a '_' variable in __builtin__, delete
73 # ipython's automatic one so we don't clobber that. gettext() in
73 # ipython's automatic one so we don't clobber that. gettext() in
74 # particular uses _, so we need to stay away from it.
74 # particular uses _, so we need to stay away from it.
75 if '_' in builtin_mod.__dict__:
75 if '_' in builtin_mod.__dict__:
76 try:
76 try:
77 user_value = self.shell.user_ns['_']
77 user_value = self.shell.user_ns['_']
78 if user_value is not self._:
78 if user_value is not self._:
79 return
79 return
80 del self.shell.user_ns['_']
80 del self.shell.user_ns['_']
81 except KeyError:
81 except KeyError:
82 pass
82 pass
83
83
84 def quiet(self):
84 def quiet(self):
85 """Should we silence the display hook because of ';'?"""
85 """Should we silence the display hook because of ';'?"""
86 # do not print output if input ends in ';'
86 # do not print output if input ends in ';'
87
87
88 try:
88 try:
89 cell = self.shell.history_manager.input_hist_parsed[-1]
89 cell = self.shell.history_manager.input_hist_parsed[-1]
90 except IndexError:
90 except IndexError:
91 # some uses of ipshellembed may fail here
91 # some uses of ipshellembed may fail here
92 return False
92 return False
93
93
94 sio = _io.StringIO(cell)
94 sio = _io.StringIO(cell)
95 tokens = list(tokenize.generate_tokens(sio.readline))
95 tokens = list(tokenize.generate_tokens(sio.readline))
96
96
97 for token in reversed(tokens):
97 for token in reversed(tokens):
98 if token[0] in (tokenize.ENDMARKER, tokenize.NL, tokenize.NEWLINE, tokenize.COMMENT):
98 if token[0] in (tokenize.ENDMARKER, tokenize.NL, tokenize.NEWLINE, tokenize.COMMENT):
99 continue
99 continue
100 if (token[0] == tokenize.OP) and (token[1] == ';'):
100 if (token[0] == tokenize.OP) and (token[1] == ';'):
101 return True
101 return True
102 else:
102 else:
103 return False
103 return False
104
104
105 def start_displayhook(self):
105 def start_displayhook(self):
106 """Start the displayhook, initializing resources."""
106 """Start the displayhook, initializing resources."""
107 pass
107 pass
108
108
109 def write_output_prompt(self):
109 def write_output_prompt(self):
110 """Write the output prompt.
110 """Write the output prompt.
111
111
112 The default implementation simply writes the prompt to
112 The default implementation simply writes the prompt to
113 ``sys.stdout``.
113 ``sys.stdout``.
114 """
114 """
115 # Use write, not print which adds an extra space.
115 # Use write, not print which adds an extra space.
116 sys.stdout.write(self.shell.separate_out)
116 sys.stdout.write(self.shell.separate_out)
117 outprompt = 'Out[{}]: '.format(self.shell.execution_count)
117 outprompt = 'Out[{}]: '.format(self.shell.execution_count)
118 if self.do_full_cache:
118 if self.do_full_cache:
119 sys.stdout.write(outprompt)
119 sys.stdout.write(outprompt)
120
120
121 def compute_format_data(self, result):
121 def compute_format_data(self, result):
122 """Compute format data of the object to be displayed.
122 """Compute format data of the object to be displayed.
123
123
124 The format data is a generalization of the :func:`repr` of an object.
124 The format data is a generalization of the :func:`repr` of an object.
125 In the default implementation the format data is a :class:`dict` of
125 In the default implementation the format data is a :class:`dict` of
126 key value pair where the keys are valid MIME types and the values
126 key value pair where the keys are valid MIME types and the values
127 are JSON'able data structure containing the raw data for that MIME
127 are JSON'able data structure containing the raw data for that MIME
128 type. It is up to frontends to determine pick a MIME to to use and
128 type. It is up to frontends to determine pick a MIME to to use and
129 display that data in an appropriate manner.
129 display that data in an appropriate manner.
130
130
131 This method only computes the format data for the object and should
131 This method only computes the format data for the object and should
132 NOT actually print or write that to a stream.
132 NOT actually print or write that to a stream.
133
133
134 Parameters
134 Parameters
135 ----------
135 ----------
136 result : object
136 result : object
137 The Python object passed to the display hook, whose format will be
137 The Python object passed to the display hook, whose format will be
138 computed.
138 computed.
139
139
140 Returns
140 Returns
141 -------
141 -------
142 (format_dict, md_dict) : dict
142 (format_dict, md_dict) : dict
143 format_dict is a :class:`dict` whose keys are valid MIME types and values are
143 format_dict is a :class:`dict` whose keys are valid MIME types and values are
144 JSON'able raw data for that MIME type. It is recommended that
144 JSON'able raw data for that MIME type. It is recommended that
145 all return values of this should always include the "text/plain"
145 all return values of this should always include the "text/plain"
146 MIME type representation of the object.
146 MIME type representation of the object.
147 md_dict is a :class:`dict` with the same MIME type keys
147 md_dict is a :class:`dict` with the same MIME type keys
148 of metadata associated with each output.
148 of metadata associated with each output.
149
149
150 """
150 """
151 return self.shell.display_formatter.format(result)
151 return self.shell.display_formatter.format(result)
152
152
153 # This can be set to True by the write_output_prompt method in a subclass
153 # This can be set to True by the write_output_prompt method in a subclass
154 prompt_end_newline = False
154 prompt_end_newline = False
155
155
156 def write_format_data(self, format_dict, md_dict=None) -> None:
156 def write_format_data(self, format_dict, md_dict=None) -> None:
157 """Write the format data dict to the frontend.
157 """Write the format data dict to the frontend.
158
158
159 This default version of this method simply writes the plain text
159 This default version of this method simply writes the plain text
160 representation of the object to ``sys.stdout``. Subclasses should
160 representation of the object to ``sys.stdout``. Subclasses should
161 override this method to send the entire `format_dict` to the
161 override this method to send the entire `format_dict` to the
162 frontends.
162 frontends.
163
163
164 Parameters
164 Parameters
165 ----------
165 ----------
166 format_dict : dict
166 format_dict : dict
167 The format dict for the object passed to `sys.displayhook`.
167 The format dict for the object passed to `sys.displayhook`.
168 md_dict : dict (optional)
168 md_dict : dict (optional)
169 The metadata dict to be associated with the display data.
169 The metadata dict to be associated with the display data.
170 """
170 """
171 if 'text/plain' not in format_dict:
171 if 'text/plain' not in format_dict:
172 # nothing to do
172 # nothing to do
173 return
173 return
174 # We want to print because we want to always make sure we have a
174 # We want to print because we want to always make sure we have a
175 # newline, even if all the prompt separators are ''. This is the
175 # newline, even if all the prompt separators are ''. This is the
176 # standard IPython behavior.
176 # standard IPython behavior.
177 result_repr = format_dict['text/plain']
177 result_repr = format_dict['text/plain']
178 if '\n' in result_repr:
178 if '\n' in result_repr:
179 # So that multi-line strings line up with the left column of
179 # So that multi-line strings line up with the left column of
180 # the screen, instead of having the output prompt mess up
180 # the screen, instead of having the output prompt mess up
181 # their first line.
181 # their first line.
182 # We use the prompt template instead of the expanded prompt
182 # We use the prompt template instead of the expanded prompt
183 # because the expansion may add ANSI escapes that will interfere
183 # because the expansion may add ANSI escapes that will interfere
184 # with our ability to determine whether or not we should add
184 # with our ability to determine whether or not we should add
185 # a newline.
185 # a newline.
186 if not self.prompt_end_newline:
186 if not self.prompt_end_newline:
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 try:
190 try:
191 print(result_repr)
191 print(result_repr)
192 except UnicodeEncodeError:
192 except UnicodeEncodeError:
193 # If a character is not supported by the terminal encoding replace
193 # If a character is not supported by the terminal encoding replace
194 # it with its \u or \x representation
194 # it with its \u or \x representation
195 print(result_repr.encode(sys.stdout.encoding,'backslashreplace').decode(sys.stdout.encoding))
195 print(result_repr.encode(sys.stdout.encoding,'backslashreplace').decode(sys.stdout.encoding))
196
196
197 def update_user_ns(self, result):
197 def update_user_ns(self, result):
198 """Update user_ns with various things like _, __, _1, etc."""
198 """Update user_ns with various things like _, __, _1, etc."""
199
199
200 # Avoid recursive reference when displaying _oh/Out
200 # Avoid recursive reference when displaying _oh/Out
201 if self.cache_size and result is not self.shell.user_ns['_oh']:
201 if self.cache_size and result is not self.shell.user_ns['_oh']:
202 if len(self.shell.user_ns['_oh']) >= self.cache_size and self.do_full_cache:
202 if len(self.shell.user_ns['_oh']) >= self.cache_size and self.do_full_cache:
203 self.cull_cache()
203 self.cull_cache()
204
204
205 # Don't overwrite '_' and friends if '_' is in __builtin__
205 # Don't overwrite '_' and friends if '_' is in __builtin__
206 # (otherwise we cause buggy behavior for things like gettext). and
206 # (otherwise we cause buggy behavior for things like gettext). and
207 # do not overwrite _, __ or ___ if one of these has been assigned
207 # do not overwrite _, __ or ___ if one of these has been assigned
208 # by the user.
208 # by the user.
209 update_unders = True
209 update_unders = True
210 for unders in ['_'*i for i in range(1,4)]:
210 for unders in ['_'*i for i in range(1,4)]:
211 if not unders in self.shell.user_ns:
211 if not unders in self.shell.user_ns:
212 continue
212 continue
213 if getattr(self, unders) is not self.shell.user_ns.get(unders):
213 if getattr(self, unders) is not self.shell.user_ns.get(unders):
214 update_unders = False
214 update_unders = False
215
215
216 self.___ = self.__
216 self.___ = self.__
217 self.__ = self._
217 self.__ = self._
218 self._ = result
218 self._ = result
219
219
220 if ('_' not in builtin_mod.__dict__) and (update_unders):
220 if ('_' not in builtin_mod.__dict__) and (update_unders):
221 self.shell.push({'_':self._,
221 self.shell.push({'_':self._,
222 '__':self.__,
222 '__':self.__,
223 '___':self.___}, interactive=False)
223 '___':self.___}, interactive=False)
224
224
225 # hackish access to top-level namespace to create _1,_2... dynamically
225 # hackish access to top-level namespace to create _1,_2... dynamically
226 to_main = {}
226 to_main = {}
227 if self.do_full_cache:
227 if self.do_full_cache:
228 new_result = '_%s' % self.prompt_count
228 new_result = '_%s' % self.prompt_count
229 to_main[new_result] = result
229 to_main[new_result] = result
230 self.shell.push(to_main, interactive=False)
230 self.shell.push(to_main, interactive=False)
231 self.shell.user_ns['_oh'][self.prompt_count] = result
231 self.shell.user_ns['_oh'][self.prompt_count] = result
232
232
233 def fill_exec_result(self, result):
233 def fill_exec_result(self, result):
234 if self.exec_result is not None:
234 if self.exec_result is not None:
235 self.exec_result.result = result
235 self.exec_result.result = result
236
236
237 def log_output(self, format_dict):
237 def log_output(self, format_dict):
238 """Log the output."""
238 """Log the output."""
239 if 'text/plain' not in format_dict:
239 if 'text/plain' not in format_dict:
240 # nothing to do
240 # nothing to do
241 return
241 return
242 if self.shell.logger.log_output:
242 if self.shell.logger.log_output:
243 self.shell.logger.log_write(format_dict['text/plain'], 'output')
243 self.shell.logger.log_write(format_dict['text/plain'], 'output')
244 self.shell.history_manager.output_hist_reprs[self.prompt_count] = \
244 self.shell.history_manager.output_hist_reprs[self.prompt_count] = \
245 format_dict['text/plain']
245 format_dict['text/plain']
246
246
247 def finish_displayhook(self):
247 def finish_displayhook(self):
248 """Finish up all displayhook activities."""
248 """Finish up all displayhook activities."""
249 sys.stdout.write(self.shell.separate_out2)
249 sys.stdout.write(self.shell.separate_out2)
250 sys.stdout.flush()
250 sys.stdout.flush()
251
251
252 def __call__(self, result=None):
252 def __call__(self, result=None):
253 """Printing with history cache management.
253 """Printing with history cache management.
254
254
255 This is invoked every time the interpreter needs to print, and is
255 This is invoked every time the interpreter needs to print, and is
256 activated by setting the variable sys.displayhook to it.
256 activated by setting the variable sys.displayhook to it.
257 """
257 """
258 self.check_for_underscore()
258 self.check_for_underscore()
259 if result is not None and not self.quiet():
259 if result is not None and not self.quiet():
260 self.start_displayhook()
260 self.start_displayhook()
261 self.write_output_prompt()
261 self.write_output_prompt()
262 format_dict, md_dict = self.compute_format_data(result)
262 format_dict, md_dict = self.compute_format_data(result)
263 self.update_user_ns(result)
263 self.update_user_ns(result)
264 self.fill_exec_result(result)
264 self.fill_exec_result(result)
265 if format_dict:
265 if format_dict:
266 self.write_format_data(format_dict, md_dict)
266 self.write_format_data(format_dict, md_dict)
267 self.log_output(format_dict)
267 self.log_output(format_dict)
268 self.finish_displayhook()
268 self.finish_displayhook()
269
269
270 def cull_cache(self):
270 def cull_cache(self):
271 """Output cache is full, cull the oldest entries"""
271 """Output cache is full, cull the oldest entries"""
272 oh = self.shell.user_ns.get('_oh', {})
272 oh = self.shell.user_ns.get('_oh', {})
273 sz = len(oh)
273 sz = len(oh)
274 cull_count = max(int(sz * self.cull_fraction), 2)
274 cull_count = max(int(sz * self.cull_fraction), 2)
275 warn('Output cache limit (currently {sz} entries) hit.\n'
275 warn('Output cache limit (currently {sz} entries) hit.\n'
276 'Flushing oldest {cull_count} entries.'.format(sz=sz, cull_count=cull_count))
276 'Flushing oldest {cull_count} entries.'.format(sz=sz, cull_count=cull_count))
277
277
278 for i, n in enumerate(sorted(oh)):
278 for i, n in enumerate(sorted(oh)):
279 if i >= cull_count:
279 if i >= cull_count:
280 break
280 break
281 self.shell.user_ns.pop('_%i' % n, None)
281 self.shell.user_ns.pop('_%i' % n, None)
282 oh.pop(n, None)
282 oh.pop(n, None)
283
283
284
284
285 def flush(self):
285 def flush(self):
286 if not self.do_full_cache:
286 if not self.do_full_cache:
287 raise ValueError("You shouldn't have reached the cache flush "
287 raise ValueError("You shouldn't have reached the cache flush "
288 "if full caching is not enabled!")
288 "if full caching is not enabled!")
289 # delete auto-generated vars from global namespace
289 # delete auto-generated vars from global namespace
290
290
291 for n in range(1,self.prompt_count + 1):
291 for n in range(1,self.prompt_count + 1):
292 key = '_'+repr(n)
292 key = '_'+repr(n)
293 try:
293 try:
294 del self.shell.user_ns[key]
294 del self.shell.user_ns[key]
295 except: pass
295 except: pass
296 # In some embedded circumstances, the user_ns doesn't have the
296 # In some embedded circumstances, the user_ns doesn't have the
297 # '_oh' key set up.
297 # '_oh' key set up.
298 oh = self.shell.user_ns.get('_oh', None)
298 oh = self.shell.user_ns.get('_oh', None)
299 if oh is not None:
299 if oh is not None:
300 oh.clear()
300 oh.clear()
301
301
302 # Release our own references to objects:
302 # Release our own references to objects:
303 self._, self.__, self.___ = '', '', ''
303 self._, self.__, self.___ = '', '', ''
304
304
305 if '_' not in builtin_mod.__dict__:
305 if '_' not in builtin_mod.__dict__:
306 self.shell.user_ns.update({'_':self._,'__':self.__,'___':self.___})
306 self.shell.user_ns.update({'_':self._,'__':self.__,'___':self.___})
307 import gc
307 import gc
308 # TODO: Is this really needed?
308 # TODO: Is this really needed?
309 # IronPython blocks here forever
309 # IronPython blocks here forever
310 if sys.platform != "cli":
310 if sys.platform != "cli":
311 gc.collect()
311 gc.collect()
312
312
313
313
314 class CapturingDisplayHook(object):
314 class CapturingDisplayHook(object):
315 def __init__(self, shell, outputs=None):
315 def __init__(self, shell, outputs=None):
316 self.shell = shell
316 self.shell = shell
317 if outputs is None:
317 if outputs is None:
318 outputs = []
318 outputs = []
319 self.outputs = outputs
319 self.outputs = outputs
320
320
321 def __call__(self, result=None):
321 def __call__(self, result=None):
322 if result is None:
322 if result is None:
323 return
323 return
324 format_dict, md_dict = self.shell.display_formatter.format(result)
324 format_dict, md_dict = self.shell.display_formatter.format(result)
325 self.outputs.append({ 'data': format_dict, 'metadata': md_dict })
325 self.outputs.append({ 'data': format_dict, 'metadata': md_dict })
@@ -1,138 +1,138 b''
1 """An interface for publishing rich data to frontends.
1 """An interface for publishing rich data to frontends.
2
2
3 There are two components of the display system:
3 There are two components of the display system:
4
4
5 * Display formatters, which take a Python object and compute the
5 * Display formatters, which take a Python object and compute the
6 representation of the object in various formats (text, HTML, SVG, etc.).
6 representation of the object in various formats (text, HTML, SVG, etc.).
7 * The display publisher that is used to send the representation data to the
7 * The display publisher that is used to send the representation data to the
8 various frontends.
8 various frontends.
9
9
10 This module defines the logic display publishing. The display publisher uses
10 This module defines the logic display publishing. The display publisher uses
11 the ``display_data`` message type that is defined in the IPython messaging
11 the ``display_data`` message type that is defined in the IPython messaging
12 spec.
12 spec.
13 """
13 """
14
14
15 # Copyright (c) IPython Development Team.
15 # Copyright (c) IPython Development Team.
16 # Distributed under the terms of the Modified BSD License.
16 # Distributed under the terms of the Modified BSD License.
17
17
18
18
19 import sys
19 import sys
20
20
21 from traitlets.config.configurable import Configurable
21 from traitlets.config.configurable import Configurable
22 from traitlets import List
22 from traitlets import List
23
23
24 # This used to be defined here - it is imported for backwards compatibility
24 # This used to be defined here - it is imported for backwards compatibility
25 from .display_functions import publish_display_data
25 from .display_functions import publish_display_data
26
26
27 #-----------------------------------------------------------------------------
27 #-----------------------------------------------------------------------------
28 # Main payload class
28 # Main payload class
29 #-----------------------------------------------------------------------------
29 #-----------------------------------------------------------------------------
30
30
31
31
32 class DisplayPublisher(Configurable):
32 class DisplayPublisher(Configurable):
33 """A traited class that publishes display data to frontends.
33 """A traited class that publishes display data to frontends.
34
34
35 Instances of this class are created by the main IPython object and should
35 Instances of this class are created by the main IPython object and should
36 be accessed there.
36 be accessed there.
37 """
37 """
38
38
39 def __init__(self, shell=None, *args, **kwargs):
39 def __init__(self, shell=None, *args, **kwargs):
40 self.shell = shell
40 self.shell = shell
41 super().__init__(*args, **kwargs)
41 super().__init__(*args, **kwargs)
42
42
43 def _validate_data(self, data, metadata=None):
43 def _validate_data(self, data, metadata=None):
44 """Validate the display data.
44 """Validate the display data.
45
45
46 Parameters
46 Parameters
47 ----------
47 ----------
48 data : dict
48 data : dict
49 The formata data dictionary.
49 The formata data dictionary.
50 metadata : dict
50 metadata : dict
51 Any metadata for the data.
51 Any metadata for the data.
52 """
52 """
53
53
54 if not isinstance(data, dict):
54 if not isinstance(data, dict):
55 raise TypeError('data must be a dict, got: %r' % data)
55 raise TypeError('data must be a dict, got: %r' % data)
56 if metadata is not None:
56 if metadata is not None:
57 if not isinstance(metadata, dict):
57 if not isinstance(metadata, dict):
58 raise TypeError('metadata must be a dict, got: %r' % data)
58 raise TypeError('metadata must be a dict, got: %r' % data)
59
59
60 # use * to indicate transient, update are keyword-only
60 # use * to indicate transient, update are keyword-only
61 def publish(self, data, metadata=None, source=None, *, transient=None, update=False, **kwargs) -> None:
61 def publish(self, data, metadata=None, source=None, *, transient=None, update=False, **kwargs) -> None:
62 """Publish data and metadata to all frontends.
62 """Publish data and metadata to all frontends.
63
63
64 See the ``display_data`` message in the messaging documentation for
64 See the ``display_data`` message in the messaging documentation for
65 more details about this message type.
65 more details about this message type.
66
66
67 The following MIME types are currently implemented:
67 The following MIME types are currently implemented:
68
68
69 * text/plain
69 * text/plain
70 * text/html
70 * text/html
71 * text/markdown
71 * text/markdown
72 * text/latex
72 * text/latex
73 * application/json
73 * application/json
74 * application/javascript
74 * application/javascript
75 * image/png
75 * image/png
76 * image/jpeg
76 * image/jpeg
77 * image/svg+xml
77 * image/svg+xml
78
78
79 Parameters
79 Parameters
80 ----------
80 ----------
81 data : dict
81 data : dict
82 A dictionary having keys that are valid MIME types (like
82 A dictionary having keys that are valid MIME types (like
83 'text/plain' or 'image/svg+xml') and values that are the data for
83 'text/plain' or 'image/svg+xml') and values that are the data for
84 that MIME type. The data itself must be a JSON'able data
84 that MIME type. The data itself must be a JSON'able data
85 structure. Minimally all data should have the 'text/plain' data,
85 structure. Minimally all data should have the 'text/plain' data,
86 which can be displayed by all frontends. If more than the plain
86 which can be displayed by all frontends. If more than the plain
87 text is given, it is up to the frontend to decide which
87 text is given, it is up to the frontend to decide which
88 representation to use.
88 representation to use.
89 metadata : dict
89 metadata : dict
90 A dictionary for metadata related to the data. This can contain
90 A dictionary for metadata related to the data. This can contain
91 arbitrary key, value pairs that frontends can use to interpret
91 arbitrary key, value pairs that frontends can use to interpret
92 the data. Metadata specific to each mime-type can be specified
92 the data. Metadata specific to each mime-type can be specified
93 in the metadata dict with the same mime-type keys as
93 in the metadata dict with the same mime-type keys as
94 the data itself.
94 the data itself.
95 source : str, deprecated
95 source : str, deprecated
96 Unused.
96 Unused.
97 transient: dict, keyword-only
97 transient : dict, keyword-only
98 A dictionary for transient data.
98 A dictionary for transient data.
99 Data in this dictionary should not be persisted as part of saving this output.
99 Data in this dictionary should not be persisted as part of saving this output.
100 Examples include 'display_id'.
100 Examples include 'display_id'.
101 update: bool, keyword-only, default: False
101 update : bool, keyword-only, default: False
102 If True, only update existing outputs with the same display_id,
102 If True, only update existing outputs with the same display_id,
103 rather than creating a new output.
103 rather than creating a new output.
104 """
104 """
105
105
106 handlers = {}
106 handlers = {}
107 if self.shell is not None:
107 if self.shell is not None:
108 handlers = getattr(self.shell, 'mime_renderers', {})
108 handlers = getattr(self.shell, 'mime_renderers', {})
109
109
110 for mime, handler in handlers.items():
110 for mime, handler in handlers.items():
111 if mime in data:
111 if mime in data:
112 handler(data[mime], metadata.get(mime, None))
112 handler(data[mime], metadata.get(mime, None))
113 return
113 return
114
114
115 if 'text/plain' in data:
115 if 'text/plain' in data:
116 print(data['text/plain'])
116 print(data['text/plain'])
117
117
118 def clear_output(self, wait=False):
118 def clear_output(self, wait=False):
119 """Clear the output of the cell receiving output."""
119 """Clear the output of the cell receiving output."""
120 print('\033[2K\r', end='')
120 print('\033[2K\r', end='')
121 sys.stdout.flush()
121 sys.stdout.flush()
122 print('\033[2K\r', end='')
122 print('\033[2K\r', end='')
123 sys.stderr.flush()
123 sys.stderr.flush()
124
124
125
125
126 class CapturingDisplayPublisher(DisplayPublisher):
126 class CapturingDisplayPublisher(DisplayPublisher):
127 """A DisplayPublisher that stores"""
127 """A DisplayPublisher that stores"""
128 outputs = List()
128 outputs = List()
129
129
130 def publish(self, data, metadata=None, source=None, *, transient=None, update=False):
130 def publish(self, data, metadata=None, source=None, *, transient=None, update=False):
131 self.outputs.append({'data':data, 'metadata':metadata,
131 self.outputs.append({'data':data, 'metadata':metadata,
132 'transient':transient, 'update':update})
132 'transient':transient, 'update':update})
133
133
134 def clear_output(self, wait=False):
134 def clear_output(self, wait=False):
135 super(CapturingDisplayPublisher, self).clear_output(wait)
135 super(CapturingDisplayPublisher, self).clear_output(wait)
136
136
137 # empty the list, *do not* reassign a new list
137 # empty the list, *do not* reassign a new list
138 self.outputs.clear()
138 self.outputs.clear()
@@ -1,161 +1,161 b''
1 """Infrastructure for registering and firing callbacks on application events.
1 """Infrastructure for registering and firing callbacks on application events.
2
2
3 Unlike :mod:`IPython.core.hooks`, which lets end users set single functions to
3 Unlike :mod:`IPython.core.hooks`, which lets end users set single functions to
4 be called at specific times, or a collection of alternative methods to try,
4 be called at specific times, or a collection of alternative methods to try,
5 callbacks are designed to be used by extension authors. A number of callbacks
5 callbacks are designed to be used by extension authors. A number of callbacks
6 can be registered for the same event without needing to be aware of one another.
6 can be registered for the same event without needing to be aware of one another.
7
7
8 The functions defined in this module are no-ops indicating the names of available
8 The functions defined in this module are no-ops indicating the names of available
9 events and the arguments which will be passed to them.
9 events and the arguments which will be passed to them.
10
10
11 .. note::
11 .. note::
12
12
13 This API is experimental in IPython 2.0, and may be revised in future versions.
13 This API is experimental in IPython 2.0, and may be revised in future versions.
14 """
14 """
15
15
16 from backcall import callback_prototype
16 from backcall import callback_prototype
17
17
18
18
19 class EventManager(object):
19 class EventManager(object):
20 """Manage a collection of events and a sequence of callbacks for each.
20 """Manage a collection of events and a sequence of callbacks for each.
21
21
22 This is attached to :class:`~IPython.core.interactiveshell.InteractiveShell`
22 This is attached to :class:`~IPython.core.interactiveshell.InteractiveShell`
23 instances as an ``events`` attribute.
23 instances as an ``events`` attribute.
24
24
25 .. note::
25 .. note::
26
26
27 This API is experimental in IPython 2.0, and may be revised in future versions.
27 This API is experimental in IPython 2.0, and may be revised in future versions.
28 """
28 """
29 def __init__(self, shell, available_events):
29 def __init__(self, shell, available_events):
30 """Initialise the :class:`CallbackManager`.
30 """Initialise the :class:`CallbackManager`.
31
31
32 Parameters
32 Parameters
33 ----------
33 ----------
34 shell
34 shell
35 The :class:`~IPython.core.interactiveshell.InteractiveShell` instance
35 The :class:`~IPython.core.interactiveshell.InteractiveShell` instance
36 available_callbacks
36 available_events
37 An iterable of names for callback events.
37 An iterable of names for callback events.
38 """
38 """
39 self.shell = shell
39 self.shell = shell
40 self.callbacks = {n:[] for n in available_events}
40 self.callbacks = {n:[] for n in available_events}
41
41
42 def register(self, event, function):
42 def register(self, event, function):
43 """Register a new event callback.
43 """Register a new event callback.
44
44
45 Parameters
45 Parameters
46 ----------
46 ----------
47 event : str
47 event : str
48 The event for which to register this callback.
48 The event for which to register this callback.
49 function : callable
49 function : callable
50 A function to be called on the given event. It should take the same
50 A function to be called on the given event. It should take the same
51 parameters as the appropriate callback prototype.
51 parameters as the appropriate callback prototype.
52
52
53 Raises
53 Raises
54 ------
54 ------
55 TypeError
55 TypeError
56 If ``function`` is not callable.
56 If ``function`` is not callable.
57 KeyError
57 KeyError
58 If ``event`` is not one of the known events.
58 If ``event`` is not one of the known events.
59 """
59 """
60 if not callable(function):
60 if not callable(function):
61 raise TypeError('Need a callable, got %r' % function)
61 raise TypeError('Need a callable, got %r' % function)
62 callback_proto = available_events.get(event)
62 callback_proto = available_events.get(event)
63 if function not in self.callbacks[event]:
63 if function not in self.callbacks[event]:
64 self.callbacks[event].append(callback_proto.adapt(function))
64 self.callbacks[event].append(callback_proto.adapt(function))
65
65
66 def unregister(self, event, function):
66 def unregister(self, event, function):
67 """Remove a callback from the given event."""
67 """Remove a callback from the given event."""
68 if function in self.callbacks[event]:
68 if function in self.callbacks[event]:
69 return self.callbacks[event].remove(function)
69 return self.callbacks[event].remove(function)
70
70
71 # Remove callback in case ``function`` was adapted by `backcall`.
71 # Remove callback in case ``function`` was adapted by `backcall`.
72 for callback in self.callbacks[event]:
72 for callback in self.callbacks[event]:
73 try:
73 try:
74 if callback.__wrapped__ is function:
74 if callback.__wrapped__ is function:
75 return self.callbacks[event].remove(callback)
75 return self.callbacks[event].remove(callback)
76 except AttributeError:
76 except AttributeError:
77 pass
77 pass
78
78
79 raise ValueError('Function {!r} is not registered as a {} callback'.format(function, event))
79 raise ValueError('Function {!r} is not registered as a {} callback'.format(function, event))
80
80
81 def trigger(self, event, *args, **kwargs):
81 def trigger(self, event, *args, **kwargs):
82 """Call callbacks for ``event``.
82 """Call callbacks for ``event``.
83
83
84 Any additional arguments are passed to all callbacks registered for this
84 Any additional arguments are passed to all callbacks registered for this
85 event. Exceptions raised by callbacks are caught, and a message printed.
85 event. Exceptions raised by callbacks are caught, and a message printed.
86 """
86 """
87 for func in self.callbacks[event][:]:
87 for func in self.callbacks[event][:]:
88 try:
88 try:
89 func(*args, **kwargs)
89 func(*args, **kwargs)
90 except (Exception, KeyboardInterrupt):
90 except (Exception, KeyboardInterrupt):
91 print("Error in callback {} (for {}):".format(func, event))
91 print("Error in callback {} (for {}):".format(func, event))
92 self.shell.showtraceback()
92 self.shell.showtraceback()
93
93
94 # event_name -> prototype mapping
94 # event_name -> prototype mapping
95 available_events = {}
95 available_events = {}
96
96
97 def _define_event(callback_function):
97 def _define_event(callback_function):
98 callback_proto = callback_prototype(callback_function)
98 callback_proto = callback_prototype(callback_function)
99 available_events[callback_function.__name__] = callback_proto
99 available_events[callback_function.__name__] = callback_proto
100 return callback_proto
100 return callback_proto
101
101
102 # ------------------------------------------------------------------------------
102 # ------------------------------------------------------------------------------
103 # Callback prototypes
103 # Callback prototypes
104 #
104 #
105 # No-op functions which describe the names of available events and the
105 # No-op functions which describe the names of available events and the
106 # signatures of callbacks for those events.
106 # signatures of callbacks for those events.
107 # ------------------------------------------------------------------------------
107 # ------------------------------------------------------------------------------
108
108
109 @_define_event
109 @_define_event
110 def pre_execute():
110 def pre_execute():
111 """Fires before code is executed in response to user/frontend action.
111 """Fires before code is executed in response to user/frontend action.
112
112
113 This includes comm and widget messages and silent execution, as well as user
113 This includes comm and widget messages and silent execution, as well as user
114 code cells.
114 code cells.
115 """
115 """
116 pass
116 pass
117
117
118 @_define_event
118 @_define_event
119 def pre_run_cell(info):
119 def pre_run_cell(info):
120 """Fires before user-entered code runs.
120 """Fires before user-entered code runs.
121
121
122 Parameters
122 Parameters
123 ----------
123 ----------
124 info : :class:`~IPython.core.interactiveshell.ExecutionInfo`
124 info : :class:`~IPython.core.interactiveshell.ExecutionInfo`
125 An object containing information used for the code execution.
125 An object containing information used for the code execution.
126 """
126 """
127 pass
127 pass
128
128
129 @_define_event
129 @_define_event
130 def post_execute():
130 def post_execute():
131 """Fires after code is executed in response to user/frontend action.
131 """Fires after code is executed in response to user/frontend action.
132
132
133 This includes comm and widget messages and silent execution, as well as user
133 This includes comm and widget messages and silent execution, as well as user
134 code cells.
134 code cells.
135 """
135 """
136 pass
136 pass
137
137
138 @_define_event
138 @_define_event
139 def post_run_cell(result):
139 def post_run_cell(result):
140 """Fires after user-entered code runs.
140 """Fires after user-entered code runs.
141
141
142 Parameters
142 Parameters
143 ----------
143 ----------
144 result : :class:`~IPython.core.interactiveshell.ExecutionResult`
144 result : :class:`~IPython.core.interactiveshell.ExecutionResult`
145 The object which will be returned as the execution result.
145 The object which will be returned as the execution result.
146 """
146 """
147 pass
147 pass
148
148
149 @_define_event
149 @_define_event
150 def shell_initialized(ip):
150 def shell_initialized(ip):
151 """Fires after initialisation of :class:`~IPython.core.interactiveshell.InteractiveShell`.
151 """Fires after initialisation of :class:`~IPython.core.interactiveshell.InteractiveShell`.
152
152
153 This is before extensions and startup scripts are loaded, so it can only be
153 This is before extensions and startup scripts are loaded, so it can only be
154 set by subclassing.
154 set by subclassing.
155
155
156 Parameters
156 Parameters
157 ----------
157 ----------
158 ip : :class:`~IPython.core.interactiveshell.InteractiveShell`
158 ip : :class:`~IPython.core.interactiveshell.InteractiveShell`
159 The newly initialised shell.
159 The newly initialised shell.
160 """
160 """
161 pass
161 pass
@@ -1,150 +1,150 b''
1 # encoding: utf-8
1 # encoding: utf-8
2 """A class for managing IPython extensions."""
2 """A class for managing IPython extensions."""
3
3
4 # Copyright (c) IPython Development Team.
4 # Copyright (c) IPython Development Team.
5 # Distributed under the terms of the Modified BSD License.
5 # Distributed under the terms of the Modified BSD License.
6
6
7 import os
7 import os
8 import os.path
8 import os.path
9 import sys
9 import sys
10 from importlib import import_module, reload
10 from importlib import import_module, reload
11
11
12 from traitlets.config.configurable import Configurable
12 from traitlets.config.configurable import Configurable
13 from IPython.utils.path import ensure_dir_exists, compress_user
13 from IPython.utils.path import ensure_dir_exists, compress_user
14 from IPython.utils.decorators import undoc
14 from IPython.utils.decorators import undoc
15 from traitlets import Instance
15 from traitlets import Instance
16
16
17
17
18 #-----------------------------------------------------------------------------
18 #-----------------------------------------------------------------------------
19 # Main class
19 # Main class
20 #-----------------------------------------------------------------------------
20 #-----------------------------------------------------------------------------
21
21
22 class ExtensionManager(Configurable):
22 class ExtensionManager(Configurable):
23 """A class to manage IPython extensions.
23 """A class to manage IPython extensions.
24
24
25 An IPython extension is an importable Python module that has
25 An IPython extension is an importable Python module that has
26 a function with the signature::
26 a function with the signature::
27
27
28 def load_ipython_extension(ipython):
28 def load_ipython_extension(ipython):
29 # Do things with ipython
29 # Do things with ipython
30
30
31 This function is called after your extension is imported and the
31 This function is called after your extension is imported and the
32 currently active :class:`InteractiveShell` instance is passed as
32 currently active :class:`InteractiveShell` instance is passed as
33 the only argument. You can do anything you want with IPython at
33 the only argument. You can do anything you want with IPython at
34 that point, including defining new magic and aliases, adding new
34 that point, including defining new magic and aliases, adding new
35 components, etc.
35 components, etc.
36
36
37 You can also optionally define an :func:`unload_ipython_extension(ipython)`
37 You can also optionally define an :func:`unload_ipython_extension(ipython)`
38 function, which will be called if the user unloads or reloads the extension.
38 function, which will be called if the user unloads or reloads the extension.
39 The extension manager will only call :func:`load_ipython_extension` again
39 The extension manager will only call :func:`load_ipython_extension` again
40 if the extension is reloaded.
40 if the extension is reloaded.
41
41
42 You can put your extension modules anywhere you want, as long as
42 You can put your extension modules anywhere you want, as long as
43 they can be imported by Python's standard import mechanism. However,
43 they can be imported by Python's standard import mechanism. However,
44 to make it easy to write extensions, you can also put your extensions
44 to make it easy to write extensions, you can also put your extensions
45 in ``os.path.join(self.ipython_dir, 'extensions')``. This directory
45 in ``os.path.join(self.ipython_dir, 'extensions')``. This directory
46 is added to ``sys.path`` automatically.
46 is added to ``sys.path`` automatically.
47 """
47 """
48
48
49 shell = Instance('IPython.core.interactiveshell.InteractiveShellABC', allow_none=True)
49 shell = Instance('IPython.core.interactiveshell.InteractiveShellABC', allow_none=True)
50
50
51 def __init__(self, shell=None, **kwargs):
51 def __init__(self, shell=None, **kwargs):
52 super(ExtensionManager, self).__init__(shell=shell, **kwargs)
52 super(ExtensionManager, self).__init__(shell=shell, **kwargs)
53 self.shell.observe(
53 self.shell.observe(
54 self._on_ipython_dir_changed, names=('ipython_dir',)
54 self._on_ipython_dir_changed, names=('ipython_dir',)
55 )
55 )
56 self.loaded = set()
56 self.loaded = set()
57
57
58 @property
58 @property
59 def ipython_extension_dir(self):
59 def ipython_extension_dir(self):
60 return os.path.join(self.shell.ipython_dir, u'extensions')
60 return os.path.join(self.shell.ipython_dir, u'extensions')
61
61
62 def _on_ipython_dir_changed(self, change):
62 def _on_ipython_dir_changed(self, change):
63 ensure_dir_exists(self.ipython_extension_dir)
63 ensure_dir_exists(self.ipython_extension_dir)
64
64
65 def load_extension(self, module_str):
65 def load_extension(self, module_str):
66 """Load an IPython extension by its module name.
66 """Load an IPython extension by its module name.
67
67
68 Returns the string "already loaded" if the extension is already loaded,
68 Returns the string "already loaded" if the extension is already loaded,
69 "no load function" if the module doesn't have a load_ipython_extension
69 "no load function" if the module doesn't have a load_ipython_extension
70 function, or None if it succeeded.
70 function, or None if it succeeded.
71 """
71 """
72 if module_str in self.loaded:
72 if module_str in self.loaded:
73 return "already loaded"
73 return "already loaded"
74
74
75 from IPython.utils.syspathcontext import prepended_to_syspath
75 from IPython.utils.syspathcontext import prepended_to_syspath
76
76
77 with self.shell.builtin_trap:
77 with self.shell.builtin_trap:
78 if module_str not in sys.modules:
78 if module_str not in sys.modules:
79 with prepended_to_syspath(self.ipython_extension_dir):
79 with prepended_to_syspath(self.ipython_extension_dir):
80 mod = import_module(module_str)
80 mod = import_module(module_str)
81 if mod.__file__.startswith(self.ipython_extension_dir):
81 if mod.__file__.startswith(self.ipython_extension_dir):
82 print(("Loading extensions from {dir} is deprecated. "
82 print(("Loading extensions from {dir} is deprecated. "
83 "We recommend managing extensions like any "
83 "We recommend managing extensions like any "
84 "other Python packages, in site-packages.").format(
84 "other Python packages, in site-packages.").format(
85 dir=compress_user(self.ipython_extension_dir)))
85 dir=compress_user(self.ipython_extension_dir)))
86 mod = sys.modules[module_str]
86 mod = sys.modules[module_str]
87 if self._call_load_ipython_extension(mod):
87 if self._call_load_ipython_extension(mod):
88 self.loaded.add(module_str)
88 self.loaded.add(module_str)
89 else:
89 else:
90 return "no load function"
90 return "no load function"
91
91
92 def unload_extension(self, module_str):
92 def unload_extension(self, module_str):
93 """Unload an IPython extension by its module name.
93 """Unload an IPython extension by its module name.
94
94
95 This function looks up the extension's name in ``sys.modules`` and
95 This function looks up the extension's name in ``sys.modules`` and
96 simply calls ``mod.unload_ipython_extension(self)``.
96 simply calls ``mod.unload_ipython_extension(self)``.
97
97
98 Returns the string "no unload function" if the extension doesn't define
98 Returns the string "no unload function" if the extension doesn't define
99 a function to unload itself, "not loaded" if the extension isn't loaded,
99 a function to unload itself, "not loaded" if the extension isn't loaded,
100 otherwise None.
100 otherwise None.
101 """
101 """
102 if module_str not in self.loaded:
102 if module_str not in self.loaded:
103 return "not loaded"
103 return "not loaded"
104
104
105 if module_str in sys.modules:
105 if module_str in sys.modules:
106 mod = sys.modules[module_str]
106 mod = sys.modules[module_str]
107 if self._call_unload_ipython_extension(mod):
107 if self._call_unload_ipython_extension(mod):
108 self.loaded.discard(module_str)
108 self.loaded.discard(module_str)
109 else:
109 else:
110 return "no unload function"
110 return "no unload function"
111
111
112 def reload_extension(self, module_str):
112 def reload_extension(self, module_str):
113 """Reload an IPython extension by calling reload.
113 """Reload an IPython extension by calling reload.
114
114
115 If the module has not been loaded before,
115 If the module has not been loaded before,
116 :meth:`InteractiveShell.load_extension` is called. Otherwise
116 :meth:`InteractiveShell.load_extension` is called. Otherwise
117 :func:`reload` is called and then the :func:`load_ipython_extension`
117 :func:`reload` is called and then the :func:`load_ipython_extension`
118 function of the module, if it exists is called.
118 function of the module, if it exists is called.
119 """
119 """
120 from IPython.utils.syspathcontext import prepended_to_syspath
120 from IPython.utils.syspathcontext import prepended_to_syspath
121
121
122 if (module_str in self.loaded) and (module_str in sys.modules):
122 if (module_str in self.loaded) and (module_str in sys.modules):
123 self.unload_extension(module_str)
123 self.unload_extension(module_str)
124 mod = sys.modules[module_str]
124 mod = sys.modules[module_str]
125 with prepended_to_syspath(self.ipython_extension_dir):
125 with prepended_to_syspath(self.ipython_extension_dir):
126 reload(mod)
126 reload(mod)
127 if self._call_load_ipython_extension(mod):
127 if self._call_load_ipython_extension(mod):
128 self.loaded.add(module_str)
128 self.loaded.add(module_str)
129 else:
129 else:
130 self.load_extension(module_str)
130 self.load_extension(module_str)
131
131
132 def _call_load_ipython_extension(self, mod):
132 def _call_load_ipython_extension(self, mod):
133 if hasattr(mod, 'load_ipython_extension'):
133 if hasattr(mod, 'load_ipython_extension'):
134 mod.load_ipython_extension(self.shell)
134 mod.load_ipython_extension(self.shell)
135 return True
135 return True
136
136
137 def _call_unload_ipython_extension(self, mod):
137 def _call_unload_ipython_extension(self, mod):
138 if hasattr(mod, 'unload_ipython_extension'):
138 if hasattr(mod, 'unload_ipython_extension'):
139 mod.unload_ipython_extension(self.shell)
139 mod.unload_ipython_extension(self.shell)
140 return True
140 return True
141
141
142 @undoc
142 @undoc
143 def install_extension(self, url, filename=None):
143 def install_extension(self, url, filename=None):
144 """
144 """
145 Deprecated.
145 Deprecated.
146 """
146 """
147 # Ensure the extension directory exists
147 # Ensure the extension directory exists
148 raise DeprecationWarning(
148 raise DeprecationWarning(
149 '`install_extension` and the `install_ext` magic have been deprecated since IPython 4.0'
149 '`install_extension` and the `install_ext` magic have been deprecated since IPython 4.0'
150 'Use pip or other package managers to manage ipython extensions.')
150 'Use pip or other package managers to manage ipython extensions.')
@@ -1,1028 +1,1026 b''
1 # -*- coding: utf-8 -*-
1 # -*- coding: utf-8 -*-
2 """Display formatters.
2 """Display formatters.
3
3
4 Inheritance diagram:
4 Inheritance diagram:
5
5
6 .. inheritance-diagram:: IPython.core.formatters
6 .. inheritance-diagram:: IPython.core.formatters
7 :parts: 3
7 :parts: 3
8 """
8 """
9
9
10 # Copyright (c) IPython Development Team.
10 # Copyright (c) IPython Development Team.
11 # Distributed under the terms of the Modified BSD License.
11 # Distributed under the terms of the Modified BSD License.
12
12
13 import abc
13 import abc
14 import json
14 import json
15 import sys
15 import sys
16 import traceback
16 import traceback
17 import warnings
17 import warnings
18 from io import StringIO
18 from io import StringIO
19
19
20 from decorator import decorator
20 from decorator import decorator
21
21
22 from traitlets.config.configurable import Configurable
22 from traitlets.config.configurable import Configurable
23 from .getipython import get_ipython
23 from .getipython import get_ipython
24 from ..utils.sentinel import Sentinel
24 from ..utils.sentinel import Sentinel
25 from ..utils.dir2 import get_real_method
25 from ..utils.dir2 import get_real_method
26 from ..lib import pretty
26 from ..lib import pretty
27 from traitlets import (
27 from traitlets import (
28 Bool, Dict, Integer, Unicode, CUnicode, ObjectName, List,
28 Bool, Dict, Integer, Unicode, CUnicode, ObjectName, List,
29 ForwardDeclaredInstance,
29 ForwardDeclaredInstance,
30 default, observe,
30 default, observe,
31 )
31 )
32
32
33
33
34 class DisplayFormatter(Configurable):
34 class DisplayFormatter(Configurable):
35
35
36 active_types = List(Unicode(),
36 active_types = List(Unicode(),
37 help="""List of currently active mime-types to display.
37 help="""List of currently active mime-types to display.
38 You can use this to set a white-list for formats to display.
38 You can use this to set a white-list for formats to display.
39
39
40 Most users will not need to change this value.
40 Most users will not need to change this value.
41 """).tag(config=True)
41 """).tag(config=True)
42
42
43 @default('active_types')
43 @default('active_types')
44 def _active_types_default(self):
44 def _active_types_default(self):
45 return self.format_types
45 return self.format_types
46
46
47 @observe('active_types')
47 @observe('active_types')
48 def _active_types_changed(self, change):
48 def _active_types_changed(self, change):
49 for key, formatter in self.formatters.items():
49 for key, formatter in self.formatters.items():
50 if key in change['new']:
50 if key in change['new']:
51 formatter.enabled = True
51 formatter.enabled = True
52 else:
52 else:
53 formatter.enabled = False
53 formatter.enabled = False
54
54
55 ipython_display_formatter = ForwardDeclaredInstance('FormatterABC')
55 ipython_display_formatter = ForwardDeclaredInstance('FormatterABC')
56 @default('ipython_display_formatter')
56 @default('ipython_display_formatter')
57 def _default_formatter(self):
57 def _default_formatter(self):
58 return IPythonDisplayFormatter(parent=self)
58 return IPythonDisplayFormatter(parent=self)
59
59
60 mimebundle_formatter = ForwardDeclaredInstance('FormatterABC')
60 mimebundle_formatter = ForwardDeclaredInstance('FormatterABC')
61 @default('mimebundle_formatter')
61 @default('mimebundle_formatter')
62 def _default_mime_formatter(self):
62 def _default_mime_formatter(self):
63 return MimeBundleFormatter(parent=self)
63 return MimeBundleFormatter(parent=self)
64
64
65 # A dict of formatter whose keys are format types (MIME types) and whose
65 # A dict of formatter whose keys are format types (MIME types) and whose
66 # values are subclasses of BaseFormatter.
66 # values are subclasses of BaseFormatter.
67 formatters = Dict()
67 formatters = Dict()
68 @default('formatters')
68 @default('formatters')
69 def _formatters_default(self):
69 def _formatters_default(self):
70 """Activate the default formatters."""
70 """Activate the default formatters."""
71 formatter_classes = [
71 formatter_classes = [
72 PlainTextFormatter,
72 PlainTextFormatter,
73 HTMLFormatter,
73 HTMLFormatter,
74 MarkdownFormatter,
74 MarkdownFormatter,
75 SVGFormatter,
75 SVGFormatter,
76 PNGFormatter,
76 PNGFormatter,
77 PDFFormatter,
77 PDFFormatter,
78 JPEGFormatter,
78 JPEGFormatter,
79 LatexFormatter,
79 LatexFormatter,
80 JSONFormatter,
80 JSONFormatter,
81 JavascriptFormatter
81 JavascriptFormatter
82 ]
82 ]
83 d = {}
83 d = {}
84 for cls in formatter_classes:
84 for cls in formatter_classes:
85 f = cls(parent=self)
85 f = cls(parent=self)
86 d[f.format_type] = f
86 d[f.format_type] = f
87 return d
87 return d
88
88
89 def format(self, obj, include=None, exclude=None):
89 def format(self, obj, include=None, exclude=None):
90 """Return a format data dict for an object.
90 """Return a format data dict for an object.
91
91
92 By default all format types will be computed.
92 By default all format types will be computed.
93
93
94 The following MIME types are usually implemented:
94 The following MIME types are usually implemented:
95
95
96 * text/plain
96 * text/plain
97 * text/html
97 * text/html
98 * text/markdown
98 * text/markdown
99 * text/latex
99 * text/latex
100 * application/json
100 * application/json
101 * application/javascript
101 * application/javascript
102 * application/pdf
102 * application/pdf
103 * image/png
103 * image/png
104 * image/jpeg
104 * image/jpeg
105 * image/svg+xml
105 * image/svg+xml
106
106
107 Parameters
107 Parameters
108 ----------
108 ----------
109 obj : object
109 obj : object
110 The Python object whose format data will be computed.
110 The Python object whose format data will be computed.
111 include : list, tuple or set; optional
111 include : list, tuple or set; optional
112 A list of format type strings (MIME types) to include in the
112 A list of format type strings (MIME types) to include in the
113 format data dict. If this is set *only* the format types included
113 format data dict. If this is set *only* the format types included
114 in this list will be computed.
114 in this list will be computed.
115 exclude : list, tuple or set; optional
115 exclude : list, tuple or set; optional
116 A list of format type string (MIME types) to exclude in the format
116 A list of format type string (MIME types) to exclude in the format
117 data dict. If this is set all format types will be computed,
117 data dict. If this is set all format types will be computed,
118 except for those included in this argument.
118 except for those included in this argument.
119 Mimetypes present in exclude will take precedence over the ones in include
119 Mimetypes present in exclude will take precedence over the ones in include
120
120
121 Returns
121 Returns
122 -------
122 -------
123 (format_dict, metadata_dict) : tuple of two dicts
123 (format_dict, metadata_dict) : tuple of two dicts
124
125 format_dict is a dictionary of key/value pairs, one of each format that was
124 format_dict is a dictionary of key/value pairs, one of each format that was
126 generated for the object. The keys are the format types, which
125 generated for the object. The keys are the format types, which
127 will usually be MIME type strings and the values and JSON'able
126 will usually be MIME type strings and the values and JSON'able
128 data structure containing the raw data for the representation in
127 data structure containing the raw data for the representation in
129 that format.
128 that format.
130
129
131 metadata_dict is a dictionary of metadata about each mime-type output.
130 metadata_dict is a dictionary of metadata about each mime-type output.
132 Its keys will be a strict subset of the keys in format_dict.
131 Its keys will be a strict subset of the keys in format_dict.
133
132
134 Notes
133 Notes
135 -----
134 -----
136
137 If an object implement `_repr_mimebundle_` as well as various
135 If an object implement `_repr_mimebundle_` as well as various
138 `_repr_*_`, the data returned by `_repr_mimebundle_` will take
136 `_repr_*_`, the data returned by `_repr_mimebundle_` will take
139 precedence and the corresponding `_repr_*_` for this mimetype will
137 precedence and the corresponding `_repr_*_` for this mimetype will
140 not be called.
138 not be called.
141
139
142 """
140 """
143 format_dict = {}
141 format_dict = {}
144 md_dict = {}
142 md_dict = {}
145
143
146 if self.ipython_display_formatter(obj):
144 if self.ipython_display_formatter(obj):
147 # object handled itself, don't proceed
145 # object handled itself, don't proceed
148 return {}, {}
146 return {}, {}
149
147
150 format_dict, md_dict = self.mimebundle_formatter(obj, include=include, exclude=exclude)
148 format_dict, md_dict = self.mimebundle_formatter(obj, include=include, exclude=exclude)
151
149
152 if format_dict or md_dict:
150 if format_dict or md_dict:
153 if include:
151 if include:
154 format_dict = {k:v for k,v in format_dict.items() if k in include}
152 format_dict = {k:v for k,v in format_dict.items() if k in include}
155 md_dict = {k:v for k,v in md_dict.items() if k in include}
153 md_dict = {k:v for k,v in md_dict.items() if k in include}
156 if exclude:
154 if exclude:
157 format_dict = {k:v for k,v in format_dict.items() if k not in exclude}
155 format_dict = {k:v for k,v in format_dict.items() if k not in exclude}
158 md_dict = {k:v for k,v in md_dict.items() if k not in exclude}
156 md_dict = {k:v for k,v in md_dict.items() if k not in exclude}
159
157
160 for format_type, formatter in self.formatters.items():
158 for format_type, formatter in self.formatters.items():
161 if format_type in format_dict:
159 if format_type in format_dict:
162 # already got it from mimebundle, maybe don't render again.
160 # already got it from mimebundle, maybe don't render again.
163 # exception: manually registered per-mime renderer
161 # exception: manually registered per-mime renderer
164 # check priority:
162 # check priority:
165 # 1. user-registered per-mime formatter
163 # 1. user-registered per-mime formatter
166 # 2. mime-bundle (user-registered or repr method)
164 # 2. mime-bundle (user-registered or repr method)
167 # 3. default per-mime formatter (e.g. repr method)
165 # 3. default per-mime formatter (e.g. repr method)
168 try:
166 try:
169 formatter.lookup(obj)
167 formatter.lookup(obj)
170 except KeyError:
168 except KeyError:
171 # no special formatter, use mime-bundle-provided value
169 # no special formatter, use mime-bundle-provided value
172 continue
170 continue
173 if include and format_type not in include:
171 if include and format_type not in include:
174 continue
172 continue
175 if exclude and format_type in exclude:
173 if exclude and format_type in exclude:
176 continue
174 continue
177
175
178 md = None
176 md = None
179 try:
177 try:
180 data = formatter(obj)
178 data = formatter(obj)
181 except:
179 except:
182 # FIXME: log the exception
180 # FIXME: log the exception
183 raise
181 raise
184
182
185 # formatters can return raw data or (data, metadata)
183 # formatters can return raw data or (data, metadata)
186 if isinstance(data, tuple) and len(data) == 2:
184 if isinstance(data, tuple) and len(data) == 2:
187 data, md = data
185 data, md = data
188
186
189 if data is not None:
187 if data is not None:
190 format_dict[format_type] = data
188 format_dict[format_type] = data
191 if md is not None:
189 if md is not None:
192 md_dict[format_type] = md
190 md_dict[format_type] = md
193 return format_dict, md_dict
191 return format_dict, md_dict
194
192
195 @property
193 @property
196 def format_types(self):
194 def format_types(self):
197 """Return the format types (MIME types) of the active formatters."""
195 """Return the format types (MIME types) of the active formatters."""
198 return list(self.formatters.keys())
196 return list(self.formatters.keys())
199
197
200
198
201 #-----------------------------------------------------------------------------
199 #-----------------------------------------------------------------------------
202 # Formatters for specific format types (text, html, svg, etc.)
200 # Formatters for specific format types (text, html, svg, etc.)
203 #-----------------------------------------------------------------------------
201 #-----------------------------------------------------------------------------
204
202
205
203
206 def _safe_repr(obj):
204 def _safe_repr(obj):
207 """Try to return a repr of an object
205 """Try to return a repr of an object
208
206
209 always returns a string, at least.
207 always returns a string, at least.
210 """
208 """
211 try:
209 try:
212 return repr(obj)
210 return repr(obj)
213 except Exception as e:
211 except Exception as e:
214 return "un-repr-able object (%r)" % e
212 return "un-repr-able object (%r)" % e
215
213
216
214
217 class FormatterWarning(UserWarning):
215 class FormatterWarning(UserWarning):
218 """Warning class for errors in formatters"""
216 """Warning class for errors in formatters"""
219
217
220 @decorator
218 @decorator
221 def catch_format_error(method, self, *args, **kwargs):
219 def catch_format_error(method, self, *args, **kwargs):
222 """show traceback on failed format call"""
220 """show traceback on failed format call"""
223 try:
221 try:
224 r = method(self, *args, **kwargs)
222 r = method(self, *args, **kwargs)
225 except NotImplementedError:
223 except NotImplementedError:
226 # don't warn on NotImplementedErrors
224 # don't warn on NotImplementedErrors
227 return self._check_return(None, args[0])
225 return self._check_return(None, args[0])
228 except Exception:
226 except Exception:
229 exc_info = sys.exc_info()
227 exc_info = sys.exc_info()
230 ip = get_ipython()
228 ip = get_ipython()
231 if ip is not None:
229 if ip is not None:
232 ip.showtraceback(exc_info)
230 ip.showtraceback(exc_info)
233 else:
231 else:
234 traceback.print_exception(*exc_info)
232 traceback.print_exception(*exc_info)
235 return self._check_return(None, args[0])
233 return self._check_return(None, args[0])
236 return self._check_return(r, args[0])
234 return self._check_return(r, args[0])
237
235
238
236
239 class FormatterABC(metaclass=abc.ABCMeta):
237 class FormatterABC(metaclass=abc.ABCMeta):
240 """ Abstract base class for Formatters.
238 """ Abstract base class for Formatters.
241
239
242 A formatter is a callable class that is responsible for computing the
240 A formatter is a callable class that is responsible for computing the
243 raw format data for a particular format type (MIME type). For example,
241 raw format data for a particular format type (MIME type). For example,
244 an HTML formatter would have a format type of `text/html` and would return
242 an HTML formatter would have a format type of `text/html` and would return
245 the HTML representation of the object when called.
243 the HTML representation of the object when called.
246 """
244 """
247
245
248 # The format type of the data returned, usually a MIME type.
246 # The format type of the data returned, usually a MIME type.
249 format_type = 'text/plain'
247 format_type = 'text/plain'
250
248
251 # Is the formatter enabled...
249 # Is the formatter enabled...
252 enabled = True
250 enabled = True
253
251
254 @abc.abstractmethod
252 @abc.abstractmethod
255 def __call__(self, obj):
253 def __call__(self, obj):
256 """Return a JSON'able representation of the object.
254 """Return a JSON'able representation of the object.
257
255
258 If the object cannot be formatted by this formatter,
256 If the object cannot be formatted by this formatter,
259 warn and return None.
257 warn and return None.
260 """
258 """
261 return repr(obj)
259 return repr(obj)
262
260
263
261
264 def _mod_name_key(typ):
262 def _mod_name_key(typ):
265 """Return a (__module__, __name__) tuple for a type.
263 """Return a (__module__, __name__) tuple for a type.
266
264
267 Used as key in Formatter.deferred_printers.
265 Used as key in Formatter.deferred_printers.
268 """
266 """
269 module = getattr(typ, '__module__', None)
267 module = getattr(typ, '__module__', None)
270 name = getattr(typ, '__name__', None)
268 name = getattr(typ, '__name__', None)
271 return (module, name)
269 return (module, name)
272
270
273
271
274 def _get_type(obj):
272 def _get_type(obj):
275 """Return the type of an instance (old and new-style)"""
273 """Return the type of an instance (old and new-style)"""
276 return getattr(obj, '__class__', None) or type(obj)
274 return getattr(obj, '__class__', None) or type(obj)
277
275
278
276
279 _raise_key_error = Sentinel('_raise_key_error', __name__,
277 _raise_key_error = Sentinel('_raise_key_error', __name__,
280 """
278 """
281 Special value to raise a KeyError
279 Special value to raise a KeyError
282
280
283 Raise KeyError in `BaseFormatter.pop` if passed as the default value to `pop`
281 Raise KeyError in `BaseFormatter.pop` if passed as the default value to `pop`
284 """)
282 """)
285
283
286
284
287 class BaseFormatter(Configurable):
285 class BaseFormatter(Configurable):
288 """A base formatter class that is configurable.
286 """A base formatter class that is configurable.
289
287
290 This formatter should usually be used as the base class of all formatters.
288 This formatter should usually be used as the base class of all formatters.
291 It is a traited :class:`Configurable` class and includes an extensible
289 It is a traited :class:`Configurable` class and includes an extensible
292 API for users to determine how their objects are formatted. The following
290 API for users to determine how their objects are formatted. The following
293 logic is used to find a function to format an given object.
291 logic is used to find a function to format an given object.
294
292
295 1. The object is introspected to see if it has a method with the name
293 1. The object is introspected to see if it has a method with the name
296 :attr:`print_method`. If is does, that object is passed to that method
294 :attr:`print_method`. If is does, that object is passed to that method
297 for formatting.
295 for formatting.
298 2. If no print method is found, three internal dictionaries are consulted
296 2. If no print method is found, three internal dictionaries are consulted
299 to find print method: :attr:`singleton_printers`, :attr:`type_printers`
297 to find print method: :attr:`singleton_printers`, :attr:`type_printers`
300 and :attr:`deferred_printers`.
298 and :attr:`deferred_printers`.
301
299
302 Users should use these dictionaries to register functions that will be
300 Users should use these dictionaries to register functions that will be
303 used to compute the format data for their objects (if those objects don't
301 used to compute the format data for their objects (if those objects don't
304 have the special print methods). The easiest way of using these
302 have the special print methods). The easiest way of using these
305 dictionaries is through the :meth:`for_type` and :meth:`for_type_by_name`
303 dictionaries is through the :meth:`for_type` and :meth:`for_type_by_name`
306 methods.
304 methods.
307
305
308 If no function/callable is found to compute the format data, ``None`` is
306 If no function/callable is found to compute the format data, ``None`` is
309 returned and this format type is not used.
307 returned and this format type is not used.
310 """
308 """
311
309
312 format_type = Unicode('text/plain')
310 format_type = Unicode('text/plain')
313 _return_type = str
311 _return_type = str
314
312
315 enabled = Bool(True).tag(config=True)
313 enabled = Bool(True).tag(config=True)
316
314
317 print_method = ObjectName('__repr__')
315 print_method = ObjectName('__repr__')
318
316
319 # The singleton printers.
317 # The singleton printers.
320 # Maps the IDs of the builtin singleton objects to the format functions.
318 # Maps the IDs of the builtin singleton objects to the format functions.
321 singleton_printers = Dict().tag(config=True)
319 singleton_printers = Dict().tag(config=True)
322
320
323 # The type-specific printers.
321 # The type-specific printers.
324 # Map type objects to the format functions.
322 # Map type objects to the format functions.
325 type_printers = Dict().tag(config=True)
323 type_printers = Dict().tag(config=True)
326
324
327 # The deferred-import type-specific printers.
325 # The deferred-import type-specific printers.
328 # Map (modulename, classname) pairs to the format functions.
326 # Map (modulename, classname) pairs to the format functions.
329 deferred_printers = Dict().tag(config=True)
327 deferred_printers = Dict().tag(config=True)
330
328
331 @catch_format_error
329 @catch_format_error
332 def __call__(self, obj):
330 def __call__(self, obj):
333 """Compute the format for an object."""
331 """Compute the format for an object."""
334 if self.enabled:
332 if self.enabled:
335 # lookup registered printer
333 # lookup registered printer
336 try:
334 try:
337 printer = self.lookup(obj)
335 printer = self.lookup(obj)
338 except KeyError:
336 except KeyError:
339 pass
337 pass
340 else:
338 else:
341 return printer(obj)
339 return printer(obj)
342 # Finally look for special method names
340 # Finally look for special method names
343 method = get_real_method(obj, self.print_method)
341 method = get_real_method(obj, self.print_method)
344 if method is not None:
342 if method is not None:
345 return method()
343 return method()
346 return None
344 return None
347 else:
345 else:
348 return None
346 return None
349
347
350 def __contains__(self, typ):
348 def __contains__(self, typ):
351 """map in to lookup_by_type"""
349 """map in to lookup_by_type"""
352 try:
350 try:
353 self.lookup_by_type(typ)
351 self.lookup_by_type(typ)
354 except KeyError:
352 except KeyError:
355 return False
353 return False
356 else:
354 else:
357 return True
355 return True
358
356
359 def _check_return(self, r, obj):
357 def _check_return(self, r, obj):
360 """Check that a return value is appropriate
358 """Check that a return value is appropriate
361
359
362 Return the value if so, None otherwise, warning if invalid.
360 Return the value if so, None otherwise, warning if invalid.
363 """
361 """
364 if r is None or isinstance(r, self._return_type) or \
362 if r is None or isinstance(r, self._return_type) or \
365 (isinstance(r, tuple) and r and isinstance(r[0], self._return_type)):
363 (isinstance(r, tuple) and r and isinstance(r[0], self._return_type)):
366 return r
364 return r
367 else:
365 else:
368 warnings.warn(
366 warnings.warn(
369 "%s formatter returned invalid type %s (expected %s) for object: %s" % \
367 "%s formatter returned invalid type %s (expected %s) for object: %s" % \
370 (self.format_type, type(r), self._return_type, _safe_repr(obj)),
368 (self.format_type, type(r), self._return_type, _safe_repr(obj)),
371 FormatterWarning
369 FormatterWarning
372 )
370 )
373
371
374 def lookup(self, obj):
372 def lookup(self, obj):
375 """Look up the formatter for a given instance.
373 """Look up the formatter for a given instance.
376
374
377 Parameters
375 Parameters
378 ----------
376 ----------
379 obj : object instance
377 obj : object instance
380
378
381 Returns
379 Returns
382 -------
380 -------
383 f : callable
381 f : callable
384 The registered formatting callable for the type.
382 The registered formatting callable for the type.
385
383
386 Raises
384 Raises
387 ------
385 ------
388 KeyError if the type has not been registered.
386 KeyError if the type has not been registered.
389 """
387 """
390 # look for singleton first
388 # look for singleton first
391 obj_id = id(obj)
389 obj_id = id(obj)
392 if obj_id in self.singleton_printers:
390 if obj_id in self.singleton_printers:
393 return self.singleton_printers[obj_id]
391 return self.singleton_printers[obj_id]
394 # then lookup by type
392 # then lookup by type
395 return self.lookup_by_type(_get_type(obj))
393 return self.lookup_by_type(_get_type(obj))
396
394
397 def lookup_by_type(self, typ):
395 def lookup_by_type(self, typ):
398 """Look up the registered formatter for a type.
396 """Look up the registered formatter for a type.
399
397
400 Parameters
398 Parameters
401 ----------
399 ----------
402 typ : type or '__module__.__name__' string for a type
400 typ : type or '__module__.__name__' string for a type
403
401
404 Returns
402 Returns
405 -------
403 -------
406 f : callable
404 f : callable
407 The registered formatting callable for the type.
405 The registered formatting callable for the type.
408
406
409 Raises
407 Raises
410 ------
408 ------
411 KeyError if the type has not been registered.
409 KeyError if the type has not been registered.
412 """
410 """
413 if isinstance(typ, str):
411 if isinstance(typ, str):
414 typ_key = tuple(typ.rsplit('.',1))
412 typ_key = tuple(typ.rsplit('.',1))
415 if typ_key not in self.deferred_printers:
413 if typ_key not in self.deferred_printers:
416 # We may have it cached in the type map. We will have to
414 # We may have it cached in the type map. We will have to
417 # iterate over all of the types to check.
415 # iterate over all of the types to check.
418 for cls in self.type_printers:
416 for cls in self.type_printers:
419 if _mod_name_key(cls) == typ_key:
417 if _mod_name_key(cls) == typ_key:
420 return self.type_printers[cls]
418 return self.type_printers[cls]
421 else:
419 else:
422 return self.deferred_printers[typ_key]
420 return self.deferred_printers[typ_key]
423 else:
421 else:
424 for cls in pretty._get_mro(typ):
422 for cls in pretty._get_mro(typ):
425 if cls in self.type_printers or self._in_deferred_types(cls):
423 if cls in self.type_printers or self._in_deferred_types(cls):
426 return self.type_printers[cls]
424 return self.type_printers[cls]
427
425
428 # If we have reached here, the lookup failed.
426 # If we have reached here, the lookup failed.
429 raise KeyError("No registered printer for {0!r}".format(typ))
427 raise KeyError("No registered printer for {0!r}".format(typ))
430
428
431 def for_type(self, typ, func=None):
429 def for_type(self, typ, func=None):
432 """Add a format function for a given type.
430 """Add a format function for a given type.
433
431
434 Parameters
432 Parameters
435 ----------
433 ----------
436 typ : type or '__module__.__name__' string for a type
434 typ : type or '__module__.__name__' string for a type
437 The class of the object that will be formatted using `func`.
435 The class of the object that will be formatted using `func`.
438 func : callable
436 func : callable
439 A callable for computing the format data.
437 A callable for computing the format data.
440 `func` will be called with the object to be formatted,
438 `func` will be called with the object to be formatted,
441 and will return the raw data in this formatter's format.
439 and will return the raw data in this formatter's format.
442 Subclasses may use a different call signature for the
440 Subclasses may use a different call signature for the
443 `func` argument.
441 `func` argument.
444
442
445 If `func` is None or not specified, there will be no change,
443 If `func` is None or not specified, there will be no change,
446 only returning the current value.
444 only returning the current value.
447
445
448 Returns
446 Returns
449 -------
447 -------
450 oldfunc : callable
448 oldfunc : callable
451 The currently registered callable.
449 The currently registered callable.
452 If you are registering a new formatter,
450 If you are registering a new formatter,
453 this will be the previous value (to enable restoring later).
451 this will be the previous value (to enable restoring later).
454 """
452 """
455 # if string given, interpret as 'pkg.module.class_name'
453 # if string given, interpret as 'pkg.module.class_name'
456 if isinstance(typ, str):
454 if isinstance(typ, str):
457 type_module, type_name = typ.rsplit('.', 1)
455 type_module, type_name = typ.rsplit('.', 1)
458 return self.for_type_by_name(type_module, type_name, func)
456 return self.for_type_by_name(type_module, type_name, func)
459
457
460 try:
458 try:
461 oldfunc = self.lookup_by_type(typ)
459 oldfunc = self.lookup_by_type(typ)
462 except KeyError:
460 except KeyError:
463 oldfunc = None
461 oldfunc = None
464
462
465 if func is not None:
463 if func is not None:
466 self.type_printers[typ] = func
464 self.type_printers[typ] = func
467
465
468 return oldfunc
466 return oldfunc
469
467
470 def for_type_by_name(self, type_module, type_name, func=None):
468 def for_type_by_name(self, type_module, type_name, func=None):
471 """Add a format function for a type specified by the full dotted
469 """Add a format function for a type specified by the full dotted
472 module and name of the type, rather than the type of the object.
470 module and name of the type, rather than the type of the object.
473
471
474 Parameters
472 Parameters
475 ----------
473 ----------
476 type_module : str
474 type_module : str
477 The full dotted name of the module the type is defined in, like
475 The full dotted name of the module the type is defined in, like
478 ``numpy``.
476 ``numpy``.
479 type_name : str
477 type_name : str
480 The name of the type (the class name), like ``dtype``
478 The name of the type (the class name), like ``dtype``
481 func : callable
479 func : callable
482 A callable for computing the format data.
480 A callable for computing the format data.
483 `func` will be called with the object to be formatted,
481 `func` will be called with the object to be formatted,
484 and will return the raw data in this formatter's format.
482 and will return the raw data in this formatter's format.
485 Subclasses may use a different call signature for the
483 Subclasses may use a different call signature for the
486 `func` argument.
484 `func` argument.
487
485
488 If `func` is None or unspecified, there will be no change,
486 If `func` is None or unspecified, there will be no change,
489 only returning the current value.
487 only returning the current value.
490
488
491 Returns
489 Returns
492 -------
490 -------
493 oldfunc : callable
491 oldfunc : callable
494 The currently registered callable.
492 The currently registered callable.
495 If you are registering a new formatter,
493 If you are registering a new formatter,
496 this will be the previous value (to enable restoring later).
494 this will be the previous value (to enable restoring later).
497 """
495 """
498 key = (type_module, type_name)
496 key = (type_module, type_name)
499
497
500 try:
498 try:
501 oldfunc = self.lookup_by_type("%s.%s" % key)
499 oldfunc = self.lookup_by_type("%s.%s" % key)
502 except KeyError:
500 except KeyError:
503 oldfunc = None
501 oldfunc = None
504
502
505 if func is not None:
503 if func is not None:
506 self.deferred_printers[key] = func
504 self.deferred_printers[key] = func
507 return oldfunc
505 return oldfunc
508
506
509 def pop(self, typ, default=_raise_key_error):
507 def pop(self, typ, default=_raise_key_error):
510 """Pop a formatter for the given type.
508 """Pop a formatter for the given type.
511
509
512 Parameters
510 Parameters
513 ----------
511 ----------
514 typ : type or '__module__.__name__' string for a type
512 typ : type or '__module__.__name__' string for a type
515 default : object
513 default : object
516 value to be returned if no formatter is registered for typ.
514 value to be returned if no formatter is registered for typ.
517
515
518 Returns
516 Returns
519 -------
517 -------
520 obj : object
518 obj : object
521 The last registered object for the type.
519 The last registered object for the type.
522
520
523 Raises
521 Raises
524 ------
522 ------
525 KeyError if the type is not registered and default is not specified.
523 KeyError if the type is not registered and default is not specified.
526 """
524 """
527
525
528 if isinstance(typ, str):
526 if isinstance(typ, str):
529 typ_key = tuple(typ.rsplit('.',1))
527 typ_key = tuple(typ.rsplit('.',1))
530 if typ_key not in self.deferred_printers:
528 if typ_key not in self.deferred_printers:
531 # We may have it cached in the type map. We will have to
529 # We may have it cached in the type map. We will have to
532 # iterate over all of the types to check.
530 # iterate over all of the types to check.
533 for cls in self.type_printers:
531 for cls in self.type_printers:
534 if _mod_name_key(cls) == typ_key:
532 if _mod_name_key(cls) == typ_key:
535 old = self.type_printers.pop(cls)
533 old = self.type_printers.pop(cls)
536 break
534 break
537 else:
535 else:
538 old = default
536 old = default
539 else:
537 else:
540 old = self.deferred_printers.pop(typ_key)
538 old = self.deferred_printers.pop(typ_key)
541 else:
539 else:
542 if typ in self.type_printers:
540 if typ in self.type_printers:
543 old = self.type_printers.pop(typ)
541 old = self.type_printers.pop(typ)
544 else:
542 else:
545 old = self.deferred_printers.pop(_mod_name_key(typ), default)
543 old = self.deferred_printers.pop(_mod_name_key(typ), default)
546 if old is _raise_key_error:
544 if old is _raise_key_error:
547 raise KeyError("No registered value for {0!r}".format(typ))
545 raise KeyError("No registered value for {0!r}".format(typ))
548 return old
546 return old
549
547
550 def _in_deferred_types(self, cls):
548 def _in_deferred_types(self, cls):
551 """
549 """
552 Check if the given class is specified in the deferred type registry.
550 Check if the given class is specified in the deferred type registry.
553
551
554 Successful matches will be moved to the regular type registry for future use.
552 Successful matches will be moved to the regular type registry for future use.
555 """
553 """
556 mod = getattr(cls, '__module__', None)
554 mod = getattr(cls, '__module__', None)
557 name = getattr(cls, '__name__', None)
555 name = getattr(cls, '__name__', None)
558 key = (mod, name)
556 key = (mod, name)
559 if key in self.deferred_printers:
557 if key in self.deferred_printers:
560 # Move the printer over to the regular registry.
558 # Move the printer over to the regular registry.
561 printer = self.deferred_printers.pop(key)
559 printer = self.deferred_printers.pop(key)
562 self.type_printers[cls] = printer
560 self.type_printers[cls] = printer
563 return True
561 return True
564 return False
562 return False
565
563
566
564
567 class PlainTextFormatter(BaseFormatter):
565 class PlainTextFormatter(BaseFormatter):
568 """The default pretty-printer.
566 """The default pretty-printer.
569
567
570 This uses :mod:`IPython.lib.pretty` to compute the format data of
568 This uses :mod:`IPython.lib.pretty` to compute the format data of
571 the object. If the object cannot be pretty printed, :func:`repr` is used.
569 the object. If the object cannot be pretty printed, :func:`repr` is used.
572 See the documentation of :mod:`IPython.lib.pretty` for details on
570 See the documentation of :mod:`IPython.lib.pretty` for details on
573 how to write pretty printers. Here is a simple example::
571 how to write pretty printers. Here is a simple example::
574
572
575 def dtype_pprinter(obj, p, cycle):
573 def dtype_pprinter(obj, p, cycle):
576 if cycle:
574 if cycle:
577 return p.text('dtype(...)')
575 return p.text('dtype(...)')
578 if hasattr(obj, 'fields'):
576 if hasattr(obj, 'fields'):
579 if obj.fields is None:
577 if obj.fields is None:
580 p.text(repr(obj))
578 p.text(repr(obj))
581 else:
579 else:
582 p.begin_group(7, 'dtype([')
580 p.begin_group(7, 'dtype([')
583 for i, field in enumerate(obj.descr):
581 for i, field in enumerate(obj.descr):
584 if i > 0:
582 if i > 0:
585 p.text(',')
583 p.text(',')
586 p.breakable()
584 p.breakable()
587 p.pretty(field)
585 p.pretty(field)
588 p.end_group(7, '])')
586 p.end_group(7, '])')
589 """
587 """
590
588
591 # The format type of data returned.
589 # The format type of data returned.
592 format_type = Unicode('text/plain')
590 format_type = Unicode('text/plain')
593
591
594 # This subclass ignores this attribute as it always need to return
592 # This subclass ignores this attribute as it always need to return
595 # something.
593 # something.
596 enabled = Bool(True).tag(config=False)
594 enabled = Bool(True).tag(config=False)
597
595
598 max_seq_length = Integer(pretty.MAX_SEQ_LENGTH,
596 max_seq_length = Integer(pretty.MAX_SEQ_LENGTH,
599 help="""Truncate large collections (lists, dicts, tuples, sets) to this size.
597 help="""Truncate large collections (lists, dicts, tuples, sets) to this size.
600
598
601 Set to 0 to disable truncation.
599 Set to 0 to disable truncation.
602 """
600 """
603 ).tag(config=True)
601 ).tag(config=True)
604
602
605 # Look for a _repr_pretty_ methods to use for pretty printing.
603 # Look for a _repr_pretty_ methods to use for pretty printing.
606 print_method = ObjectName('_repr_pretty_')
604 print_method = ObjectName('_repr_pretty_')
607
605
608 # Whether to pretty-print or not.
606 # Whether to pretty-print or not.
609 pprint = Bool(True).tag(config=True)
607 pprint = Bool(True).tag(config=True)
610
608
611 # Whether to be verbose or not.
609 # Whether to be verbose or not.
612 verbose = Bool(False).tag(config=True)
610 verbose = Bool(False).tag(config=True)
613
611
614 # The maximum width.
612 # The maximum width.
615 max_width = Integer(79).tag(config=True)
613 max_width = Integer(79).tag(config=True)
616
614
617 # The newline character.
615 # The newline character.
618 newline = Unicode('\n').tag(config=True)
616 newline = Unicode('\n').tag(config=True)
619
617
620 # format-string for pprinting floats
618 # format-string for pprinting floats
621 float_format = Unicode('%r')
619 float_format = Unicode('%r')
622 # setter for float precision, either int or direct format-string
620 # setter for float precision, either int or direct format-string
623 float_precision = CUnicode('').tag(config=True)
621 float_precision = CUnicode('').tag(config=True)
624
622
625 @observe('float_precision')
623 @observe('float_precision')
626 def _float_precision_changed(self, change):
624 def _float_precision_changed(self, change):
627 """float_precision changed, set float_format accordingly.
625 """float_precision changed, set float_format accordingly.
628
626
629 float_precision can be set by int or str.
627 float_precision can be set by int or str.
630 This will set float_format, after interpreting input.
628 This will set float_format, after interpreting input.
631 If numpy has been imported, numpy print precision will also be set.
629 If numpy has been imported, numpy print precision will also be set.
632
630
633 integer `n` sets format to '%.nf', otherwise, format set directly.
631 integer `n` sets format to '%.nf', otherwise, format set directly.
634
632
635 An empty string returns to defaults (repr for float, 8 for numpy).
633 An empty string returns to defaults (repr for float, 8 for numpy).
636
634
637 This parameter can be set via the '%precision' magic.
635 This parameter can be set via the '%precision' magic.
638 """
636 """
639 new = change['new']
637 new = change['new']
640 if '%' in new:
638 if '%' in new:
641 # got explicit format string
639 # got explicit format string
642 fmt = new
640 fmt = new
643 try:
641 try:
644 fmt%3.14159
642 fmt%3.14159
645 except Exception as e:
643 except Exception as e:
646 raise ValueError("Precision must be int or format string, not %r"%new) from e
644 raise ValueError("Precision must be int or format string, not %r"%new) from e
647 elif new:
645 elif new:
648 # otherwise, should be an int
646 # otherwise, should be an int
649 try:
647 try:
650 i = int(new)
648 i = int(new)
651 assert i >= 0
649 assert i >= 0
652 except ValueError as e:
650 except ValueError as e:
653 raise ValueError("Precision must be int or format string, not %r"%new) from e
651 raise ValueError("Precision must be int or format string, not %r"%new) from e
654 except AssertionError as e:
652 except AssertionError as e:
655 raise ValueError("int precision must be non-negative, not %r"%i) from e
653 raise ValueError("int precision must be non-negative, not %r"%i) from e
656
654
657 fmt = '%%.%if'%i
655 fmt = '%%.%if'%i
658 if 'numpy' in sys.modules:
656 if 'numpy' in sys.modules:
659 # set numpy precision if it has been imported
657 # set numpy precision if it has been imported
660 import numpy
658 import numpy
661 numpy.set_printoptions(precision=i)
659 numpy.set_printoptions(precision=i)
662 else:
660 else:
663 # default back to repr
661 # default back to repr
664 fmt = '%r'
662 fmt = '%r'
665 if 'numpy' in sys.modules:
663 if 'numpy' in sys.modules:
666 import numpy
664 import numpy
667 # numpy default is 8
665 # numpy default is 8
668 numpy.set_printoptions(precision=8)
666 numpy.set_printoptions(precision=8)
669 self.float_format = fmt
667 self.float_format = fmt
670
668
671 # Use the default pretty printers from IPython.lib.pretty.
669 # Use the default pretty printers from IPython.lib.pretty.
672 @default('singleton_printers')
670 @default('singleton_printers')
673 def _singleton_printers_default(self):
671 def _singleton_printers_default(self):
674 return pretty._singleton_pprinters.copy()
672 return pretty._singleton_pprinters.copy()
675
673
676 @default('type_printers')
674 @default('type_printers')
677 def _type_printers_default(self):
675 def _type_printers_default(self):
678 d = pretty._type_pprinters.copy()
676 d = pretty._type_pprinters.copy()
679 d[float] = lambda obj,p,cycle: p.text(self.float_format%obj)
677 d[float] = lambda obj,p,cycle: p.text(self.float_format%obj)
680 # if NumPy is used, set precision for its float64 type
678 # if NumPy is used, set precision for its float64 type
681 if "numpy" in sys.modules:
679 if "numpy" in sys.modules:
682 import numpy
680 import numpy
683
681
684 d[numpy.float64] = lambda obj, p, cycle: p.text(self.float_format % obj)
682 d[numpy.float64] = lambda obj, p, cycle: p.text(self.float_format % obj)
685 return d
683 return d
686
684
687 @default('deferred_printers')
685 @default('deferred_printers')
688 def _deferred_printers_default(self):
686 def _deferred_printers_default(self):
689 return pretty._deferred_type_pprinters.copy()
687 return pretty._deferred_type_pprinters.copy()
690
688
691 #### FormatterABC interface ####
689 #### FormatterABC interface ####
692
690
693 @catch_format_error
691 @catch_format_error
694 def __call__(self, obj):
692 def __call__(self, obj):
695 """Compute the pretty representation of the object."""
693 """Compute the pretty representation of the object."""
696 if not self.pprint:
694 if not self.pprint:
697 return repr(obj)
695 return repr(obj)
698 else:
696 else:
699 stream = StringIO()
697 stream = StringIO()
700 printer = pretty.RepresentationPrinter(stream, self.verbose,
698 printer = pretty.RepresentationPrinter(stream, self.verbose,
701 self.max_width, self.newline,
699 self.max_width, self.newline,
702 max_seq_length=self.max_seq_length,
700 max_seq_length=self.max_seq_length,
703 singleton_pprinters=self.singleton_printers,
701 singleton_pprinters=self.singleton_printers,
704 type_pprinters=self.type_printers,
702 type_pprinters=self.type_printers,
705 deferred_pprinters=self.deferred_printers)
703 deferred_pprinters=self.deferred_printers)
706 printer.pretty(obj)
704 printer.pretty(obj)
707 printer.flush()
705 printer.flush()
708 return stream.getvalue()
706 return stream.getvalue()
709
707
710
708
711 class HTMLFormatter(BaseFormatter):
709 class HTMLFormatter(BaseFormatter):
712 """An HTML formatter.
710 """An HTML formatter.
713
711
714 To define the callables that compute the HTML representation of your
712 To define the callables that compute the HTML representation of your
715 objects, define a :meth:`_repr_html_` method or use the :meth:`for_type`
713 objects, define a :meth:`_repr_html_` method or use the :meth:`for_type`
716 or :meth:`for_type_by_name` methods to register functions that handle
714 or :meth:`for_type_by_name` methods to register functions that handle
717 this.
715 this.
718
716
719 The return value of this formatter should be a valid HTML snippet that
717 The return value of this formatter should be a valid HTML snippet that
720 could be injected into an existing DOM. It should *not* include the
718 could be injected into an existing DOM. It should *not* include the
721 ```<html>`` or ```<body>`` tags.
719 ```<html>`` or ```<body>`` tags.
722 """
720 """
723 format_type = Unicode('text/html')
721 format_type = Unicode('text/html')
724
722
725 print_method = ObjectName('_repr_html_')
723 print_method = ObjectName('_repr_html_')
726
724
727
725
728 class MarkdownFormatter(BaseFormatter):
726 class MarkdownFormatter(BaseFormatter):
729 """A Markdown formatter.
727 """A Markdown formatter.
730
728
731 To define the callables that compute the Markdown representation of your
729 To define the callables that compute the Markdown representation of your
732 objects, define a :meth:`_repr_markdown_` method or use the :meth:`for_type`
730 objects, define a :meth:`_repr_markdown_` method or use the :meth:`for_type`
733 or :meth:`for_type_by_name` methods to register functions that handle
731 or :meth:`for_type_by_name` methods to register functions that handle
734 this.
732 this.
735
733
736 The return value of this formatter should be a valid Markdown.
734 The return value of this formatter should be a valid Markdown.
737 """
735 """
738 format_type = Unicode('text/markdown')
736 format_type = Unicode('text/markdown')
739
737
740 print_method = ObjectName('_repr_markdown_')
738 print_method = ObjectName('_repr_markdown_')
741
739
742 class SVGFormatter(BaseFormatter):
740 class SVGFormatter(BaseFormatter):
743 """An SVG formatter.
741 """An SVG formatter.
744
742
745 To define the callables that compute the SVG representation of your
743 To define the callables that compute the SVG representation of your
746 objects, define a :meth:`_repr_svg_` method or use the :meth:`for_type`
744 objects, define a :meth:`_repr_svg_` method or use the :meth:`for_type`
747 or :meth:`for_type_by_name` methods to register functions that handle
745 or :meth:`for_type_by_name` methods to register functions that handle
748 this.
746 this.
749
747
750 The return value of this formatter should be valid SVG enclosed in
748 The return value of this formatter should be valid SVG enclosed in
751 ```<svg>``` tags, that could be injected into an existing DOM. It should
749 ```<svg>``` tags, that could be injected into an existing DOM. It should
752 *not* include the ```<html>`` or ```<body>`` tags.
750 *not* include the ```<html>`` or ```<body>`` tags.
753 """
751 """
754 format_type = Unicode('image/svg+xml')
752 format_type = Unicode('image/svg+xml')
755
753
756 print_method = ObjectName('_repr_svg_')
754 print_method = ObjectName('_repr_svg_')
757
755
758
756
759 class PNGFormatter(BaseFormatter):
757 class PNGFormatter(BaseFormatter):
760 """A PNG formatter.
758 """A PNG formatter.
761
759
762 To define the callables that compute the PNG representation of your
760 To define the callables that compute the PNG representation of your
763 objects, define a :meth:`_repr_png_` method or use the :meth:`for_type`
761 objects, define a :meth:`_repr_png_` method or use the :meth:`for_type`
764 or :meth:`for_type_by_name` methods to register functions that handle
762 or :meth:`for_type_by_name` methods to register functions that handle
765 this.
763 this.
766
764
767 The return value of this formatter should be raw PNG data, *not*
765 The return value of this formatter should be raw PNG data, *not*
768 base64 encoded.
766 base64 encoded.
769 """
767 """
770 format_type = Unicode('image/png')
768 format_type = Unicode('image/png')
771
769
772 print_method = ObjectName('_repr_png_')
770 print_method = ObjectName('_repr_png_')
773
771
774 _return_type = (bytes, str)
772 _return_type = (bytes, str)
775
773
776
774
777 class JPEGFormatter(BaseFormatter):
775 class JPEGFormatter(BaseFormatter):
778 """A JPEG formatter.
776 """A JPEG formatter.
779
777
780 To define the callables that compute the JPEG representation of your
778 To define the callables that compute the JPEG representation of your
781 objects, define a :meth:`_repr_jpeg_` method or use the :meth:`for_type`
779 objects, define a :meth:`_repr_jpeg_` method or use the :meth:`for_type`
782 or :meth:`for_type_by_name` methods to register functions that handle
780 or :meth:`for_type_by_name` methods to register functions that handle
783 this.
781 this.
784
782
785 The return value of this formatter should be raw JPEG data, *not*
783 The return value of this formatter should be raw JPEG data, *not*
786 base64 encoded.
784 base64 encoded.
787 """
785 """
788 format_type = Unicode('image/jpeg')
786 format_type = Unicode('image/jpeg')
789
787
790 print_method = ObjectName('_repr_jpeg_')
788 print_method = ObjectName('_repr_jpeg_')
791
789
792 _return_type = (bytes, str)
790 _return_type = (bytes, str)
793
791
794
792
795 class LatexFormatter(BaseFormatter):
793 class LatexFormatter(BaseFormatter):
796 """A LaTeX formatter.
794 """A LaTeX formatter.
797
795
798 To define the callables that compute the LaTeX representation of your
796 To define the callables that compute the LaTeX representation of your
799 objects, define a :meth:`_repr_latex_` method or use the :meth:`for_type`
797 objects, define a :meth:`_repr_latex_` method or use the :meth:`for_type`
800 or :meth:`for_type_by_name` methods to register functions that handle
798 or :meth:`for_type_by_name` methods to register functions that handle
801 this.
799 this.
802
800
803 The return value of this formatter should be a valid LaTeX equation,
801 The return value of this formatter should be a valid LaTeX equation,
804 enclosed in either ```$```, ```$$``` or another LaTeX equation
802 enclosed in either ```$```, ```$$``` or another LaTeX equation
805 environment.
803 environment.
806 """
804 """
807 format_type = Unicode('text/latex')
805 format_type = Unicode('text/latex')
808
806
809 print_method = ObjectName('_repr_latex_')
807 print_method = ObjectName('_repr_latex_')
810
808
811
809
812 class JSONFormatter(BaseFormatter):
810 class JSONFormatter(BaseFormatter):
813 """A JSON string formatter.
811 """A JSON string formatter.
814
812
815 To define the callables that compute the JSONable representation of
813 To define the callables that compute the JSONable representation of
816 your objects, define a :meth:`_repr_json_` method or use the :meth:`for_type`
814 your objects, define a :meth:`_repr_json_` method or use the :meth:`for_type`
817 or :meth:`for_type_by_name` methods to register functions that handle
815 or :meth:`for_type_by_name` methods to register functions that handle
818 this.
816 this.
819
817
820 The return value of this formatter should be a JSONable list or dict.
818 The return value of this formatter should be a JSONable list or dict.
821 JSON scalars (None, number, string) are not allowed, only dict or list containers.
819 JSON scalars (None, number, string) are not allowed, only dict or list containers.
822 """
820 """
823 format_type = Unicode('application/json')
821 format_type = Unicode('application/json')
824 _return_type = (list, dict)
822 _return_type = (list, dict)
825
823
826 print_method = ObjectName('_repr_json_')
824 print_method = ObjectName('_repr_json_')
827
825
828 def _check_return(self, r, obj):
826 def _check_return(self, r, obj):
829 """Check that a return value is appropriate
827 """Check that a return value is appropriate
830
828
831 Return the value if so, None otherwise, warning if invalid.
829 Return the value if so, None otherwise, warning if invalid.
832 """
830 """
833 if r is None:
831 if r is None:
834 return
832 return
835 md = None
833 md = None
836 if isinstance(r, tuple):
834 if isinstance(r, tuple):
837 # unpack data, metadata tuple for type checking on first element
835 # unpack data, metadata tuple for type checking on first element
838 r, md = r
836 r, md = r
839
837
840 # handle deprecated JSON-as-string form from IPython < 3
838 # handle deprecated JSON-as-string form from IPython < 3
841 if isinstance(r, str):
839 if isinstance(r, str):
842 warnings.warn("JSON expects JSONable list/dict containers, not JSON strings",
840 warnings.warn("JSON expects JSONable list/dict containers, not JSON strings",
843 FormatterWarning)
841 FormatterWarning)
844 r = json.loads(r)
842 r = json.loads(r)
845
843
846 if md is not None:
844 if md is not None:
847 # put the tuple back together
845 # put the tuple back together
848 r = (r, md)
846 r = (r, md)
849 return super(JSONFormatter, self)._check_return(r, obj)
847 return super(JSONFormatter, self)._check_return(r, obj)
850
848
851
849
852 class JavascriptFormatter(BaseFormatter):
850 class JavascriptFormatter(BaseFormatter):
853 """A Javascript formatter.
851 """A Javascript formatter.
854
852
855 To define the callables that compute the Javascript representation of
853 To define the callables that compute the Javascript representation of
856 your objects, define a :meth:`_repr_javascript_` method or use the
854 your objects, define a :meth:`_repr_javascript_` method or use the
857 :meth:`for_type` or :meth:`for_type_by_name` methods to register functions
855 :meth:`for_type` or :meth:`for_type_by_name` methods to register functions
858 that handle this.
856 that handle this.
859
857
860 The return value of this formatter should be valid Javascript code and
858 The return value of this formatter should be valid Javascript code and
861 should *not* be enclosed in ```<script>``` tags.
859 should *not* be enclosed in ```<script>``` tags.
862 """
860 """
863 format_type = Unicode('application/javascript')
861 format_type = Unicode('application/javascript')
864
862
865 print_method = ObjectName('_repr_javascript_')
863 print_method = ObjectName('_repr_javascript_')
866
864
867
865
868 class PDFFormatter(BaseFormatter):
866 class PDFFormatter(BaseFormatter):
869 """A PDF formatter.
867 """A PDF formatter.
870
868
871 To define the callables that compute the PDF representation of your
869 To define the callables that compute the PDF representation of your
872 objects, define a :meth:`_repr_pdf_` method or use the :meth:`for_type`
870 objects, define a :meth:`_repr_pdf_` method or use the :meth:`for_type`
873 or :meth:`for_type_by_name` methods to register functions that handle
871 or :meth:`for_type_by_name` methods to register functions that handle
874 this.
872 this.
875
873
876 The return value of this formatter should be raw PDF data, *not*
874 The return value of this formatter should be raw PDF data, *not*
877 base64 encoded.
875 base64 encoded.
878 """
876 """
879 format_type = Unicode('application/pdf')
877 format_type = Unicode('application/pdf')
880
878
881 print_method = ObjectName('_repr_pdf_')
879 print_method = ObjectName('_repr_pdf_')
882
880
883 _return_type = (bytes, str)
881 _return_type = (bytes, str)
884
882
885 class IPythonDisplayFormatter(BaseFormatter):
883 class IPythonDisplayFormatter(BaseFormatter):
886 """An escape-hatch Formatter for objects that know how to display themselves.
884 """An escape-hatch Formatter for objects that know how to display themselves.
887
885
888 To define the callables that compute the representation of your
886 To define the callables that compute the representation of your
889 objects, define a :meth:`_ipython_display_` method or use the :meth:`for_type`
887 objects, define a :meth:`_ipython_display_` method or use the :meth:`for_type`
890 or :meth:`for_type_by_name` methods to register functions that handle
888 or :meth:`for_type_by_name` methods to register functions that handle
891 this. Unlike mime-type displays, this method should not return anything,
889 this. Unlike mime-type displays, this method should not return anything,
892 instead calling any appropriate display methods itself.
890 instead calling any appropriate display methods itself.
893
891
894 This display formatter has highest priority.
892 This display formatter has highest priority.
895 If it fires, no other display formatter will be called.
893 If it fires, no other display formatter will be called.
896
894
897 Prior to IPython 6.1, `_ipython_display_` was the only way to display custom mime-types
895 Prior to IPython 6.1, `_ipython_display_` was the only way to display custom mime-types
898 without registering a new Formatter.
896 without registering a new Formatter.
899
897
900 IPython 6.1 introduces `_repr_mimebundle_` for displaying custom mime-types,
898 IPython 6.1 introduces `_repr_mimebundle_` for displaying custom mime-types,
901 so `_ipython_display_` should only be used for objects that require unusual
899 so `_ipython_display_` should only be used for objects that require unusual
902 display patterns, such as multiple display calls.
900 display patterns, such as multiple display calls.
903 """
901 """
904 print_method = ObjectName('_ipython_display_')
902 print_method = ObjectName('_ipython_display_')
905 _return_type = (type(None), bool)
903 _return_type = (type(None), bool)
906
904
907 @catch_format_error
905 @catch_format_error
908 def __call__(self, obj):
906 def __call__(self, obj):
909 """Compute the format for an object."""
907 """Compute the format for an object."""
910 if self.enabled:
908 if self.enabled:
911 # lookup registered printer
909 # lookup registered printer
912 try:
910 try:
913 printer = self.lookup(obj)
911 printer = self.lookup(obj)
914 except KeyError:
912 except KeyError:
915 pass
913 pass
916 else:
914 else:
917 printer(obj)
915 printer(obj)
918 return True
916 return True
919 # Finally look for special method names
917 # Finally look for special method names
920 method = get_real_method(obj, self.print_method)
918 method = get_real_method(obj, self.print_method)
921 if method is not None:
919 if method is not None:
922 method()
920 method()
923 return True
921 return True
924
922
925
923
926 class MimeBundleFormatter(BaseFormatter):
924 class MimeBundleFormatter(BaseFormatter):
927 """A Formatter for arbitrary mime-types.
925 """A Formatter for arbitrary mime-types.
928
926
929 Unlike other `_repr_<mimetype>_` methods,
927 Unlike other `_repr_<mimetype>_` methods,
930 `_repr_mimebundle_` should return mime-bundle data,
928 `_repr_mimebundle_` should return mime-bundle data,
931 either the mime-keyed `data` dictionary or the tuple `(data, metadata)`.
929 either the mime-keyed `data` dictionary or the tuple `(data, metadata)`.
932 Any mime-type is valid.
930 Any mime-type is valid.
933
931
934 To define the callables that compute the mime-bundle representation of your
932 To define the callables that compute the mime-bundle representation of your
935 objects, define a :meth:`_repr_mimebundle_` method or use the :meth:`for_type`
933 objects, define a :meth:`_repr_mimebundle_` method or use the :meth:`for_type`
936 or :meth:`for_type_by_name` methods to register functions that handle
934 or :meth:`for_type_by_name` methods to register functions that handle
937 this.
935 this.
938
936
939 .. versionadded:: 6.1
937 .. versionadded:: 6.1
940 """
938 """
941 print_method = ObjectName('_repr_mimebundle_')
939 print_method = ObjectName('_repr_mimebundle_')
942 _return_type = dict
940 _return_type = dict
943
941
944 def _check_return(self, r, obj):
942 def _check_return(self, r, obj):
945 r = super(MimeBundleFormatter, self)._check_return(r, obj)
943 r = super(MimeBundleFormatter, self)._check_return(r, obj)
946 # always return (data, metadata):
944 # always return (data, metadata):
947 if r is None:
945 if r is None:
948 return {}, {}
946 return {}, {}
949 if not isinstance(r, tuple):
947 if not isinstance(r, tuple):
950 return r, {}
948 return r, {}
951 return r
949 return r
952
950
953 @catch_format_error
951 @catch_format_error
954 def __call__(self, obj, include=None, exclude=None):
952 def __call__(self, obj, include=None, exclude=None):
955 """Compute the format for an object.
953 """Compute the format for an object.
956
954
957 Identical to parent's method but we pass extra parameters to the method.
955 Identical to parent's method but we pass extra parameters to the method.
958
956
959 Unlike other _repr_*_ `_repr_mimebundle_` should allow extra kwargs, in
957 Unlike other _repr_*_ `_repr_mimebundle_` should allow extra kwargs, in
960 particular `include` and `exclude`.
958 particular `include` and `exclude`.
961 """
959 """
962 if self.enabled:
960 if self.enabled:
963 # lookup registered printer
961 # lookup registered printer
964 try:
962 try:
965 printer = self.lookup(obj)
963 printer = self.lookup(obj)
966 except KeyError:
964 except KeyError:
967 pass
965 pass
968 else:
966 else:
969 return printer(obj)
967 return printer(obj)
970 # Finally look for special method names
968 # Finally look for special method names
971 method = get_real_method(obj, self.print_method)
969 method = get_real_method(obj, self.print_method)
972
970
973 if method is not None:
971 if method is not None:
974 return method(include=include, exclude=exclude)
972 return method(include=include, exclude=exclude)
975 return None
973 return None
976 else:
974 else:
977 return None
975 return None
978
976
979
977
980 FormatterABC.register(BaseFormatter)
978 FormatterABC.register(BaseFormatter)
981 FormatterABC.register(PlainTextFormatter)
979 FormatterABC.register(PlainTextFormatter)
982 FormatterABC.register(HTMLFormatter)
980 FormatterABC.register(HTMLFormatter)
983 FormatterABC.register(MarkdownFormatter)
981 FormatterABC.register(MarkdownFormatter)
984 FormatterABC.register(SVGFormatter)
982 FormatterABC.register(SVGFormatter)
985 FormatterABC.register(PNGFormatter)
983 FormatterABC.register(PNGFormatter)
986 FormatterABC.register(PDFFormatter)
984 FormatterABC.register(PDFFormatter)
987 FormatterABC.register(JPEGFormatter)
985 FormatterABC.register(JPEGFormatter)
988 FormatterABC.register(LatexFormatter)
986 FormatterABC.register(LatexFormatter)
989 FormatterABC.register(JSONFormatter)
987 FormatterABC.register(JSONFormatter)
990 FormatterABC.register(JavascriptFormatter)
988 FormatterABC.register(JavascriptFormatter)
991 FormatterABC.register(IPythonDisplayFormatter)
989 FormatterABC.register(IPythonDisplayFormatter)
992 FormatterABC.register(MimeBundleFormatter)
990 FormatterABC.register(MimeBundleFormatter)
993
991
994
992
995 def format_display_data(obj, include=None, exclude=None):
993 def format_display_data(obj, include=None, exclude=None):
996 """Return a format data dict for an object.
994 """Return a format data dict for an object.
997
995
998 By default all format types will be computed.
996 By default all format types will be computed.
999
997
1000 Parameters
998 Parameters
1001 ----------
999 ----------
1002 obj : object
1000 obj : object
1003 The Python object whose format data will be computed.
1001 The Python object whose format data will be computed.
1004
1002
1005 Returns
1003 Returns
1006 -------
1004 -------
1007 format_dict : dict
1005 format_dict : dict
1008 A dictionary of key/value pairs, one or each format that was
1006 A dictionary of key/value pairs, one or each format that was
1009 generated for the object. The keys are the format types, which
1007 generated for the object. The keys are the format types, which
1010 will usually be MIME type strings and the values and JSON'able
1008 will usually be MIME type strings and the values and JSON'able
1011 data structure containing the raw data for the representation in
1009 data structure containing the raw data for the representation in
1012 that format.
1010 that format.
1013 include : list or tuple, optional
1011 include : list or tuple, optional
1014 A list of format type strings (MIME types) to include in the
1012 A list of format type strings (MIME types) to include in the
1015 format data dict. If this is set *only* the format types included
1013 format data dict. If this is set *only* the format types included
1016 in this list will be computed.
1014 in this list will be computed.
1017 exclude : list or tuple, optional
1015 exclude : list or tuple, optional
1018 A list of format type string (MIME types) to exclude in the format
1016 A list of format type string (MIME types) to exclude in the format
1019 data dict. If this is set all format types will be computed,
1017 data dict. If this is set all format types will be computed,
1020 except for those included in this argument.
1018 except for those included in this argument.
1021 """
1019 """
1022 from .interactiveshell import InteractiveShell
1020 from .interactiveshell import InteractiveShell
1023
1021
1024 return InteractiveShell.instance().display_formatter.format(
1022 return InteractiveShell.instance().display_formatter.format(
1025 obj,
1023 obj,
1026 include,
1024 include,
1027 exclude
1025 exclude
1028 )
1026 )
@@ -1,2 +1,7 b''
1 [metadata]
1 [metadata]
2 license_file = LICENSE
2 license_file = LICENSE
3
4 [velin]
5 ignore_patterns =
6 IPython/core/tests,
7 IPython/testing
General Comments 0
You need to be logged in to leave comments. Login now