##// END OF EJS Templates
Backport PR #10496: Define `_repr_mimebundle_`...
Matthias Bussonnier -
Show More
@@ -53,12 +53,17 b' class DisplayFormatter(Configurable):'
53 53 formatter.enabled = True
54 54 else:
55 55 formatter.enabled = False
56
56
57 57 ipython_display_formatter = ForwardDeclaredInstance('FormatterABC')
58 58 @default('ipython_display_formatter')
59 59 def _default_formatter(self):
60 60 return IPythonDisplayFormatter(parent=self)
61
61
62 mimebundle_formatter = ForwardDeclaredInstance('FormatterABC')
63 @default('mimebundle_formatter')
64 def _default_mime_formatter(self):
65 return MimeBundleFormatter(parent=self)
66
62 67 # A dict of formatter whose keys are format types (MIME types) and whose
63 68 # values are subclasses of BaseFormatter.
64 69 formatters = Dict()
@@ -133,8 +138,13 b' class DisplayFormatter(Configurable):'
133 138 if self.ipython_display_formatter(obj):
134 139 # object handled itself, don't proceed
135 140 return {}, {}
136
141
142 format_dict, md_dict = self.mimebundle_formatter(obj)
143
137 144 for format_type, formatter in self.formatters.items():
145 if format_type in format_dict:
146 # already got it from mimebundle, don't render again
147 continue
138 148 if include and format_type not in include:
139 149 continue
140 150 if exclude and format_type in exclude:
@@ -849,7 +859,7 b' class PDFFormatter(BaseFormatter):'
849 859 _return_type = (bytes, unicode_type)
850 860
851 861 class IPythonDisplayFormatter(BaseFormatter):
852 """A Formatter for objects that know how to display themselves.
862 """An escape-hatch Formatter for objects that know how to display themselves.
853 863
854 864 To define the callables that compute the representation of your
855 865 objects, define a :meth:`_ipython_display_` method or use the :meth:`for_type`
@@ -859,10 +869,16 b' class IPythonDisplayFormatter(BaseFormatter):'
859 869
860 870 This display formatter has highest priority.
861 871 If it fires, no other display formatter will be called.
872
873 Prior to IPython 6.1, `_ipython_display_` was the only way to display custom mime-types
874 without registering a new Formatter.
875
876 IPython 6.1 introduces `_repr_mimebundle_` for displaying custom mime-types,
877 so `_ipython_display_` should only be used for objects that require unusual
878 display patterns, such as multiple display calls.
862 879 """
863 880 print_method = ObjectName('_ipython_display_')
864 881 _return_type = (type(None), bool)
865
866 882
867 883 @catch_format_error
868 884 def __call__(self, obj):
@@ -883,6 +899,34 b' class IPythonDisplayFormatter(BaseFormatter):'
883 899 return True
884 900
885 901
902 class MimeBundleFormatter(BaseFormatter):
903 """A Formatter for arbitrary mime-types.
904
905 Unlike other `_repr_<mimetype>_` methods,
906 `_repr_mimebundle_` should return mime-bundle data,
907 either the mime-keyed `data` dictionary or the tuple `(data, metadata)`.
908 Any mime-type is valid.
909
910 To define the callables that compute the mime-bundle representation of your
911 objects, define a :meth:`_repr_mimebundle_` method or use the :meth:`for_type`
912 or :meth:`for_type_by_name` methods to register functions that handle
913 this.
914
915 .. versionadded:: 6.1
916 """
917 print_method = ObjectName('_repr_mimebundle_')
918 _return_type = dict
919
920 def _check_return(self, r, obj):
921 r = super(MimeBundleFormatter, self)._check_return(r, obj)
922 # always return (data, metadata):
923 if r is None:
924 return {}, {}
925 if not isinstance(r, tuple):
926 return r, {}
927 return r
928
929
886 930 FormatterABC.register(BaseFormatter)
887 931 FormatterABC.register(PlainTextFormatter)
888 932 FormatterABC.register(HTMLFormatter)
@@ -895,6 +939,7 b' FormatterABC.register(LatexFormatter)'
895 939 FormatterABC.register(JSONFormatter)
896 940 FormatterABC.register(JavascriptFormatter)
897 941 FormatterABC.register(IPythonDisplayFormatter)
942 FormatterABC.register(MimeBundleFormatter)
898 943
899 944
900 945 def format_display_data(obj, include=None, exclude=None):
@@ -436,4 +436,55 b' def test_json_as_string_deprecated():'
436 436 d = f(JSONString())
437 437 nt.assert_equal(d, {})
438 438 nt.assert_equal(len(w), 1)
439 No newline at end of file
439
440
441 def test_repr_mime():
442 class HasReprMime(object):
443 def _repr_mimebundle_(self):
444 return {
445 'application/json+test.v2': {
446 'x': 'y'
447 }
448 }
449
450 def _repr_html_(self):
451 return '<b>hi!</b>'
452
453 f = get_ipython().display_formatter
454 html_f = f.formatters['text/html']
455 save_enabled = html_f.enabled
456 html_f.enabled = True
457 obj = HasReprMime()
458 d, md = f.format(obj)
459 html_f.enabled = save_enabled
460
461 nt.assert_equal(sorted(d), ['application/json+test.v2', 'text/html', 'text/plain'])
462 nt.assert_equal(md, {})
463
464
465 def test_repr_mime_meta():
466 class HasReprMimeMeta(object):
467 def _repr_mimebundle_(self):
468 data = {
469 'image/png': 'base64-image-data',
470 }
471 metadata = {
472 'image/png': {
473 'width': 5,
474 'height': 10,
475 }
476 }
477 return (data, metadata)
478
479 f = get_ipython().display_formatter
480 obj = HasReprMimeMeta()
481 d, md = f.format(obj)
482 nt.assert_equal(sorted(d), ['image/png', 'text/plain'])
483 nt.assert_equal(md, {
484 'image/png': {
485 'width': 5,
486 'height': 10,
487 }
488 })
489
490
General Comments 0
You need to be logged in to leave comments. Login now