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