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