Show More
@@ -164,20 +164,13 b' def display(*objs, **kwargs):' | |||||
164 | format = InteractiveShell.instance().display_formatter.format |
|
164 | format = InteractiveShell.instance().display_formatter.format | |
165 |
|
165 | |||
166 | for obj in objs: |
|
166 | for obj in objs: | |
167 |
|
||||
168 | # If _ipython_display_ is defined, use that to display this object. |
|
|||
169 | display_method = _safe_get_formatter_method(obj, '_ipython_display_') |
|
|||
170 | if display_method is not None: |
|
|||
171 | try: |
|
|||
172 | display_method(**kwargs) |
|
|||
173 | except NotImplementedError: |
|
|||
174 | pass |
|
|||
175 | else: |
|
|||
176 | continue |
|
|||
177 | if raw: |
|
167 | if raw: | |
178 | publish_display_data(data=obj, metadata=metadata) |
|
168 | publish_display_data(data=obj, metadata=metadata) | |
179 | else: |
|
169 | else: | |
180 | format_dict, md_dict = format(obj, include=include, exclude=exclude) |
|
170 | format_dict, md_dict = format(obj, include=include, exclude=exclude) | |
|
171 | if not format_dict: | |||
|
172 | # nothing to display (e.g. _ipython_display_ took over) | |||
|
173 | continue | |||
181 | if metadata: |
|
174 | if metadata: | |
182 | # kwarg-specified metadata gets precedence |
|
175 | # kwarg-specified metadata gets precedence | |
183 | _merge(md_dict, metadata) |
|
176 | _merge(md_dict, metadata) |
@@ -221,19 +221,12 b' class DisplayHook(Configurable):' | |||||
221 | """ |
|
221 | """ | |
222 | self.check_for_underscore() |
|
222 | self.check_for_underscore() | |
223 | if result is not None and not self.quiet(): |
|
223 | if result is not None and not self.quiet(): | |
224 | # If _ipython_display_ is defined, use that to display this object. |
|
|||
225 | display_method = _safe_get_formatter_method(result, '_ipython_display_') |
|
|||
226 | if display_method is not None: |
|
|||
227 | try: |
|
|||
228 | return display_method() |
|
|||
229 | except NotImplementedError: |
|
|||
230 | pass |
|
|||
231 |
|
||||
232 | self.start_displayhook() |
|
224 | self.start_displayhook() | |
233 | self.write_output_prompt() |
|
225 | self.write_output_prompt() | |
234 | format_dict, md_dict = self.compute_format_data(result) |
|
226 | format_dict, md_dict = self.compute_format_data(result) | |
235 | self.write_format_data(format_dict, md_dict) |
|
|||
236 | self.update_user_ns(result) |
|
227 | self.update_user_ns(result) | |
|
228 | if format_dict: | |||
|
229 | self.write_format_data(format_dict, md_dict) | |||
237 | self.log_output(format_dict) |
|
230 | self.log_output(format_dict) | |
238 | self.finish_displayhook() |
|
231 | self.finish_displayhook() | |
239 |
|
232 |
@@ -14,7 +14,6 b' import abc' | |||||
14 | import inspect |
|
14 | import inspect | |
15 | import sys |
|
15 | import sys | |
16 | import traceback |
|
16 | import traceback | |
17 | import types |
|
|||
18 | import warnings |
|
17 | import warnings | |
19 |
|
18 | |||
20 | from IPython.external.decorator import decorator |
|
19 | from IPython.external.decorator import decorator | |
@@ -24,6 +23,7 b' from IPython.core.getipython import get_ipython' | |||||
24 | from IPython.lib import pretty |
|
23 | from IPython.lib import pretty | |
25 | from IPython.utils.traitlets import ( |
|
24 | from IPython.utils.traitlets import ( | |
26 | Bool, Dict, Integer, Unicode, CUnicode, ObjectName, List, |
|
25 | Bool, Dict, Integer, Unicode, CUnicode, ObjectName, List, | |
|
26 | ForwardDeclaredInstance, | |||
27 | ) |
|
27 | ) | |
28 | from IPython.utils.py3compat import ( |
|
28 | from IPython.utils.py3compat import ( | |
29 | unicode_to_str, with_metaclass, PY3, string_types, unicode_type, |
|
29 | unicode_to_str, with_metaclass, PY3, string_types, unicode_type, | |
@@ -89,6 +89,10 b' class DisplayFormatter(Configurable):' | |||||
89 | else: |
|
89 | else: | |
90 | formatter.enabled = False |
|
90 | formatter.enabled = False | |
91 |
|
91 | |||
|
92 | ipython_display_formatter = ForwardDeclaredInstance('FormatterABC') | |||
|
93 | def _ipython_display_formatter_default(self): | |||
|
94 | return IPythonDisplayFormatter(parent=self) | |||
|
95 | ||||
92 | # A dict of formatter whose keys are format types (MIME types) and whose |
|
96 | # A dict of formatter whose keys are format types (MIME types) and whose | |
93 | # values are subclasses of BaseFormatter. |
|
97 | # values are subclasses of BaseFormatter. | |
94 | formatters = Dict() |
|
98 | formatters = Dict() | |
@@ -159,6 +163,10 b' class DisplayFormatter(Configurable):' | |||||
159 | format_dict = {} |
|
163 | format_dict = {} | |
160 | md_dict = {} |
|
164 | md_dict = {} | |
161 |
|
165 | |||
|
166 | if self.ipython_display_formatter(obj): | |||
|
167 | # object handled itself, don't proceed | |||
|
168 | return {}, {} | |||
|
169 | ||||
162 | for format_type, formatter in self.formatters.items(): |
|
170 | for format_type, formatter in self.formatters.items(): | |
163 | if include and format_type not in include: |
|
171 | if include and format_type not in include: | |
164 | continue |
|
172 | continue | |
@@ -831,6 +839,40 b' class PDFFormatter(BaseFormatter):' | |||||
831 |
|
839 | |||
832 | _return_type = (bytes, unicode_type) |
|
840 | _return_type = (bytes, unicode_type) | |
833 |
|
841 | |||
|
842 | class IPythonDisplayFormatter(BaseFormatter): | |||
|
843 | """A Formatter for objects that know how to display themselves. | |||
|
844 | ||||
|
845 | To define the callables that compute the representation of your | |||
|
846 | objects, define a :meth:`_ipython_display_` method or use the :meth:`for_type` | |||
|
847 | or :meth:`for_type_by_name` methods to register functions that handle | |||
|
848 | this. Unlike mime-type displays, this method should not return anything, | |||
|
849 | instead calling any appropriate display methods itself. | |||
|
850 | ||||
|
851 | This display formatter has highest priority. | |||
|
852 | If it fires, no other display formatter will be called. | |||
|
853 | """ | |||
|
854 | print_method = ObjectName('_ipython_display_') | |||
|
855 | _return_type = (type(None), bool) | |||
|
856 | ||||
|
857 | ||||
|
858 | @warn_format_error | |||
|
859 | def __call__(self, obj): | |||
|
860 | """Compute the format for an object.""" | |||
|
861 | if self.enabled: | |||
|
862 | # lookup registered printer | |||
|
863 | try: | |||
|
864 | printer = self.lookup(obj) | |||
|
865 | except KeyError: | |||
|
866 | pass | |||
|
867 | else: | |||
|
868 | printer(obj) | |||
|
869 | return True | |||
|
870 | # Finally look for special method names | |||
|
871 | method = _safe_get_formatter_method(obj, self.print_method) | |||
|
872 | if method is not None: | |||
|
873 | method() | |||
|
874 | return True | |||
|
875 | ||||
834 |
|
876 | |||
835 | FormatterABC.register(BaseFormatter) |
|
877 | FormatterABC.register(BaseFormatter) | |
836 | FormatterABC.register(PlainTextFormatter) |
|
878 | FormatterABC.register(PlainTextFormatter) | |
@@ -843,6 +885,7 b' FormatterABC.register(JPEGFormatter)' | |||||
843 | FormatterABC.register(LatexFormatter) |
|
885 | FormatterABC.register(LatexFormatter) | |
844 | FormatterABC.register(JSONFormatter) |
|
886 | FormatterABC.register(JSONFormatter) | |
845 | FormatterABC.register(JavascriptFormatter) |
|
887 | FormatterABC.register(JavascriptFormatter) | |
|
888 | FormatterABC.register(IPythonDisplayFormatter) | |||
846 |
|
889 | |||
847 |
|
890 | |||
848 | def format_display_data(obj, include=None, exclude=None): |
|
891 | def format_display_data(obj, include=None, exclude=None): |
@@ -10,7 +10,8 b' import nose.tools as nt' | |||||
10 |
|
10 | |||
11 | from IPython.config import Config |
|
11 | from IPython.config import Config | |
12 | from IPython.core.formatters import ( |
|
12 | from IPython.core.formatters import ( | |
13 | PlainTextFormatter, HTMLFormatter, PDFFormatter, _mod_name_key |
|
13 | PlainTextFormatter, HTMLFormatter, PDFFormatter, _mod_name_key, | |
|
14 | DisplayFormatter, | |||
14 | ) |
|
15 | ) | |
15 | from IPython.utils.io import capture_output |
|
16 | from IPython.utils.io import capture_output | |
16 |
|
17 | |||
@@ -387,3 +388,33 b' def test_pretty_max_seq_length():' | |||||
387 | text = f(list(range(1024))) |
|
388 | text = f(list(range(1024))) | |
388 | lines = text.splitlines() |
|
389 | lines = text.splitlines() | |
389 | nt.assert_equal(len(lines), 1024) |
|
390 | nt.assert_equal(len(lines), 1024) | |
|
391 | ||||
|
392 | ||||
|
393 | def test_ipython_display_formatter(): | |||
|
394 | """Objects with _ipython_display_ defined bypass other formatters""" | |||
|
395 | f = get_ipython().display_formatter | |||
|
396 | catcher = [] | |||
|
397 | class SelfDisplaying(object): | |||
|
398 | def _ipython_display_(self): | |||
|
399 | catcher.append(self) | |||
|
400 | ||||
|
401 | class NotSelfDisplaying(object): | |||
|
402 | def __repr__(self): | |||
|
403 | return "NotSelfDisplaying" | |||
|
404 | ||||
|
405 | def _ipython_display_(self): | |||
|
406 | raise NotImplementedError | |||
|
407 | ||||
|
408 | yes = SelfDisplaying() | |||
|
409 | no = NotSelfDisplaying() | |||
|
410 | ||||
|
411 | d, md = f.format(no) | |||
|
412 | nt.assert_equal(d, {'text/plain': repr(no)}) | |||
|
413 | nt.assert_equal(md, {}) | |||
|
414 | nt.assert_equal(catcher, []) | |||
|
415 | ||||
|
416 | d, md = f.format(yes) | |||
|
417 | nt.assert_equal(d, {}) | |||
|
418 | nt.assert_equal(md, {}) | |||
|
419 | nt.assert_equal(catcher, [yes]) | |||
|
420 |
General Comments 0
You need to be logged in to leave comments.
Login now