##// END OF EJS Templates
require print_method to be a bound method...
MinRK -
Show More
@@ -1,846 +1,848 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 Authors:
9 Authors:
10
10
11 * Robert Kern
11 * Robert Kern
12 * Brian Granger
12 * Brian Granger
13 """
13 """
14 #-----------------------------------------------------------------------------
14 #-----------------------------------------------------------------------------
15 # Copyright (C) 2010-2011, IPython Development Team.
15 # Copyright (C) 2010-2011, IPython Development Team.
16 #
16 #
17 # Distributed under the terms of the Modified BSD License.
17 # Distributed under the terms of the Modified BSD License.
18 #
18 #
19 # The full license is in the file COPYING.txt, distributed with this software.
19 # The full license is in the file COPYING.txt, distributed with this software.
20 #-----------------------------------------------------------------------------
20 #-----------------------------------------------------------------------------
21
21
22 #-----------------------------------------------------------------------------
22 #-----------------------------------------------------------------------------
23 # Imports
23 # Imports
24 #-----------------------------------------------------------------------------
24 #-----------------------------------------------------------------------------
25
25
26 # Stdlib imports
26 # Stdlib imports
27 import abc
27 import abc
28 import sys
28 import sys
29 import types
29 import warnings
30 import warnings
30
31
31 from IPython.external.decorator import decorator
32 from IPython.external.decorator import decorator
32
33
33 # Our own imports
34 # Our own imports
34 from IPython.config.configurable import Configurable
35 from IPython.config.configurable import Configurable
35 from IPython.lib import pretty
36 from IPython.lib import pretty
36 from IPython.utils import io
37 from IPython.utils import io
37 from IPython.utils.traitlets import (
38 from IPython.utils.traitlets import (
38 Bool, Dict, Integer, Unicode, CUnicode, ObjectName, List,
39 Bool, Dict, Integer, Unicode, CUnicode, ObjectName, List,
39 )
40 )
40 from IPython.utils.warn import warn
41 from IPython.utils.warn import warn
41 from IPython.utils.py3compat import (
42 from IPython.utils.py3compat import (
42 unicode_to_str, with_metaclass, PY3, string_types, unicode_type,
43 unicode_to_str, with_metaclass, PY3, string_types, unicode_type,
43 )
44 )
44
45
45 if PY3:
46 if PY3:
46 from io import StringIO
47 from io import StringIO
47 else:
48 else:
48 from StringIO import StringIO
49 from StringIO import StringIO
49
50
50
51
51 #-----------------------------------------------------------------------------
52 #-----------------------------------------------------------------------------
52 # The main DisplayFormatter class
53 # The main DisplayFormatter class
53 #-----------------------------------------------------------------------------
54 #-----------------------------------------------------------------------------
54
55
55 class DisplayFormatter(Configurable):
56 class DisplayFormatter(Configurable):
56
57
57 # When set to true only the default plain text formatter will be used.
58 # When set to true only the default plain text formatter will be used.
58 plain_text_only = Bool(False, config=True)
59 plain_text_only = Bool(False, config=True)
59 def _plain_text_only_changed(self, name, old, new):
60 def _plain_text_only_changed(self, name, old, new):
60 warnings.warn("""DisplayFormatter.plain_text_only is deprecated.
61 warnings.warn("""DisplayFormatter.plain_text_only is deprecated.
61
62
62 Use DisplayFormatter.active_types = ['text/plain']
63 Use DisplayFormatter.active_types = ['text/plain']
63 for the same effect.
64 for the same effect.
64 """, DeprecationWarning)
65 """, DeprecationWarning)
65 if new:
66 if new:
66 self.active_types = ['text/plain']
67 self.active_types = ['text/plain']
67 else:
68 else:
68 self.active_types = self.format_types
69 self.active_types = self.format_types
69
70
70 active_types = List(Unicode, config=True,
71 active_types = List(Unicode, config=True,
71 help="""List of currently active mime-types to display.
72 help="""List of currently active mime-types to display.
72 You can use this to set a white-list for formats to display.
73 You can use this to set a white-list for formats to display.
73
74
74 Most users will not need to change this value.
75 Most users will not need to change this value.
75 """)
76 """)
76 def _active_types_default(self):
77 def _active_types_default(self):
77 return self.format_types
78 return self.format_types
78
79
79 def _active_types_changed(self, name, old, new):
80 def _active_types_changed(self, name, old, new):
80 for key, formatter in self.formatters.items():
81 for key, formatter in self.formatters.items():
81 if key in new:
82 if key in new:
82 formatter.enabled = True
83 formatter.enabled = True
83 else:
84 else:
84 formatter.enabled = False
85 formatter.enabled = False
85
86
86 # A dict of formatter whose keys are format types (MIME types) and whose
87 # A dict of formatter whose keys are format types (MIME types) and whose
87 # values are subclasses of BaseFormatter.
88 # values are subclasses of BaseFormatter.
88 formatters = Dict()
89 formatters = Dict()
89 def _formatters_default(self):
90 def _formatters_default(self):
90 """Activate the default formatters."""
91 """Activate the default formatters."""
91 formatter_classes = [
92 formatter_classes = [
92 PlainTextFormatter,
93 PlainTextFormatter,
93 HTMLFormatter,
94 HTMLFormatter,
94 SVGFormatter,
95 SVGFormatter,
95 PNGFormatter,
96 PNGFormatter,
96 PDFFormatter,
97 PDFFormatter,
97 JPEGFormatter,
98 JPEGFormatter,
98 LatexFormatter,
99 LatexFormatter,
99 JSONFormatter,
100 JSONFormatter,
100 JavascriptFormatter
101 JavascriptFormatter
101 ]
102 ]
102 d = {}
103 d = {}
103 for cls in formatter_classes:
104 for cls in formatter_classes:
104 f = cls(parent=self)
105 f = cls(parent=self)
105 d[f.format_type] = f
106 d[f.format_type] = f
106 return d
107 return d
107
108
108 def format(self, obj, include=None, exclude=None):
109 def format(self, obj, include=None, exclude=None):
109 """Return a format data dict for an object.
110 """Return a format data dict for an object.
110
111
111 By default all format types will be computed.
112 By default all format types will be computed.
112
113
113 The following MIME types are currently implemented:
114 The following MIME types are currently implemented:
114
115
115 * text/plain
116 * text/plain
116 * text/html
117 * text/html
117 * text/latex
118 * text/latex
118 * application/json
119 * application/json
119 * application/javascript
120 * application/javascript
120 * application/pdf
121 * application/pdf
121 * image/png
122 * image/png
122 * image/jpeg
123 * image/jpeg
123 * image/svg+xml
124 * image/svg+xml
124
125
125 Parameters
126 Parameters
126 ----------
127 ----------
127 obj : object
128 obj : object
128 The Python object whose format data will be computed.
129 The Python object whose format data will be computed.
129 include : list or tuple, optional
130 include : list or tuple, optional
130 A list of format type strings (MIME types) to include in the
131 A list of format type strings (MIME types) to include in the
131 format data dict. If this is set *only* the format types included
132 format data dict. If this is set *only* the format types included
132 in this list will be computed.
133 in this list will be computed.
133 exclude : list or tuple, optional
134 exclude : list or tuple, optional
134 A list of format type string (MIME types) to exclude in the format
135 A list of format type string (MIME types) to exclude in the format
135 data dict. If this is set all format types will be computed,
136 data dict. If this is set all format types will be computed,
136 except for those included in this argument.
137 except for those included in this argument.
137
138
138 Returns
139 Returns
139 -------
140 -------
140 (format_dict, metadata_dict) : tuple of two dicts
141 (format_dict, metadata_dict) : tuple of two dicts
141
142
142 format_dict is a dictionary of key/value pairs, one of each format that was
143 format_dict is a dictionary of key/value pairs, one of each format that was
143 generated for the object. The keys are the format types, which
144 generated for the object. The keys are the format types, which
144 will usually be MIME type strings and the values and JSON'able
145 will usually be MIME type strings and the values and JSON'able
145 data structure containing the raw data for the representation in
146 data structure containing the raw data for the representation in
146 that format.
147 that format.
147
148
148 metadata_dict is a dictionary of metadata about each mime-type output.
149 metadata_dict is a dictionary of metadata about each mime-type output.
149 Its keys will be a strict subset of the keys in format_dict.
150 Its keys will be a strict subset of the keys in format_dict.
150 """
151 """
151 format_dict = {}
152 format_dict = {}
152 md_dict = {}
153 md_dict = {}
153
154
154 for format_type, formatter in self.formatters.items():
155 for format_type, formatter in self.formatters.items():
155 if include and format_type not in include:
156 if include and format_type not in include:
156 continue
157 continue
157 if exclude and format_type in exclude:
158 if exclude and format_type in exclude:
158 continue
159 continue
159
160
160 md = None
161 md = None
161 try:
162 try:
162 data = formatter(obj)
163 data = formatter(obj)
163 except:
164 except:
164 # FIXME: log the exception
165 # FIXME: log the exception
165 raise
166 raise
166
167
167 # formatters can return raw data or (data, metadata)
168 # formatters can return raw data or (data, metadata)
168 if isinstance(data, tuple) and len(data) == 2:
169 if isinstance(data, tuple) and len(data) == 2:
169 data, md = data
170 data, md = data
170
171
171 if data is not None:
172 if data is not None:
172 format_dict[format_type] = data
173 format_dict[format_type] = data
173 if md is not None:
174 if md is not None:
174 md_dict[format_type] = md
175 md_dict[format_type] = md
175
176
176 return format_dict, md_dict
177 return format_dict, md_dict
177
178
178 @property
179 @property
179 def format_types(self):
180 def format_types(self):
180 """Return the format types (MIME types) of the active formatters."""
181 """Return the format types (MIME types) of the active formatters."""
181 return list(self.formatters.keys())
182 return list(self.formatters.keys())
182
183
183
184
184 #-----------------------------------------------------------------------------
185 #-----------------------------------------------------------------------------
185 # Formatters for specific format types (text, html, svg, etc.)
186 # Formatters for specific format types (text, html, svg, etc.)
186 #-----------------------------------------------------------------------------
187 #-----------------------------------------------------------------------------
187
188
188 class FormatterWarning(UserWarning):
189 class FormatterWarning(UserWarning):
189 """Warning class for errors in formatters"""
190 """Warning class for errors in formatters"""
190
191
191 @decorator
192 @decorator
192 def warn_format_error(method, self, *args, **kwargs):
193 def warn_format_error(method, self, *args, **kwargs):
193 """decorator for warning on failed format call"""
194 """decorator for warning on failed format call"""
194 try:
195 try:
195 r = method(self, *args, **kwargs)
196 r = method(self, *args, **kwargs)
196 except NotImplementedError as e:
197 except NotImplementedError as e:
197 # don't warn on NotImplementedErrors
198 # don't warn on NotImplementedErrors
198 return None
199 return None
199 except Exception as e:
200 except Exception as e:
200 warnings.warn("Exception in %s formatter: %s" % (self.format_type, e),
201 warnings.warn("Exception in %s formatter: %s" % (self.format_type, e),
201 FormatterWarning,
202 FormatterWarning,
202 )
203 )
203 return None
204 return None
204 if r is None or isinstance(r, self._return_type) or \
205 if r is None or isinstance(r, self._return_type) or \
205 (isinstance(r, tuple) and r and isinstance(r[0], self._return_type)):
206 (isinstance(r, tuple) and r and isinstance(r[0], self._return_type)):
206 return r
207 return r
207 else:
208 else:
208 warnings.warn(
209 warnings.warn(
209 "%s formatter returned invalid type %s (expected %s) for object: %s" % \
210 "%s formatter returned invalid type %s (expected %s) for object: %s" % \
210 (self.format_type, type(r), self._return_type, pretty._safe_repr(args[0])),
211 (self.format_type, type(r), self._return_type, pretty._safe_repr(args[0])),
211 FormatterWarning
212 FormatterWarning
212 )
213 )
213
214
214
215
215 class FormatterABC(with_metaclass(abc.ABCMeta, object)):
216 class FormatterABC(with_metaclass(abc.ABCMeta, object)):
216 """ Abstract base class for Formatters.
217 """ Abstract base class for Formatters.
217
218
218 A formatter is a callable class that is responsible for computing the
219 A formatter is a callable class that is responsible for computing the
219 raw format data for a particular format type (MIME type). For example,
220 raw format data for a particular format type (MIME type). For example,
220 an HTML formatter would have a format type of `text/html` and would return
221 an HTML formatter would have a format type of `text/html` and would return
221 the HTML representation of the object when called.
222 the HTML representation of the object when called.
222 """
223 """
223
224
224 # The format type of the data returned, usually a MIME type.
225 # The format type of the data returned, usually a MIME type.
225 format_type = 'text/plain'
226 format_type = 'text/plain'
226
227
227 # Is the formatter enabled...
228 # Is the formatter enabled...
228 enabled = True
229 enabled = True
229
230
230 @abc.abstractmethod
231 @abc.abstractmethod
231 @warn_format_error
232 @warn_format_error
232 def __call__(self, obj):
233 def __call__(self, obj):
233 """Return a JSON'able representation of the object.
234 """Return a JSON'able representation of the object.
234
235
235 If the object cannot be formatted by this formatter,
236 If the object cannot be formatted by this formatter,
236 warn and return None.
237 warn and return None.
237 """
238 """
238 return repr(obj)
239 return repr(obj)
239
240
240
241
241 def _mod_name_key(typ):
242 def _mod_name_key(typ):
242 """Return a (__module__, __name__) tuple for a type.
243 """Return a (__module__, __name__) tuple for a type.
243
244
244 Used as key in Formatter.deferred_printers.
245 Used as key in Formatter.deferred_printers.
245 """
246 """
246 module = getattr(typ, '__module__', None)
247 module = getattr(typ, '__module__', None)
247 name = getattr(typ, '__name__', None)
248 name = getattr(typ, '__name__', None)
248 return (module, name)
249 return (module, name)
249
250
250
251
251 def _get_type(obj):
252 def _get_type(obj):
252 """Return the type of an instance (old and new-style)"""
253 """Return the type of an instance (old and new-style)"""
253 return getattr(obj, '__class__', None) or type(obj)
254 return getattr(obj, '__class__', None) or type(obj)
254
255
255 _raise_key_error = object()
256 _raise_key_error = object()
256
257
257
258
258 class BaseFormatter(Configurable):
259 class BaseFormatter(Configurable):
259 """A base formatter class that is configurable.
260 """A base formatter class that is configurable.
260
261
261 This formatter should usually be used as the base class of all formatters.
262 This formatter should usually be used as the base class of all formatters.
262 It is a traited :class:`Configurable` class and includes an extensible
263 It is a traited :class:`Configurable` class and includes an extensible
263 API for users to determine how their objects are formatted. The following
264 API for users to determine how their objects are formatted. The following
264 logic is used to find a function to format an given object.
265 logic is used to find a function to format an given object.
265
266
266 1. The object is introspected to see if it has a method with the name
267 1. The object is introspected to see if it has a method with the name
267 :attr:`print_method`. If is does, that object is passed to that method
268 :attr:`print_method`. If is does, that object is passed to that method
268 for formatting.
269 for formatting.
269 2. If no print method is found, three internal dictionaries are consulted
270 2. If no print method is found, three internal dictionaries are consulted
270 to find print method: :attr:`singleton_printers`, :attr:`type_printers`
271 to find print method: :attr:`singleton_printers`, :attr:`type_printers`
271 and :attr:`deferred_printers`.
272 and :attr:`deferred_printers`.
272
273
273 Users should use these dictionaries to register functions that will be
274 Users should use these dictionaries to register functions that will be
274 used to compute the format data for their objects (if those objects don't
275 used to compute the format data for their objects (if those objects don't
275 have the special print methods). The easiest way of using these
276 have the special print methods). The easiest way of using these
276 dictionaries is through the :meth:`for_type` and :meth:`for_type_by_name`
277 dictionaries is through the :meth:`for_type` and :meth:`for_type_by_name`
277 methods.
278 methods.
278
279
279 If no function/callable is found to compute the format data, ``None`` is
280 If no function/callable is found to compute the format data, ``None`` is
280 returned and this format type is not used.
281 returned and this format type is not used.
281 """
282 """
282
283
283 format_type = Unicode('text/plain')
284 format_type = Unicode('text/plain')
284 _return_type = string_types
285 _return_type = string_types
285
286
286 enabled = Bool(True, config=True)
287 enabled = Bool(True, config=True)
287
288
288 print_method = ObjectName('__repr__')
289 print_method = ObjectName('__repr__')
289
290
290 # The singleton printers.
291 # The singleton printers.
291 # Maps the IDs of the builtin singleton objects to the format functions.
292 # Maps the IDs of the builtin singleton objects to the format functions.
292 singleton_printers = Dict(config=True)
293 singleton_printers = Dict(config=True)
293
294
294 # The type-specific printers.
295 # The type-specific printers.
295 # Map type objects to the format functions.
296 # Map type objects to the format functions.
296 type_printers = Dict(config=True)
297 type_printers = Dict(config=True)
297
298
298 # The deferred-import type-specific printers.
299 # The deferred-import type-specific printers.
299 # Map (modulename, classname) pairs to the format functions.
300 # Map (modulename, classname) pairs to the format functions.
300 deferred_printers = Dict(config=True)
301 deferred_printers = Dict(config=True)
301
302
302 @warn_format_error
303 @warn_format_error
303 def __call__(self, obj):
304 def __call__(self, obj):
304 """Compute the format for an object."""
305 """Compute the format for an object."""
305 if self.enabled:
306 if self.enabled:
306 # lookup registered printer
307 # lookup registered printer
307 try:
308 try:
308 printer = self.lookup(obj)
309 printer = self.lookup(obj)
309 except KeyError:
310 except KeyError:
310 pass
311 pass
311 else:
312 else:
312 return printer(obj)
313 return printer(obj)
313 # Finally look for special method names
314 # Finally look for special method names
314 method = pretty._safe_getattr(obj, self.print_method, None)
315 method = pretty._safe_getattr(obj, self.print_method, None)
315 if method is not None:
316 # print_method must be a bound method:
317 if isinstance(method, types.MethodType) and method.__self__ is not None:
316 return method()
318 return method()
317 return None
319 return None
318 else:
320 else:
319 return None
321 return None
320
322
321 def __contains__(self, typ):
323 def __contains__(self, typ):
322 """map in to lookup_by_type"""
324 """map in to lookup_by_type"""
323 try:
325 try:
324 self.lookup_by_type(typ)
326 self.lookup_by_type(typ)
325 except KeyError:
327 except KeyError:
326 return False
328 return False
327 else:
329 else:
328 return True
330 return True
329
331
330 def lookup(self, obj):
332 def lookup(self, obj):
331 """Look up the formatter for a given instance.
333 """Look up the formatter for a given instance.
332
334
333 Parameters
335 Parameters
334 ----------
336 ----------
335 obj : object instance
337 obj : object instance
336
338
337 Returns
339 Returns
338 -------
340 -------
339 f : callable
341 f : callable
340 The registered formatting callable for the type.
342 The registered formatting callable for the type.
341
343
342 Raises
344 Raises
343 ------
345 ------
344 KeyError if the type has not been registered.
346 KeyError if the type has not been registered.
345 """
347 """
346 # look for singleton first
348 # look for singleton first
347 obj_id = id(obj)
349 obj_id = id(obj)
348 if obj_id in self.singleton_printers:
350 if obj_id in self.singleton_printers:
349 return self.singleton_printers[obj_id]
351 return self.singleton_printers[obj_id]
350 # then lookup by type
352 # then lookup by type
351 return self.lookup_by_type(_get_type(obj))
353 return self.lookup_by_type(_get_type(obj))
352
354
353 def lookup_by_type(self, typ):
355 def lookup_by_type(self, typ):
354 """Look up the registered formatter for a type.
356 """Look up the registered formatter for a type.
355
357
356 Parameters
358 Parameters
357 ----------
359 ----------
358 typ : type or '__module__.__name__' string for a type
360 typ : type or '__module__.__name__' string for a type
359
361
360 Returns
362 Returns
361 -------
363 -------
362 f : callable
364 f : callable
363 The registered formatting callable for the type.
365 The registered formatting callable for the type.
364
366
365 Raises
367 Raises
366 ------
368 ------
367 KeyError if the type has not been registered.
369 KeyError if the type has not been registered.
368 """
370 """
369 if isinstance(typ, string_types):
371 if isinstance(typ, string_types):
370 typ_key = tuple(typ.rsplit('.',1))
372 typ_key = tuple(typ.rsplit('.',1))
371 if typ_key not in self.deferred_printers:
373 if typ_key not in self.deferred_printers:
372 # We may have it cached in the type map. We will have to
374 # We may have it cached in the type map. We will have to
373 # iterate over all of the types to check.
375 # iterate over all of the types to check.
374 for cls in self.type_printers:
376 for cls in self.type_printers:
375 if _mod_name_key(cls) == typ_key:
377 if _mod_name_key(cls) == typ_key:
376 return self.type_printers[cls]
378 return self.type_printers[cls]
377 else:
379 else:
378 return self.deferred_printers[typ_key]
380 return self.deferred_printers[typ_key]
379 else:
381 else:
380 for cls in pretty._get_mro(typ):
382 for cls in pretty._get_mro(typ):
381 if cls in self.type_printers or self._in_deferred_types(cls):
383 if cls in self.type_printers or self._in_deferred_types(cls):
382 return self.type_printers[cls]
384 return self.type_printers[cls]
383
385
384 # If we have reached here, the lookup failed.
386 # If we have reached here, the lookup failed.
385 raise KeyError("No registered printer for {0!r}".format(typ))
387 raise KeyError("No registered printer for {0!r}".format(typ))
386
388
387 def for_type(self, typ, func=None):
389 def for_type(self, typ, func=None):
388 """Add a format function for a given type.
390 """Add a format function for a given type.
389
391
390 Parameters
392 Parameters
391 -----------
393 -----------
392 typ : type or '__module__.__name__' string for a type
394 typ : type or '__module__.__name__' string for a type
393 The class of the object that will be formatted using `func`.
395 The class of the object that will be formatted using `func`.
394 func : callable
396 func : callable
395 A callable for computing the format data.
397 A callable for computing the format data.
396 `func` will be called with the object to be formatted,
398 `func` will be called with the object to be formatted,
397 and will return the raw data in this formatter's format.
399 and will return the raw data in this formatter's format.
398 Subclasses may use a different call signature for the
400 Subclasses may use a different call signature for the
399 `func` argument.
401 `func` argument.
400
402
401 If `func` is None or not specified, there will be no change,
403 If `func` is None or not specified, there will be no change,
402 only returning the current value.
404 only returning the current value.
403
405
404 Returns
406 Returns
405 -------
407 -------
406 oldfunc : callable
408 oldfunc : callable
407 The currently registered callable.
409 The currently registered callable.
408 If you are registering a new formatter,
410 If you are registering a new formatter,
409 this will be the previous value (to enable restoring later).
411 this will be the previous value (to enable restoring later).
410 """
412 """
411 # if string given, interpret as 'pkg.module.class_name'
413 # if string given, interpret as 'pkg.module.class_name'
412 if isinstance(typ, string_types):
414 if isinstance(typ, string_types):
413 type_module, type_name = typ.rsplit('.', 1)
415 type_module, type_name = typ.rsplit('.', 1)
414 return self.for_type_by_name(type_module, type_name, func)
416 return self.for_type_by_name(type_module, type_name, func)
415
417
416 try:
418 try:
417 oldfunc = self.lookup_by_type(typ)
419 oldfunc = self.lookup_by_type(typ)
418 except KeyError:
420 except KeyError:
419 oldfunc = None
421 oldfunc = None
420
422
421 if func is not None:
423 if func is not None:
422 self.type_printers[typ] = func
424 self.type_printers[typ] = func
423
425
424 return oldfunc
426 return oldfunc
425
427
426 def for_type_by_name(self, type_module, type_name, func=None):
428 def for_type_by_name(self, type_module, type_name, func=None):
427 """Add a format function for a type specified by the full dotted
429 """Add a format function for a type specified by the full dotted
428 module and name of the type, rather than the type of the object.
430 module and name of the type, rather than the type of the object.
429
431
430 Parameters
432 Parameters
431 ----------
433 ----------
432 type_module : str
434 type_module : str
433 The full dotted name of the module the type is defined in, like
435 The full dotted name of the module the type is defined in, like
434 ``numpy``.
436 ``numpy``.
435 type_name : str
437 type_name : str
436 The name of the type (the class name), like ``dtype``
438 The name of the type (the class name), like ``dtype``
437 func : callable
439 func : callable
438 A callable for computing the format data.
440 A callable for computing the format data.
439 `func` will be called with the object to be formatted,
441 `func` will be called with the object to be formatted,
440 and will return the raw data in this formatter's format.
442 and will return the raw data in this formatter's format.
441 Subclasses may use a different call signature for the
443 Subclasses may use a different call signature for the
442 `func` argument.
444 `func` argument.
443
445
444 If `func` is None or unspecified, there will be no change,
446 If `func` is None or unspecified, there will be no change,
445 only returning the current value.
447 only returning the current value.
446
448
447 Returns
449 Returns
448 -------
450 -------
449 oldfunc : callable
451 oldfunc : callable
450 The currently registered callable.
452 The currently registered callable.
451 If you are registering a new formatter,
453 If you are registering a new formatter,
452 this will be the previous value (to enable restoring later).
454 this will be the previous value (to enable restoring later).
453 """
455 """
454 key = (type_module, type_name)
456 key = (type_module, type_name)
455
457
456 try:
458 try:
457 oldfunc = self.lookup_by_type("%s.%s" % key)
459 oldfunc = self.lookup_by_type("%s.%s" % key)
458 except KeyError:
460 except KeyError:
459 oldfunc = None
461 oldfunc = None
460
462
461 if func is not None:
463 if func is not None:
462 self.deferred_printers[key] = func
464 self.deferred_printers[key] = func
463 return oldfunc
465 return oldfunc
464
466
465 def pop(self, typ, default=_raise_key_error):
467 def pop(self, typ, default=_raise_key_error):
466 """Pop a formatter for the given type.
468 """Pop a formatter for the given type.
467
469
468 Parameters
470 Parameters
469 ----------
471 ----------
470 typ : type or '__module__.__name__' string for a type
472 typ : type or '__module__.__name__' string for a type
471 default : object
473 default : object
472 value to be returned if no formatter is registered for typ.
474 value to be returned if no formatter is registered for typ.
473
475
474 Returns
476 Returns
475 -------
477 -------
476 obj : object
478 obj : object
477 The last registered object for the type.
479 The last registered object for the type.
478
480
479 Raises
481 Raises
480 ------
482 ------
481 KeyError if the type is not registered and default is not specified.
483 KeyError if the type is not registered and default is not specified.
482 """
484 """
483
485
484 if isinstance(typ, string_types):
486 if isinstance(typ, string_types):
485 typ_key = tuple(typ.rsplit('.',1))
487 typ_key = tuple(typ.rsplit('.',1))
486 if typ_key not in self.deferred_printers:
488 if typ_key not in self.deferred_printers:
487 # We may have it cached in the type map. We will have to
489 # We may have it cached in the type map. We will have to
488 # iterate over all of the types to check.
490 # iterate over all of the types to check.
489 for cls in self.type_printers:
491 for cls in self.type_printers:
490 if _mod_name_key(cls) == typ_key:
492 if _mod_name_key(cls) == typ_key:
491 old = self.type_printers.pop(cls)
493 old = self.type_printers.pop(cls)
492 break
494 break
493 else:
495 else:
494 old = default
496 old = default
495 else:
497 else:
496 old = self.deferred_printers.pop(typ_key)
498 old = self.deferred_printers.pop(typ_key)
497 else:
499 else:
498 if typ in self.type_printers:
500 if typ in self.type_printers:
499 old = self.type_printers.pop(typ)
501 old = self.type_printers.pop(typ)
500 else:
502 else:
501 old = self.deferred_printers.pop(_mod_name_key(typ), default)
503 old = self.deferred_printers.pop(_mod_name_key(typ), default)
502 if old is _raise_key_error:
504 if old is _raise_key_error:
503 raise KeyError("No registered value for {0!r}".format(typ))
505 raise KeyError("No registered value for {0!r}".format(typ))
504 return old
506 return old
505
507
506 def _in_deferred_types(self, cls):
508 def _in_deferred_types(self, cls):
507 """
509 """
508 Check if the given class is specified in the deferred type registry.
510 Check if the given class is specified in the deferred type registry.
509
511
510 Successful matches will be moved to the regular type registry for future use.
512 Successful matches will be moved to the regular type registry for future use.
511 """
513 """
512 mod = getattr(cls, '__module__', None)
514 mod = getattr(cls, '__module__', None)
513 name = getattr(cls, '__name__', None)
515 name = getattr(cls, '__name__', None)
514 key = (mod, name)
516 key = (mod, name)
515 if key in self.deferred_printers:
517 if key in self.deferred_printers:
516 # Move the printer over to the regular registry.
518 # Move the printer over to the regular registry.
517 printer = self.deferred_printers.pop(key)
519 printer = self.deferred_printers.pop(key)
518 self.type_printers[cls] = printer
520 self.type_printers[cls] = printer
519 return True
521 return True
520 return False
522 return False
521
523
522
524
523 class PlainTextFormatter(BaseFormatter):
525 class PlainTextFormatter(BaseFormatter):
524 """The default pretty-printer.
526 """The default pretty-printer.
525
527
526 This uses :mod:`IPython.lib.pretty` to compute the format data of
528 This uses :mod:`IPython.lib.pretty` to compute the format data of
527 the object. If the object cannot be pretty printed, :func:`repr` is used.
529 the object. If the object cannot be pretty printed, :func:`repr` is used.
528 See the documentation of :mod:`IPython.lib.pretty` for details on
530 See the documentation of :mod:`IPython.lib.pretty` for details on
529 how to write pretty printers. Here is a simple example::
531 how to write pretty printers. Here is a simple example::
530
532
531 def dtype_pprinter(obj, p, cycle):
533 def dtype_pprinter(obj, p, cycle):
532 if cycle:
534 if cycle:
533 return p.text('dtype(...)')
535 return p.text('dtype(...)')
534 if hasattr(obj, 'fields'):
536 if hasattr(obj, 'fields'):
535 if obj.fields is None:
537 if obj.fields is None:
536 p.text(repr(obj))
538 p.text(repr(obj))
537 else:
539 else:
538 p.begin_group(7, 'dtype([')
540 p.begin_group(7, 'dtype([')
539 for i, field in enumerate(obj.descr):
541 for i, field in enumerate(obj.descr):
540 if i > 0:
542 if i > 0:
541 p.text(',')
543 p.text(',')
542 p.breakable()
544 p.breakable()
543 p.pretty(field)
545 p.pretty(field)
544 p.end_group(7, '])')
546 p.end_group(7, '])')
545 """
547 """
546
548
547 # The format type of data returned.
549 # The format type of data returned.
548 format_type = Unicode('text/plain')
550 format_type = Unicode('text/plain')
549
551
550 # This subclass ignores this attribute as it always need to return
552 # This subclass ignores this attribute as it always need to return
551 # something.
553 # something.
552 enabled = Bool(True, config=False)
554 enabled = Bool(True, config=False)
553
555
554 # Look for a _repr_pretty_ methods to use for pretty printing.
556 # Look for a _repr_pretty_ methods to use for pretty printing.
555 print_method = ObjectName('_repr_pretty_')
557 print_method = ObjectName('_repr_pretty_')
556
558
557 # Whether to pretty-print or not.
559 # Whether to pretty-print or not.
558 pprint = Bool(True, config=True)
560 pprint = Bool(True, config=True)
559
561
560 # Whether to be verbose or not.
562 # Whether to be verbose or not.
561 verbose = Bool(False, config=True)
563 verbose = Bool(False, config=True)
562
564
563 # The maximum width.
565 # The maximum width.
564 max_width = Integer(79, config=True)
566 max_width = Integer(79, config=True)
565
567
566 # The newline character.
568 # The newline character.
567 newline = Unicode('\n', config=True)
569 newline = Unicode('\n', config=True)
568
570
569 # format-string for pprinting floats
571 # format-string for pprinting floats
570 float_format = Unicode('%r')
572 float_format = Unicode('%r')
571 # setter for float precision, either int or direct format-string
573 # setter for float precision, either int or direct format-string
572 float_precision = CUnicode('', config=True)
574 float_precision = CUnicode('', config=True)
573
575
574 def _float_precision_changed(self, name, old, new):
576 def _float_precision_changed(self, name, old, new):
575 """float_precision changed, set float_format accordingly.
577 """float_precision changed, set float_format accordingly.
576
578
577 float_precision can be set by int or str.
579 float_precision can be set by int or str.
578 This will set float_format, after interpreting input.
580 This will set float_format, after interpreting input.
579 If numpy has been imported, numpy print precision will also be set.
581 If numpy has been imported, numpy print precision will also be set.
580
582
581 integer `n` sets format to '%.nf', otherwise, format set directly.
583 integer `n` sets format to '%.nf', otherwise, format set directly.
582
584
583 An empty string returns to defaults (repr for float, 8 for numpy).
585 An empty string returns to defaults (repr for float, 8 for numpy).
584
586
585 This parameter can be set via the '%precision' magic.
587 This parameter can be set via the '%precision' magic.
586 """
588 """
587
589
588 if '%' in new:
590 if '%' in new:
589 # got explicit format string
591 # got explicit format string
590 fmt = new
592 fmt = new
591 try:
593 try:
592 fmt%3.14159
594 fmt%3.14159
593 except Exception:
595 except Exception:
594 raise ValueError("Precision must be int or format string, not %r"%new)
596 raise ValueError("Precision must be int or format string, not %r"%new)
595 elif new:
597 elif new:
596 # otherwise, should be an int
598 # otherwise, should be an int
597 try:
599 try:
598 i = int(new)
600 i = int(new)
599 assert i >= 0
601 assert i >= 0
600 except ValueError:
602 except ValueError:
601 raise ValueError("Precision must be int or format string, not %r"%new)
603 raise ValueError("Precision must be int or format string, not %r"%new)
602 except AssertionError:
604 except AssertionError:
603 raise ValueError("int precision must be non-negative, not %r"%i)
605 raise ValueError("int precision must be non-negative, not %r"%i)
604
606
605 fmt = '%%.%if'%i
607 fmt = '%%.%if'%i
606 if 'numpy' in sys.modules:
608 if 'numpy' in sys.modules:
607 # set numpy precision if it has been imported
609 # set numpy precision if it has been imported
608 import numpy
610 import numpy
609 numpy.set_printoptions(precision=i)
611 numpy.set_printoptions(precision=i)
610 else:
612 else:
611 # default back to repr
613 # default back to repr
612 fmt = '%r'
614 fmt = '%r'
613 if 'numpy' in sys.modules:
615 if 'numpy' in sys.modules:
614 import numpy
616 import numpy
615 # numpy default is 8
617 # numpy default is 8
616 numpy.set_printoptions(precision=8)
618 numpy.set_printoptions(precision=8)
617 self.float_format = fmt
619 self.float_format = fmt
618
620
619 # Use the default pretty printers from IPython.lib.pretty.
621 # Use the default pretty printers from IPython.lib.pretty.
620 def _singleton_printers_default(self):
622 def _singleton_printers_default(self):
621 return pretty._singleton_pprinters.copy()
623 return pretty._singleton_pprinters.copy()
622
624
623 def _type_printers_default(self):
625 def _type_printers_default(self):
624 d = pretty._type_pprinters.copy()
626 d = pretty._type_pprinters.copy()
625 d[float] = lambda obj,p,cycle: p.text(self.float_format%obj)
627 d[float] = lambda obj,p,cycle: p.text(self.float_format%obj)
626 return d
628 return d
627
629
628 def _deferred_printers_default(self):
630 def _deferred_printers_default(self):
629 return pretty._deferred_type_pprinters.copy()
631 return pretty._deferred_type_pprinters.copy()
630
632
631 #### FormatterABC interface ####
633 #### FormatterABC interface ####
632
634
633 @warn_format_error
635 @warn_format_error
634 def __call__(self, obj):
636 def __call__(self, obj):
635 """Compute the pretty representation of the object."""
637 """Compute the pretty representation of the object."""
636 if not self.pprint:
638 if not self.pprint:
637 return pretty._safe_repr(obj)
639 return pretty._safe_repr(obj)
638 else:
640 else:
639 # This uses use StringIO, as cStringIO doesn't handle unicode.
641 # This uses use StringIO, as cStringIO doesn't handle unicode.
640 stream = StringIO()
642 stream = StringIO()
641 # self.newline.encode() is a quick fix for issue gh-597. We need to
643 # self.newline.encode() is a quick fix for issue gh-597. We need to
642 # ensure that stream does not get a mix of unicode and bytestrings,
644 # ensure that stream does not get a mix of unicode and bytestrings,
643 # or it will cause trouble.
645 # or it will cause trouble.
644 printer = pretty.RepresentationPrinter(stream, self.verbose,
646 printer = pretty.RepresentationPrinter(stream, self.verbose,
645 self.max_width, unicode_to_str(self.newline),
647 self.max_width, unicode_to_str(self.newline),
646 singleton_pprinters=self.singleton_printers,
648 singleton_pprinters=self.singleton_printers,
647 type_pprinters=self.type_printers,
649 type_pprinters=self.type_printers,
648 deferred_pprinters=self.deferred_printers)
650 deferred_pprinters=self.deferred_printers)
649 printer.pretty(obj)
651 printer.pretty(obj)
650 printer.flush()
652 printer.flush()
651 return stream.getvalue()
653 return stream.getvalue()
652
654
653
655
654 class HTMLFormatter(BaseFormatter):
656 class HTMLFormatter(BaseFormatter):
655 """An HTML formatter.
657 """An HTML formatter.
656
658
657 To define the callables that compute the HTML representation of your
659 To define the callables that compute the HTML representation of your
658 objects, define a :meth:`_repr_html_` method or use the :meth:`for_type`
660 objects, define a :meth:`_repr_html_` method or use the :meth:`for_type`
659 or :meth:`for_type_by_name` methods to register functions that handle
661 or :meth:`for_type_by_name` methods to register functions that handle
660 this.
662 this.
661
663
662 The return value of this formatter should be a valid HTML snippet that
664 The return value of this formatter should be a valid HTML snippet that
663 could be injected into an existing DOM. It should *not* include the
665 could be injected into an existing DOM. It should *not* include the
664 ```<html>`` or ```<body>`` tags.
666 ```<html>`` or ```<body>`` tags.
665 """
667 """
666 format_type = Unicode('text/html')
668 format_type = Unicode('text/html')
667
669
668 print_method = ObjectName('_repr_html_')
670 print_method = ObjectName('_repr_html_')
669
671
670
672
671 class SVGFormatter(BaseFormatter):
673 class SVGFormatter(BaseFormatter):
672 """An SVG formatter.
674 """An SVG formatter.
673
675
674 To define the callables that compute the SVG representation of your
676 To define the callables that compute the SVG representation of your
675 objects, define a :meth:`_repr_svg_` method or use the :meth:`for_type`
677 objects, define a :meth:`_repr_svg_` method or use the :meth:`for_type`
676 or :meth:`for_type_by_name` methods to register functions that handle
678 or :meth:`for_type_by_name` methods to register functions that handle
677 this.
679 this.
678
680
679 The return value of this formatter should be valid SVG enclosed in
681 The return value of this formatter should be valid SVG enclosed in
680 ```<svg>``` tags, that could be injected into an existing DOM. It should
682 ```<svg>``` tags, that could be injected into an existing DOM. It should
681 *not* include the ```<html>`` or ```<body>`` tags.
683 *not* include the ```<html>`` or ```<body>`` tags.
682 """
684 """
683 format_type = Unicode('image/svg+xml')
685 format_type = Unicode('image/svg+xml')
684
686
685 print_method = ObjectName('_repr_svg_')
687 print_method = ObjectName('_repr_svg_')
686
688
687
689
688 class PNGFormatter(BaseFormatter):
690 class PNGFormatter(BaseFormatter):
689 """A PNG formatter.
691 """A PNG formatter.
690
692
691 To define the callables that compute the PNG representation of your
693 To define the callables that compute the PNG representation of your
692 objects, define a :meth:`_repr_png_` method or use the :meth:`for_type`
694 objects, define a :meth:`_repr_png_` method or use the :meth:`for_type`
693 or :meth:`for_type_by_name` methods to register functions that handle
695 or :meth:`for_type_by_name` methods to register functions that handle
694 this.
696 this.
695
697
696 The return value of this formatter should be raw PNG data, *not*
698 The return value of this formatter should be raw PNG data, *not*
697 base64 encoded.
699 base64 encoded.
698 """
700 """
699 format_type = Unicode('image/png')
701 format_type = Unicode('image/png')
700
702
701 print_method = ObjectName('_repr_png_')
703 print_method = ObjectName('_repr_png_')
702
704
703 _return_type = (bytes, unicode_type)
705 _return_type = (bytes, unicode_type)
704
706
705
707
706 class JPEGFormatter(BaseFormatter):
708 class JPEGFormatter(BaseFormatter):
707 """A JPEG formatter.
709 """A JPEG formatter.
708
710
709 To define the callables that compute the JPEG representation of your
711 To define the callables that compute the JPEG representation of your
710 objects, define a :meth:`_repr_jpeg_` method or use the :meth:`for_type`
712 objects, define a :meth:`_repr_jpeg_` method or use the :meth:`for_type`
711 or :meth:`for_type_by_name` methods to register functions that handle
713 or :meth:`for_type_by_name` methods to register functions that handle
712 this.
714 this.
713
715
714 The return value of this formatter should be raw JPEG data, *not*
716 The return value of this formatter should be raw JPEG data, *not*
715 base64 encoded.
717 base64 encoded.
716 """
718 """
717 format_type = Unicode('image/jpeg')
719 format_type = Unicode('image/jpeg')
718
720
719 print_method = ObjectName('_repr_jpeg_')
721 print_method = ObjectName('_repr_jpeg_')
720
722
721 _return_type = (bytes, unicode_type)
723 _return_type = (bytes, unicode_type)
722
724
723
725
724 class LatexFormatter(BaseFormatter):
726 class LatexFormatter(BaseFormatter):
725 """A LaTeX formatter.
727 """A LaTeX formatter.
726
728
727 To define the callables that compute the LaTeX representation of your
729 To define the callables that compute the LaTeX representation of your
728 objects, define a :meth:`_repr_latex_` method or use the :meth:`for_type`
730 objects, define a :meth:`_repr_latex_` method or use the :meth:`for_type`
729 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
730 this.
732 this.
731
733
732 The return value of this formatter should be a valid LaTeX equation,
734 The return value of this formatter should be a valid LaTeX equation,
733 enclosed in either ```$```, ```$$``` or another LaTeX equation
735 enclosed in either ```$```, ```$$``` or another LaTeX equation
734 environment.
736 environment.
735 """
737 """
736 format_type = Unicode('text/latex')
738 format_type = Unicode('text/latex')
737
739
738 print_method = ObjectName('_repr_latex_')
740 print_method = ObjectName('_repr_latex_')
739
741
740
742
741 class JSONFormatter(BaseFormatter):
743 class JSONFormatter(BaseFormatter):
742 """A JSON string formatter.
744 """A JSON string formatter.
743
745
744 To define the callables that compute the JSON string representation of
746 To define the callables that compute the JSON string representation of
745 your objects, define a :meth:`_repr_json_` method or use the :meth:`for_type`
747 your objects, define a :meth:`_repr_json_` method or use the :meth:`for_type`
746 or :meth:`for_type_by_name` methods to register functions that handle
748 or :meth:`for_type_by_name` methods to register functions that handle
747 this.
749 this.
748
750
749 The return value of this formatter should be a valid JSON string.
751 The return value of this formatter should be a valid JSON string.
750 """
752 """
751 format_type = Unicode('application/json')
753 format_type = Unicode('application/json')
752
754
753 print_method = ObjectName('_repr_json_')
755 print_method = ObjectName('_repr_json_')
754
756
755
757
756 class JavascriptFormatter(BaseFormatter):
758 class JavascriptFormatter(BaseFormatter):
757 """A Javascript formatter.
759 """A Javascript formatter.
758
760
759 To define the callables that compute the Javascript representation of
761 To define the callables that compute the Javascript representation of
760 your objects, define a :meth:`_repr_javascript_` method or use the
762 your objects, define a :meth:`_repr_javascript_` method or use the
761 :meth:`for_type` or :meth:`for_type_by_name` methods to register functions
763 :meth:`for_type` or :meth:`for_type_by_name` methods to register functions
762 that handle this.
764 that handle this.
763
765
764 The return value of this formatter should be valid Javascript code and
766 The return value of this formatter should be valid Javascript code and
765 should *not* be enclosed in ```<script>``` tags.
767 should *not* be enclosed in ```<script>``` tags.
766 """
768 """
767 format_type = Unicode('application/javascript')
769 format_type = Unicode('application/javascript')
768
770
769 print_method = ObjectName('_repr_javascript_')
771 print_method = ObjectName('_repr_javascript_')
770
772
771
773
772 class PDFFormatter(BaseFormatter):
774 class PDFFormatter(BaseFormatter):
773 """A PDF formatter.
775 """A PDF formatter.
774
776
775 To defined the callables that compute to PDF representation of your
777 To defined the callables that compute to PDF representation of your
776 objects, define a :meth:`_repr_pdf_` method or use the :meth:`for_type`
778 objects, define a :meth:`_repr_pdf_` method or use the :meth:`for_type`
777 or :meth:`for_type_by_name` methods to register functions that handle
779 or :meth:`for_type_by_name` methods to register functions that handle
778 this.
780 this.
779
781
780 The return value of this formatter should be raw PDF data, *not*
782 The return value of this formatter should be raw PDF data, *not*
781 base64 encoded.
783 base64 encoded.
782 """
784 """
783 format_type = Unicode('application/pdf')
785 format_type = Unicode('application/pdf')
784
786
785 print_method = ObjectName('_repr_pdf_')
787 print_method = ObjectName('_repr_pdf_')
786
788
787
789
788 FormatterABC.register(BaseFormatter)
790 FormatterABC.register(BaseFormatter)
789 FormatterABC.register(PlainTextFormatter)
791 FormatterABC.register(PlainTextFormatter)
790 FormatterABC.register(HTMLFormatter)
792 FormatterABC.register(HTMLFormatter)
791 FormatterABC.register(SVGFormatter)
793 FormatterABC.register(SVGFormatter)
792 FormatterABC.register(PNGFormatter)
794 FormatterABC.register(PNGFormatter)
793 FormatterABC.register(PDFFormatter)
795 FormatterABC.register(PDFFormatter)
794 FormatterABC.register(JPEGFormatter)
796 FormatterABC.register(JPEGFormatter)
795 FormatterABC.register(LatexFormatter)
797 FormatterABC.register(LatexFormatter)
796 FormatterABC.register(JSONFormatter)
798 FormatterABC.register(JSONFormatter)
797 FormatterABC.register(JavascriptFormatter)
799 FormatterABC.register(JavascriptFormatter)
798
800
799
801
800 def format_display_data(obj, include=None, exclude=None):
802 def format_display_data(obj, include=None, exclude=None):
801 """Return a format data dict for an object.
803 """Return a format data dict for an object.
802
804
803 By default all format types will be computed.
805 By default all format types will be computed.
804
806
805 The following MIME types are currently implemented:
807 The following MIME types are currently implemented:
806
808
807 * text/plain
809 * text/plain
808 * text/html
810 * text/html
809 * text/latex
811 * text/latex
810 * application/json
812 * application/json
811 * application/javascript
813 * application/javascript
812 * application/pdf
814 * application/pdf
813 * image/png
815 * image/png
814 * image/jpeg
816 * image/jpeg
815 * image/svg+xml
817 * image/svg+xml
816
818
817 Parameters
819 Parameters
818 ----------
820 ----------
819 obj : object
821 obj : object
820 The Python object whose format data will be computed.
822 The Python object whose format data will be computed.
821
823
822 Returns
824 Returns
823 -------
825 -------
824 format_dict : dict
826 format_dict : dict
825 A dictionary of key/value pairs, one or each format that was
827 A dictionary of key/value pairs, one or each format that was
826 generated for the object. The keys are the format types, which
828 generated for the object. The keys are the format types, which
827 will usually be MIME type strings and the values and JSON'able
829 will usually be MIME type strings and the values and JSON'able
828 data structure containing the raw data for the representation in
830 data structure containing the raw data for the representation in
829 that format.
831 that format.
830 include : list or tuple, optional
832 include : list or tuple, optional
831 A list of format type strings (MIME types) to include in the
833 A list of format type strings (MIME types) to include in the
832 format data dict. If this is set *only* the format types included
834 format data dict. If this is set *only* the format types included
833 in this list will be computed.
835 in this list will be computed.
834 exclude : list or tuple, optional
836 exclude : list or tuple, optional
835 A list of format type string (MIME types) to exclue in the format
837 A list of format type string (MIME types) to exclue in the format
836 data dict. If this is set all format types will be computed,
838 data dict. If this is set all format types will be computed,
837 except for those included in this argument.
839 except for those included in this argument.
838 """
840 """
839 from IPython.core.interactiveshell import InteractiveShell
841 from IPython.core.interactiveshell import InteractiveShell
840
842
841 InteractiveShell.instance().display_formatter.format(
843 InteractiveShell.instance().display_formatter.format(
842 obj,
844 obj,
843 include,
845 include,
844 exclude
846 exclude
845 )
847 )
846
848
@@ -1,291 +1,322 b''
1 """Tests for the Formatters."""
1 """Tests for the Formatters."""
2
2
3 from math import pi
3 from math import pi
4
4
5 try:
5 try:
6 import numpy
6 import numpy
7 except:
7 except:
8 numpy = None
8 numpy = None
9 import nose.tools as nt
9 import nose.tools as nt
10
10
11 from IPython.config import Config
11 from IPython.core.formatters import (
12 from IPython.core.formatters import (
12 PlainTextFormatter, HTMLFormatter, PDFFormatter, _mod_name_key
13 PlainTextFormatter, HTMLFormatter, PDFFormatter, _mod_name_key
13 )
14 )
14 from IPython.utils.io import capture_output
15 from IPython.utils.io import capture_output
15
16
16 class A(object):
17 class A(object):
17 def __repr__(self):
18 def __repr__(self):
18 return 'A()'
19 return 'A()'
19
20
20 class B(A):
21 class B(A):
21 def __repr__(self):
22 def __repr__(self):
22 return 'B()'
23 return 'B()'
23
24
24 class C:
25 class C:
25 pass
26 pass
26
27
27 class BadPretty(object):
28 class BadPretty(object):
28 _repr_pretty_ = None
29 _repr_pretty_ = None
29
30
30 class GoodPretty(object):
31 class GoodPretty(object):
31 def _repr_pretty_(self, pp, cycle):
32 def _repr_pretty_(self, pp, cycle):
32 pp.text('foo')
33 pp.text('foo')
33
34
34 def __repr__(self):
35 def __repr__(self):
35 return 'GoodPretty()'
36 return 'GoodPretty()'
36
37
37 def foo_printer(obj, pp, cycle):
38 def foo_printer(obj, pp, cycle):
38 pp.text('foo')
39 pp.text('foo')
39
40
40 def test_pretty():
41 def test_pretty():
41 f = PlainTextFormatter()
42 f = PlainTextFormatter()
42 f.for_type(A, foo_printer)
43 f.for_type(A, foo_printer)
43 nt.assert_equal(f(A()), 'foo')
44 nt.assert_equal(f(A()), 'foo')
44 nt.assert_equal(f(B()), 'foo')
45 nt.assert_equal(f(B()), 'foo')
45 nt.assert_equal(f(GoodPretty()), 'foo')
46 nt.assert_equal(f(GoodPretty()), 'foo')
46 # Just don't raise an exception for the following:
47 # Just don't raise an exception for the following:
47 f(BadPretty())
48 f(BadPretty())
48
49
49 f.pprint = False
50 f.pprint = False
50 nt.assert_equal(f(A()), 'A()')
51 nt.assert_equal(f(A()), 'A()')
51 nt.assert_equal(f(B()), 'B()')
52 nt.assert_equal(f(B()), 'B()')
52 nt.assert_equal(f(GoodPretty()), 'GoodPretty()')
53 nt.assert_equal(f(GoodPretty()), 'GoodPretty()')
53
54
54
55
55 def test_deferred():
56 def test_deferred():
56 f = PlainTextFormatter()
57 f = PlainTextFormatter()
57
58
58 def test_precision():
59 def test_precision():
59 """test various values for float_precision."""
60 """test various values for float_precision."""
60 f = PlainTextFormatter()
61 f = PlainTextFormatter()
61 nt.assert_equal(f(pi), repr(pi))
62 nt.assert_equal(f(pi), repr(pi))
62 f.float_precision = 0
63 f.float_precision = 0
63 if numpy:
64 if numpy:
64 po = numpy.get_printoptions()
65 po = numpy.get_printoptions()
65 nt.assert_equal(po['precision'], 0)
66 nt.assert_equal(po['precision'], 0)
66 nt.assert_equal(f(pi), '3')
67 nt.assert_equal(f(pi), '3')
67 f.float_precision = 2
68 f.float_precision = 2
68 if numpy:
69 if numpy:
69 po = numpy.get_printoptions()
70 po = numpy.get_printoptions()
70 nt.assert_equal(po['precision'], 2)
71 nt.assert_equal(po['precision'], 2)
71 nt.assert_equal(f(pi), '3.14')
72 nt.assert_equal(f(pi), '3.14')
72 f.float_precision = '%g'
73 f.float_precision = '%g'
73 if numpy:
74 if numpy:
74 po = numpy.get_printoptions()
75 po = numpy.get_printoptions()
75 nt.assert_equal(po['precision'], 2)
76 nt.assert_equal(po['precision'], 2)
76 nt.assert_equal(f(pi), '3.14159')
77 nt.assert_equal(f(pi), '3.14159')
77 f.float_precision = '%e'
78 f.float_precision = '%e'
78 nt.assert_equal(f(pi), '3.141593e+00')
79 nt.assert_equal(f(pi), '3.141593e+00')
79 f.float_precision = ''
80 f.float_precision = ''
80 if numpy:
81 if numpy:
81 po = numpy.get_printoptions()
82 po = numpy.get_printoptions()
82 nt.assert_equal(po['precision'], 8)
83 nt.assert_equal(po['precision'], 8)
83 nt.assert_equal(f(pi), repr(pi))
84 nt.assert_equal(f(pi), repr(pi))
84
85
85 def test_bad_precision():
86 def test_bad_precision():
86 """test various invalid values for float_precision."""
87 """test various invalid values for float_precision."""
87 f = PlainTextFormatter()
88 f = PlainTextFormatter()
88 def set_fp(p):
89 def set_fp(p):
89 f.float_precision=p
90 f.float_precision=p
90 nt.assert_raises(ValueError, set_fp, '%')
91 nt.assert_raises(ValueError, set_fp, '%')
91 nt.assert_raises(ValueError, set_fp, '%.3f%i')
92 nt.assert_raises(ValueError, set_fp, '%.3f%i')
92 nt.assert_raises(ValueError, set_fp, 'foo')
93 nt.assert_raises(ValueError, set_fp, 'foo')
93 nt.assert_raises(ValueError, set_fp, -1)
94 nt.assert_raises(ValueError, set_fp, -1)
94
95
95 def test_for_type():
96 def test_for_type():
96 f = PlainTextFormatter()
97 f = PlainTextFormatter()
97
98
98 # initial return, None
99 # initial return, None
99 nt.assert_is(f.for_type(C, foo_printer), None)
100 nt.assert_is(f.for_type(C, foo_printer), None)
100 # no func queries
101 # no func queries
101 nt.assert_is(f.for_type(C), foo_printer)
102 nt.assert_is(f.for_type(C), foo_printer)
102 # shouldn't change anything
103 # shouldn't change anything
103 nt.assert_is(f.for_type(C), foo_printer)
104 nt.assert_is(f.for_type(C), foo_printer)
104 # None should do the same
105 # None should do the same
105 nt.assert_is(f.for_type(C, None), foo_printer)
106 nt.assert_is(f.for_type(C, None), foo_printer)
106 nt.assert_is(f.for_type(C, None), foo_printer)
107 nt.assert_is(f.for_type(C, None), foo_printer)
107
108
108 def test_for_type_string():
109 def test_for_type_string():
109 f = PlainTextFormatter()
110 f = PlainTextFormatter()
110
111
111 mod = C.__module__
112 mod = C.__module__
112
113
113 type_str = '%s.%s' % (C.__module__, 'C')
114 type_str = '%s.%s' % (C.__module__, 'C')
114
115
115 # initial return, None
116 # initial return, None
116 nt.assert_is(f.for_type(type_str, foo_printer), None)
117 nt.assert_is(f.for_type(type_str, foo_printer), None)
117 # no func queries
118 # no func queries
118 nt.assert_is(f.for_type(type_str), foo_printer)
119 nt.assert_is(f.for_type(type_str), foo_printer)
119 nt.assert_in(_mod_name_key(C), f.deferred_printers)
120 nt.assert_in(_mod_name_key(C), f.deferred_printers)
120 nt.assert_is(f.for_type(C), foo_printer)
121 nt.assert_is(f.for_type(C), foo_printer)
121 nt.assert_not_in(_mod_name_key(C), f.deferred_printers)
122 nt.assert_not_in(_mod_name_key(C), f.deferred_printers)
122 nt.assert_in(C, f.type_printers)
123 nt.assert_in(C, f.type_printers)
123
124
124 def test_for_type_by_name():
125 def test_for_type_by_name():
125 f = PlainTextFormatter()
126 f = PlainTextFormatter()
126
127
127 mod = C.__module__
128 mod = C.__module__
128
129
129 # initial return, None
130 # initial return, None
130 nt.assert_is(f.for_type_by_name(mod, 'C', foo_printer), None)
131 nt.assert_is(f.for_type_by_name(mod, 'C', foo_printer), None)
131 # no func queries
132 # no func queries
132 nt.assert_is(f.for_type_by_name(mod, 'C'), foo_printer)
133 nt.assert_is(f.for_type_by_name(mod, 'C'), foo_printer)
133 # shouldn't change anything
134 # shouldn't change anything
134 nt.assert_is(f.for_type_by_name(mod, 'C'), foo_printer)
135 nt.assert_is(f.for_type_by_name(mod, 'C'), foo_printer)
135 # None should do the same
136 # None should do the same
136 nt.assert_is(f.for_type_by_name(mod, 'C', None), foo_printer)
137 nt.assert_is(f.for_type_by_name(mod, 'C', None), foo_printer)
137 nt.assert_is(f.for_type_by_name(mod, 'C', None), foo_printer)
138 nt.assert_is(f.for_type_by_name(mod, 'C', None), foo_printer)
138
139
139 def test_lookup():
140 def test_lookup():
140 f = PlainTextFormatter()
141 f = PlainTextFormatter()
141
142
142 f.for_type(C, foo_printer)
143 f.for_type(C, foo_printer)
143 nt.assert_is(f.lookup(C()), foo_printer)
144 nt.assert_is(f.lookup(C()), foo_printer)
144 with nt.assert_raises(KeyError):
145 with nt.assert_raises(KeyError):
145 f.lookup(A())
146 f.lookup(A())
146
147
147 def test_lookup_string():
148 def test_lookup_string():
148 f = PlainTextFormatter()
149 f = PlainTextFormatter()
149 type_str = '%s.%s' % (C.__module__, 'C')
150 type_str = '%s.%s' % (C.__module__, 'C')
150
151
151 f.for_type(type_str, foo_printer)
152 f.for_type(type_str, foo_printer)
152 nt.assert_is(f.lookup(C()), foo_printer)
153 nt.assert_is(f.lookup(C()), foo_printer)
153 # should move from deferred to imported dict
154 # should move from deferred to imported dict
154 nt.assert_not_in(_mod_name_key(C), f.deferred_printers)
155 nt.assert_not_in(_mod_name_key(C), f.deferred_printers)
155 nt.assert_in(C, f.type_printers)
156 nt.assert_in(C, f.type_printers)
156
157
157 def test_lookup_by_type():
158 def test_lookup_by_type():
158 f = PlainTextFormatter()
159 f = PlainTextFormatter()
159 f.for_type(C, foo_printer)
160 f.for_type(C, foo_printer)
160 nt.assert_is(f.lookup_by_type(C), foo_printer)
161 nt.assert_is(f.lookup_by_type(C), foo_printer)
161 type_str = '%s.%s' % (C.__module__, 'C')
162 type_str = '%s.%s' % (C.__module__, 'C')
162 with nt.assert_raises(KeyError):
163 with nt.assert_raises(KeyError):
163 f.lookup_by_type(A)
164 f.lookup_by_type(A)
164
165
165 def test_lookup_by_type_string():
166 def test_lookup_by_type_string():
166 f = PlainTextFormatter()
167 f = PlainTextFormatter()
167 type_str = '%s.%s' % (C.__module__, 'C')
168 type_str = '%s.%s' % (C.__module__, 'C')
168 f.for_type(type_str, foo_printer)
169 f.for_type(type_str, foo_printer)
169
170
170 # verify insertion
171 # verify insertion
171 nt.assert_in(_mod_name_key(C), f.deferred_printers)
172 nt.assert_in(_mod_name_key(C), f.deferred_printers)
172 nt.assert_not_in(C, f.type_printers)
173 nt.assert_not_in(C, f.type_printers)
173
174
174 nt.assert_is(f.lookup_by_type(type_str), foo_printer)
175 nt.assert_is(f.lookup_by_type(type_str), foo_printer)
175 # lookup by string doesn't cause import
176 # lookup by string doesn't cause import
176 nt.assert_in(_mod_name_key(C), f.deferred_printers)
177 nt.assert_in(_mod_name_key(C), f.deferred_printers)
177 nt.assert_not_in(C, f.type_printers)
178 nt.assert_not_in(C, f.type_printers)
178
179
179 nt.assert_is(f.lookup_by_type(C), foo_printer)
180 nt.assert_is(f.lookup_by_type(C), foo_printer)
180 # should move from deferred to imported dict
181 # should move from deferred to imported dict
181 nt.assert_not_in(_mod_name_key(C), f.deferred_printers)
182 nt.assert_not_in(_mod_name_key(C), f.deferred_printers)
182 nt.assert_in(C, f.type_printers)
183 nt.assert_in(C, f.type_printers)
183
184
184 def test_in_formatter():
185 def test_in_formatter():
185 f = PlainTextFormatter()
186 f = PlainTextFormatter()
186 f.for_type(C, foo_printer)
187 f.for_type(C, foo_printer)
187 type_str = '%s.%s' % (C.__module__, 'C')
188 type_str = '%s.%s' % (C.__module__, 'C')
188 nt.assert_in(C, f)
189 nt.assert_in(C, f)
189 nt.assert_in(type_str, f)
190 nt.assert_in(type_str, f)
190
191
191 def test_string_in_formatter():
192 def test_string_in_formatter():
192 f = PlainTextFormatter()
193 f = PlainTextFormatter()
193 type_str = '%s.%s' % (C.__module__, 'C')
194 type_str = '%s.%s' % (C.__module__, 'C')
194 f.for_type(type_str, foo_printer)
195 f.for_type(type_str, foo_printer)
195 nt.assert_in(type_str, f)
196 nt.assert_in(type_str, f)
196 nt.assert_in(C, f)
197 nt.assert_in(C, f)
197
198
198 def test_pop():
199 def test_pop():
199 f = PlainTextFormatter()
200 f = PlainTextFormatter()
200 f.for_type(C, foo_printer)
201 f.for_type(C, foo_printer)
201 nt.assert_is(f.lookup_by_type(C), foo_printer)
202 nt.assert_is(f.lookup_by_type(C), foo_printer)
202 nt.assert_is(f.pop(C, None), foo_printer)
203 nt.assert_is(f.pop(C, None), foo_printer)
203 f.for_type(C, foo_printer)
204 f.for_type(C, foo_printer)
204 nt.assert_is(f.pop(C), foo_printer)
205 nt.assert_is(f.pop(C), foo_printer)
205 with nt.assert_raises(KeyError):
206 with nt.assert_raises(KeyError):
206 f.lookup_by_type(C)
207 f.lookup_by_type(C)
207 with nt.assert_raises(KeyError):
208 with nt.assert_raises(KeyError):
208 f.pop(C)
209 f.pop(C)
209 with nt.assert_raises(KeyError):
210 with nt.assert_raises(KeyError):
210 f.pop(A)
211 f.pop(A)
211 nt.assert_is(f.pop(A, None), None)
212 nt.assert_is(f.pop(A, None), None)
212
213
213 def test_pop_string():
214 def test_pop_string():
214 f = PlainTextFormatter()
215 f = PlainTextFormatter()
215 type_str = '%s.%s' % (C.__module__, 'C')
216 type_str = '%s.%s' % (C.__module__, 'C')
216
217
217 with nt.assert_raises(KeyError):
218 with nt.assert_raises(KeyError):
218 f.pop(type_str)
219 f.pop(type_str)
219
220
220 f.for_type(type_str, foo_printer)
221 f.for_type(type_str, foo_printer)
221 f.pop(type_str)
222 f.pop(type_str)
222 with nt.assert_raises(KeyError):
223 with nt.assert_raises(KeyError):
223 f.lookup_by_type(C)
224 f.lookup_by_type(C)
224 with nt.assert_raises(KeyError):
225 with nt.assert_raises(KeyError):
225 f.pop(type_str)
226 f.pop(type_str)
226
227
227 f.for_type(C, foo_printer)
228 f.for_type(C, foo_printer)
228 nt.assert_is(f.pop(type_str, None), foo_printer)
229 nt.assert_is(f.pop(type_str, None), foo_printer)
229 with nt.assert_raises(KeyError):
230 with nt.assert_raises(KeyError):
230 f.lookup_by_type(C)
231 f.lookup_by_type(C)
231 with nt.assert_raises(KeyError):
232 with nt.assert_raises(KeyError):
232 f.pop(type_str)
233 f.pop(type_str)
233 nt.assert_is(f.pop(type_str, None), None)
234 nt.assert_is(f.pop(type_str, None), None)
234
235
235
236
236 def test_warn_error_method():
237 def test_warn_error_method():
237 f = HTMLFormatter()
238 f = HTMLFormatter()
238 class BadHTML(object):
239 class BadHTML(object):
239 def _repr_html_(self):
240 def _repr_html_(self):
240 return 1/0
241 return 1/0
241 bad = BadHTML()
242 bad = BadHTML()
242 with capture_output() as captured:
243 with capture_output() as captured:
243 result = f(bad)
244 result = f(bad)
244 nt.assert_is(result, None)
245 nt.assert_is(result, None)
245 nt.assert_in("FormatterWarning", captured.stderr)
246 nt.assert_in("FormatterWarning", captured.stderr)
246 nt.assert_in("text/html", captured.stderr)
247 nt.assert_in("text/html", captured.stderr)
247 nt.assert_in("zero", captured.stderr)
248 nt.assert_in("zero", captured.stderr)
248
249
249 def test_nowarn_notimplemented():
250 def test_nowarn_notimplemented():
250 f = HTMLFormatter()
251 f = HTMLFormatter()
251 class HTMLNotImplemented(object):
252 class HTMLNotImplemented(object):
252 def _repr_html_(self):
253 def _repr_html_(self):
253 raise NotImplementedError
254 raise NotImplementedError
254 return 1/0
255 return 1/0
255 h = HTMLNotImplemented()
256 h = HTMLNotImplemented()
256 with capture_output() as captured:
257 with capture_output() as captured:
257 result = f(h)
258 result = f(h)
258 nt.assert_is(result, None)
259 nt.assert_is(result, None)
259 nt.assert_not_in("FormatterWarning", captured.stderr)
260 nt.assert_not_in("FormatterWarning", captured.stderr)
260
261
261 def test_warn_error_for_type():
262 def test_warn_error_for_type():
262 f = HTMLFormatter()
263 f = HTMLFormatter()
263 f.for_type(int, lambda i: name_error)
264 f.for_type(int, lambda i: name_error)
264 with capture_output() as captured:
265 with capture_output() as captured:
265 result = f(5)
266 result = f(5)
266 nt.assert_is(result, None)
267 nt.assert_is(result, None)
267 nt.assert_in("FormatterWarning", captured.stderr)
268 nt.assert_in("FormatterWarning", captured.stderr)
268 nt.assert_in("text/html", captured.stderr)
269 nt.assert_in("text/html", captured.stderr)
269 nt.assert_in("name_error", captured.stderr)
270 nt.assert_in("name_error", captured.stderr)
270
271
271 def test_warn_error_pretty_method():
272 def test_warn_error_pretty_method():
272 f = PlainTextFormatter()
273 f = PlainTextFormatter()
273 class BadPretty(object):
274 class BadPretty(object):
274 def _repr_pretty_(self):
275 def _repr_pretty_(self):
275 return "hello"
276 return "hello"
276 bad = BadPretty()
277 bad = BadPretty()
277 with capture_output() as captured:
278 with capture_output() as captured:
278 result = f(bad)
279 result = f(bad)
279 nt.assert_is(result, None)
280 nt.assert_is(result, None)
280 nt.assert_in("FormatterWarning", captured.stderr)
281 nt.assert_in("FormatterWarning", captured.stderr)
281 nt.assert_in("text/plain", captured.stderr)
282 nt.assert_in("text/plain", captured.stderr)
282 nt.assert_in("argument", captured.stderr)
283 nt.assert_in("argument", captured.stderr)
283
284
284 class MakePDF(object):
285 class MakePDF(object):
285 def _repr_pdf_(self):
286 def _repr_pdf_(self):
286 return 'PDF'
287 return 'PDF'
287
288
288 def test_pdf_formatter():
289 def test_pdf_formatter():
289 pdf = MakePDF()
290 pdf = MakePDF()
290 f = PDFFormatter()
291 f = PDFFormatter()
291 nt.assert_equal(f(pdf), 'PDF')
292 nt.assert_equal(f(pdf), 'PDF')
293
294 def test_print_method_bound():
295 f = HTMLFormatter()
296 class MyHTML(object):
297 def _repr_html_(self):
298 return "hello"
299
300 with capture_output() as captured:
301 result = f(MyHTML)
302 nt.assert_is(result, None)
303 nt.assert_not_in("FormatterWarning", captured.stderr)
304
305 with capture_output() as captured:
306 result = f(MyHTML())
307 nt.assert_equal(result, "hello")
308 nt.assert_equal(captured.stderr, "")
309
310 def test_format_config():
311 """config objects don't pretend to support fancy reprs with lazy attrs"""
312 f = HTMLFormatter()
313 cfg = Config()
314 with capture_output() as captured:
315 result = f(cfg)
316 nt.assert_is(result, None)
317 nt.assert_equal(captured.stderr, "")
318
319 with capture_output() as captured:
320 result = f(Config)
321 nt.assert_is(result, None)
322 nt.assert_equal(captured.stderr, "")
General Comments 0
You need to be logged in to leave comments. Login now