Show More
@@ -1,6 +1,61 b'' | |||
|
1 | 1 | # -*- coding: utf-8 -*- |
|
2 | 2 | """Display formatters. |
|
3 | 3 | |
|
4 | This module defines the base instances in order to implement custom | |
|
5 | formatters/mimetypes | |
|
6 | got objects: | |
|
7 | ||
|
8 | As we want to see internal IPython working we are going to use the following | |
|
9 | function to diaply objects instead of the normal print or display method: | |
|
10 | ||
|
11 | >>> ip = get_ipython() | |
|
12 | >>> ip.display_formatter.format(...) | |
|
13 | ({'text/plain': 'Ellipsis'}, {}) | |
|
14 | ||
|
15 | This return a tuple with the mimebumdle for the current object, and the | |
|
16 | associated metadata. | |
|
17 | ||
|
18 | ||
|
19 | We can now define our own formatter and register it: | |
|
20 | ||
|
21 | ||
|
22 | >>> from IPython.core.formatters import BaseFormatter, FormatterABC | |
|
23 | ||
|
24 | ||
|
25 | >>> class LLMFormatter(BaseFormatter): | |
|
26 | ... | |
|
27 | ... format_type = 'x-vendor/llm' | |
|
28 | ... print_method = '_repr_llm_' | |
|
29 | ... _return_type = (dict, str) | |
|
30 | ||
|
31 | >>> llm_formatter = LLMFormatter(parent=ip.display_formatter) | |
|
32 | ||
|
33 | >>> ip.display_formatter.formatters[LLMFormatter.format_type] = llm_formatter | |
|
34 | ||
|
35 | Now any class that define `_repr_llm_` will return a x-vendor/llm as part of | |
|
36 | it's display data: | |
|
37 | ||
|
38 | >>> class A: | |
|
39 | ... | |
|
40 | ... def _repr_llm_(self, *kwargs): | |
|
41 | ... return 'This a A' | |
|
42 | ... | |
|
43 | ||
|
44 | >>> ip.display_formatter.format(A()) | |
|
45 | ({'text/plain': '<IPython.core.formatters.A at ...>', 'x-vendor/llm': 'This a A'}, {}) | |
|
46 | ||
|
47 | As usual, you can register methods for third party types (see | |
|
48 | :ref:`third_party_formatting`) | |
|
49 | ||
|
50 | >>> def llm_int(obj): | |
|
51 | ... return 'This is the integer %s, in between %s and %s'%(obj, obj-1, obj+1) | |
|
52 | ||
|
53 | >>> llm_formatter.for_type(int, llm_int) | |
|
54 | ||
|
55 | >>> ip.display_formatter.format(42) | |
|
56 | ({'text/plain': '42', 'x-vendor/llm': 'This is the integer 42, in between 41 and 43'}, {}) | |
|
57 | ||
|
58 | ||
|
4 | 59 | Inheritance diagram: |
|
5 | 60 | |
|
6 | 61 | .. inheritance-diagram:: IPython.core.formatters |
@@ -37,9 +92,10 b' class DisplayFormatter(Configurable):' | |||
|
37 | 92 | active_types = List(Unicode(), |
|
38 | 93 | help="""List of currently active mime-types to display. |
|
39 | 94 | You can use this to set a white-list for formats to display. |
|
40 | ||
|
95 | ||
|
41 | 96 | Most users will not need to change this value. |
|
42 | """).tag(config=True) | |
|
97 | """, | |
|
98 | ).tag(config=True) | |
|
43 | 99 | |
|
44 | 100 | @default('active_types') |
|
45 | 101 | def _active_types_default(self): |
@@ -144,7 +200,7 b' class DisplayFormatter(Configurable):' | |||
|
144 | 200 | """ |
|
145 | 201 | format_dict = {} |
|
146 | 202 | md_dict = {} |
|
147 | ||
|
203 | ||
|
148 | 204 | if self.ipython_display_formatter(obj): |
|
149 | 205 | # object handled itself, don't proceed |
|
150 | 206 | return {}, {} |
@@ -176,18 +232,18 b' class DisplayFormatter(Configurable):' | |||
|
176 | 232 | continue |
|
177 | 233 | if exclude and format_type in exclude: |
|
178 | 234 | continue |
|
179 | ||
|
235 | ||
|
180 | 236 | md = None |
|
181 | 237 | try: |
|
182 | 238 | data = formatter(obj) |
|
183 | 239 | except: |
|
184 | 240 | # FIXME: log the exception |
|
185 | 241 | raise |
|
186 | ||
|
242 | ||
|
187 | 243 | # formatters can return raw data or (data, metadata) |
|
188 | 244 | if isinstance(data, tuple) and len(data) == 2: |
|
189 | 245 | data, md = data |
|
190 | ||
|
246 | ||
|
191 | 247 | if data is not None: |
|
192 | 248 | format_dict[format_type] = data |
|
193 | 249 | if md is not None: |
@@ -252,7 +308,7 b' class FormatterABC(metaclass=abc.ABCMeta):' | |||
|
252 | 308 | |
|
253 | 309 | # Is the formatter enabled... |
|
254 | 310 | enabled = True |
|
255 | ||
|
311 | ||
|
256 | 312 | @abc.abstractmethod |
|
257 | 313 | def __call__(self, obj): |
|
258 | 314 | """Return a JSON'able representation of the object. |
@@ -278,12 +334,15 b' def _get_type(obj):' | |||
|
278 | 334 | return getattr(obj, '__class__', None) or type(obj) |
|
279 | 335 | |
|
280 | 336 | |
|
281 |
_raise_key_error = Sentinel( |
|
|
282 | """ | |
|
337 | _raise_key_error = Sentinel( | |
|
338 | "_raise_key_error", | |
|
339 | __name__, | |
|
340 | """ | |
|
283 | 341 | Special value to raise a KeyError |
|
284 | 342 | |
|
285 | 343 | Raise KeyError in `BaseFormatter.pop` if passed as the default value to `pop` |
|
286 |
""" |
|
|
344 | """, | |
|
345 | ) | |
|
287 | 346 | |
|
288 | 347 | |
|
289 | 348 | class BaseFormatter(Configurable): |
@@ -329,7 +388,7 b' class BaseFormatter(Configurable):' | |||
|
329 | 388 | # The deferred-import type-specific printers. |
|
330 | 389 | # Map (modulename, classname) pairs to the format functions. |
|
331 | 390 | deferred_printers = Dict().tag(config=True) |
|
332 | ||
|
391 | ||
|
333 | 392 | @catch_format_error |
|
334 | 393 | def __call__(self, obj): |
|
335 | 394 | """Compute the format for an object.""" |
@@ -348,7 +407,7 b' class BaseFormatter(Configurable):' | |||
|
348 | 407 | return None |
|
349 | 408 | else: |
|
350 | 409 | return None |
|
351 | ||
|
410 | ||
|
352 | 411 | def __contains__(self, typ): |
|
353 | 412 | """map in to lookup_by_type""" |
|
354 | 413 | try: |
@@ -357,7 +416,7 b' class BaseFormatter(Configurable):' | |||
|
357 | 416 | return False |
|
358 | 417 | else: |
|
359 | 418 | return True |
|
360 | ||
|
419 | ||
|
361 | 420 | def _check_return(self, r, obj): |
|
362 | 421 | """Check that a return value is appropriate |
|
363 | 422 | |
@@ -372,7 +431,7 b' class BaseFormatter(Configurable):' | |||
|
372 | 431 | (self.format_type, type(r), self._return_type, _safe_repr(obj)), |
|
373 | 432 | FormatterWarning |
|
374 | 433 | ) |
|
375 | ||
|
434 | ||
|
376 | 435 | def lookup(self, obj): |
|
377 | 436 | """Look up the formatter for a given instance. |
|
378 | 437 | |
@@ -395,7 +454,7 b' class BaseFormatter(Configurable):' | |||
|
395 | 454 | return self.singleton_printers[obj_id] |
|
396 | 455 | # then lookup by type |
|
397 | 456 | return self.lookup_by_type(_get_type(obj)) |
|
398 | ||
|
457 | ||
|
399 | 458 | def lookup_by_type(self, typ): |
|
400 | 459 | """Look up the registered formatter for a type. |
|
401 | 460 | |
@@ -426,7 +485,7 b' class BaseFormatter(Configurable):' | |||
|
426 | 485 | for cls in pretty._get_mro(typ): |
|
427 | 486 | if cls in self.type_printers or self._in_deferred_types(cls): |
|
428 | 487 | return self.type_printers[cls] |
|
429 | ||
|
488 | ||
|
430 | 489 | # If we have reached here, the lookup failed. |
|
431 | 490 | raise KeyError("No registered printer for {0!r}".format(typ)) |
|
432 | 491 | |
@@ -459,15 +518,15 b' class BaseFormatter(Configurable):' | |||
|
459 | 518 | if isinstance(typ, str): |
|
460 | 519 | type_module, type_name = typ.rsplit('.', 1) |
|
461 | 520 | return self.for_type_by_name(type_module, type_name, func) |
|
462 | ||
|
521 | ||
|
463 | 522 | try: |
|
464 | 523 | oldfunc = self.lookup_by_type(typ) |
|
465 | 524 | except KeyError: |
|
466 | 525 | oldfunc = None |
|
467 | ||
|
526 | ||
|
468 | 527 | if func is not None: |
|
469 | 528 | self.type_printers[typ] = func |
|
470 | ||
|
529 | ||
|
471 | 530 | return oldfunc |
|
472 | 531 | |
|
473 | 532 | def for_type_by_name(self, type_module, type_name, func=None): |
@@ -501,16 +560,16 b' class BaseFormatter(Configurable):' | |||
|
501 | 560 | this will be the previous value (to enable restoring later). |
|
502 | 561 | """ |
|
503 | 562 | key = (type_module, type_name) |
|
504 | ||
|
563 | ||
|
505 | 564 | try: |
|
506 | 565 | oldfunc = self.lookup_by_type("%s.%s" % key) |
|
507 | 566 | except KeyError: |
|
508 | 567 | oldfunc = None |
|
509 | ||
|
568 | ||
|
510 | 569 | if func is not None: |
|
511 | 570 | self.deferred_printers[key] = func |
|
512 | 571 | return oldfunc |
|
513 | ||
|
572 | ||
|
514 | 573 | def pop(self, typ, default=_raise_key_error): |
|
515 | 574 | """Pop a formatter for the given type. |
|
516 | 575 | |
@@ -529,7 +588,7 b' class BaseFormatter(Configurable):' | |||
|
529 | 588 | ------ |
|
530 | 589 | KeyError if the type is not registered and default is not specified. |
|
531 | 590 | """ |
|
532 | ||
|
591 | ||
|
533 | 592 | if isinstance(typ, str): |
|
534 | 593 | typ_key = tuple(typ.rsplit('.',1)) |
|
535 | 594 | if typ_key not in self.deferred_printers: |
@@ -599,14 +658,14 b' class PlainTextFormatter(BaseFormatter):' | |||
|
599 | 658 | # This subclass ignores this attribute as it always need to return |
|
600 | 659 | # something. |
|
601 | 660 | enabled = Bool(True).tag(config=False) |
|
602 | ||
|
661 | ||
|
603 | 662 | max_seq_length = Integer(pretty.MAX_SEQ_LENGTH, |
|
604 | 663 | help="""Truncate large collections (lists, dicts, tuples, sets) to this size. |
|
605 | ||
|
664 | ||
|
606 | 665 | Set to 0 to disable truncation. |
|
607 | """ | |
|
666 | """, | |
|
608 | 667 | ).tag(config=True) |
|
609 | ||
|
668 | ||
|
610 | 669 | # Look for a _repr_pretty_ methods to use for pretty printing. |
|
611 | 670 | print_method = ObjectName('_repr_pretty_') |
|
612 | 671 | |
@@ -775,7 +834,7 b' class PNGFormatter(BaseFormatter):' | |||
|
775 | 834 | format_type = Unicode('image/png') |
|
776 | 835 | |
|
777 | 836 | print_method = ObjectName('_repr_png_') |
|
778 | ||
|
837 | ||
|
779 | 838 | _return_type = (bytes, str) |
|
780 | 839 | |
|
781 | 840 | |
@@ -829,7 +888,7 b' class JSONFormatter(BaseFormatter):' | |||
|
829 | 888 | _return_type = (list, dict) |
|
830 | 889 | |
|
831 | 890 | print_method = ObjectName('_repr_json_') |
|
832 | ||
|
891 | ||
|
833 | 892 | def _check_return(self, r, obj): |
|
834 | 893 | """Check that a return value is appropriate |
|
835 | 894 | |
@@ -887,19 +946,19 b' class PDFFormatter(BaseFormatter):' | |||
|
887 | 946 | |
|
888 | 947 | class IPythonDisplayFormatter(BaseFormatter): |
|
889 | 948 | """An escape-hatch Formatter for objects that know how to display themselves. |
|
890 | ||
|
949 | ||
|
891 | 950 | To define the callables that compute the representation of your |
|
892 | 951 | objects, define a :meth:`_ipython_display_` method or use the :meth:`for_type` |
|
893 | 952 | or :meth:`for_type_by_name` methods to register functions that handle |
|
894 | 953 | this. Unlike mime-type displays, this method should not return anything, |
|
895 | 954 | instead calling any appropriate display methods itself. |
|
896 | ||
|
955 | ||
|
897 | 956 | This display formatter has highest priority. |
|
898 | 957 | If it fires, no other display formatter will be called. |
|
899 | 958 | |
|
900 | 959 | Prior to IPython 6.1, `_ipython_display_` was the only way to display custom mime-types |
|
901 | 960 | without registering a new Formatter. |
|
902 | ||
|
961 | ||
|
903 | 962 | IPython 6.1 introduces `_repr_mimebundle_` for displaying custom mime-types, |
|
904 | 963 | so `_ipython_display_` should only be used for objects that require unusual |
|
905 | 964 | display patterns, such as multiple display calls. |
@@ -943,7 +1002,7 b' class MimeBundleFormatter(BaseFormatter):' | |||
|
943 | 1002 | """ |
|
944 | 1003 | print_method = ObjectName('_repr_mimebundle_') |
|
945 | 1004 | _return_type = dict |
|
946 | ||
|
1005 | ||
|
947 | 1006 | def _check_return(self, r, obj): |
|
948 | 1007 | r = super(MimeBundleFormatter, self)._check_return(r, obj) |
|
949 | 1008 | # always return (data, metadata): |
@@ -9,7 +9,7 b' Tab completion' | |||
|
9 | 9 | |
|
10 | 10 | To change the attributes displayed by tab-completing your object, define a |
|
11 | 11 | ``__dir__(self)`` method for it. For more details, see the documentation of the |
|
12 | built-in `dir() function <http://docs.python.org/library/functions.html#dir>`_. | |
|
12 | built-in :external+python:py:func:`dir` | |
|
13 | 13 | |
|
14 | 14 | You can also customise key completions for your objects, e.g. pressing tab after |
|
15 | 15 | ``obj["a``. To do so, define a method ``_ipython_key_completions_()``, which |
@@ -25,7 +25,7 b' Rich display' | |||
|
25 | 25 | ============ |
|
26 | 26 | |
|
27 | 27 | Custom methods |
|
28 |
-------------- |
|
|
28 | -------------- | |
|
29 | 29 | |
|
30 | 30 | IPython can display richer representations of objects. |
|
31 | 31 | To do this, you can define ``_ipython_display_()``, or any of a number of |
@@ -154,6 +154,8 b' to inform the frontend how to size the image.' | |||
|
154 | 154 | |
|
155 | 155 | |
|
156 | 156 | |
|
157 | .. _third_party_formatting: | |
|
158 | ||
|
157 | 159 | Formatters for third-party types |
|
158 | 160 | -------------------------------- |
|
159 | 161 |
General Comments 0
You need to be logged in to leave comments.
Login now