Show More
@@ -53,12 +53,17 b' class DisplayFormatter(Configurable):' | |||||
53 | formatter.enabled = True |
|
53 | formatter.enabled = True | |
54 | else: |
|
54 | else: | |
55 | formatter.enabled = False |
|
55 | formatter.enabled = False | |
56 |
|
56 | |||
57 | ipython_display_formatter = ForwardDeclaredInstance('FormatterABC') |
|
57 | ipython_display_formatter = ForwardDeclaredInstance('FormatterABC') | |
58 | @default('ipython_display_formatter') |
|
58 | @default('ipython_display_formatter') | |
59 | def _default_formatter(self): |
|
59 | def _default_formatter(self): | |
60 | return IPythonDisplayFormatter(parent=self) |
|
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 | # A dict of formatter whose keys are format types (MIME types) and whose |
|
67 | # A dict of formatter whose keys are format types (MIME types) and whose | |
63 | # values are subclasses of BaseFormatter. |
|
68 | # values are subclasses of BaseFormatter. | |
64 | formatters = Dict() |
|
69 | formatters = Dict() | |
@@ -133,8 +138,13 b' class DisplayFormatter(Configurable):' | |||||
133 | if self.ipython_display_formatter(obj): |
|
138 | if self.ipython_display_formatter(obj): | |
134 | # object handled itself, don't proceed |
|
139 | # object handled itself, don't proceed | |
135 | return {}, {} |
|
140 | return {}, {} | |
136 |
|
141 | |||
|
142 | format_dict, md_dict = self.mimebundle_formatter(obj) | |||
|
143 | ||||
137 | for format_type, formatter in self.formatters.items(): |
|
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 | if include and format_type not in include: |
|
148 | if include and format_type not in include: | |
139 | continue |
|
149 | continue | |
140 | if exclude and format_type in exclude: |
|
150 | if exclude and format_type in exclude: | |
@@ -849,7 +859,7 b' class PDFFormatter(BaseFormatter):' | |||||
849 | _return_type = (bytes, unicode_type) |
|
859 | _return_type = (bytes, unicode_type) | |
850 |
|
860 | |||
851 | class IPythonDisplayFormatter(BaseFormatter): |
|
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 | To define the callables that compute the representation of your |
|
864 | To define the callables that compute the representation of your | |
855 | objects, define a :meth:`_ipython_display_` method or use the :meth:`for_type` |
|
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 | This display formatter has highest priority. |
|
870 | This display formatter has highest priority. | |
861 | If it fires, no other display formatter will be called. |
|
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 | print_method = ObjectName('_ipython_display_') |
|
880 | print_method = ObjectName('_ipython_display_') | |
864 | _return_type = (type(None), bool) |
|
881 | _return_type = (type(None), bool) | |
865 |
|
||||
866 |
|
882 | |||
867 | @catch_format_error |
|
883 | @catch_format_error | |
868 | def __call__(self, obj): |
|
884 | def __call__(self, obj): | |
@@ -883,6 +899,34 b' class IPythonDisplayFormatter(BaseFormatter):' | |||||
883 | return True |
|
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 | FormatterABC.register(BaseFormatter) |
|
930 | FormatterABC.register(BaseFormatter) | |
887 | FormatterABC.register(PlainTextFormatter) |
|
931 | FormatterABC.register(PlainTextFormatter) | |
888 | FormatterABC.register(HTMLFormatter) |
|
932 | FormatterABC.register(HTMLFormatter) | |
@@ -895,6 +939,7 b' FormatterABC.register(LatexFormatter)' | |||||
895 | FormatterABC.register(JSONFormatter) |
|
939 | FormatterABC.register(JSONFormatter) | |
896 | FormatterABC.register(JavascriptFormatter) |
|
940 | FormatterABC.register(JavascriptFormatter) | |
897 | FormatterABC.register(IPythonDisplayFormatter) |
|
941 | FormatterABC.register(IPythonDisplayFormatter) | |
|
942 | FormatterABC.register(MimeBundleFormatter) | |||
898 |
|
943 | |||
899 |
|
944 | |||
900 | def format_display_data(obj, include=None, exclude=None): |
|
945 | def format_display_data(obj, include=None, exclude=None): |
@@ -436,4 +436,55 b' def test_json_as_string_deprecated():' | |||||
436 | d = f(JSONString()) |
|
436 | d = f(JSONString()) | |
437 | nt.assert_equal(d, {}) |
|
437 | nt.assert_equal(d, {}) | |
438 | nt.assert_equal(len(w), 1) |
|
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