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