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