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