##// END OF EJS Templates
Display system is fully working now....
Brian Granger -
Show More
@@ -0,0 +1,106 b''
1 # -*- coding: utf-8 -*-
2 """Top-level display functions for displaying object in different formats.
3
4 Authors:
5
6 * Brian Granger
7 """
8
9 #-----------------------------------------------------------------------------
10 # Copyright (C) 2008-2010 The IPython Development Team
11 #
12 # Distributed under the terms of the BSD License. The full license is in
13 # the file COPYING, distributed as part of this software.
14 #-----------------------------------------------------------------------------
15
16 #-----------------------------------------------------------------------------
17 # Imports
18 #-----------------------------------------------------------------------------
19
20 #-----------------------------------------------------------------------------
21 # Main functions
22 #-----------------------------------------------------------------------------
23
24 def display(obj, include=None, exclude=None):
25 """Display a Python object in all frontends.
26
27 By default all representations will be computed and sent to the frontends.
28 Frontends can decide which representation is used and how.
29
30 Parameters
31 ----------
32 obj : object
33 The Python object to display.
34 include : list or tuple, optional
35 A list of format type strings (MIME types) to include in the
36 format data dict. If this is set *only* the format types included
37 in this list will be computed.
38 exclude : list or tuple, optional
39 A list of format type string (MIME types) to exclue in the format
40 data dict. If this is set all format types will be computed,
41 except for those included in this argument.
42 """
43 from IPython.core.interactiveshell import InteractiveShell
44 format = InteractiveShell.instance().display_formatter.format
45 publish = InteractiveShell.instance().display_pub.publish
46
47 format_dict = format(obj, include=include, exclude=exclude)
48 publish('IPython.core.display.display', format_dict)
49
50
51 def display_html(obj):
52 """Display the HTML representation of an object.
53
54 Parameters
55 ----------
56 obj : object
57 The Python object to display.
58 """
59 display(obj, include=['text/plain','text/html'])
60
61
62 def display_svg(obj):
63 """Display the SVG representation of an object.
64
65 Parameters
66 ----------
67 obj : object
68 The Python object to display.
69 """
70 display(obj, include=['text/plain','image/svg+xml'])
71
72
73 def display_png(obj):
74 """Display the PNG representation of an object.
75
76 Parameters
77 ----------
78 obj : object
79 The Python object to display.
80 """
81 display(obj, include=['text/plain','image/png'])
82
83
84 def display_latex(obj):
85 """Display the LaTeX representation of an object.
86
87 Parameters
88 ----------
89 obj : object
90 The Python object to display.
91 """
92 display(obj, include=['text/plain','text/latex'])
93
94
95 def display_json(obj):
96 """Display the JSON representation of an object.
97
98 Parameters
99 ----------
100 obj : object
101 The Python object to display.
102 """
103 display(obj, include=['text/plain','application/json'])
104
105
106
@@ -0,0 +1,45 b''
1 """A print function that pretty prints sympy Basic objects.
2
3 Authors:
4 * Brian Granger
5 """
6 #-----------------------------------------------------------------------------
7 # Copyright (C) 2008-2011 The IPython Development Team
8 #
9 # Distributed under the terms of the BSD License. The full license is in
10 # the file COPYING, distributed as part of this software.
11 #-----------------------------------------------------------------------------
12
13 #-----------------------------------------------------------------------------
14 # Imports
15 #-----------------------------------------------------------------------------
16
17 from sympy import pretty
18
19 #-----------------------------------------------------------------------------
20 # Definitions of magic functions for use with IPython
21 #-----------------------------------------------------------------------------
22
23 def print_basic_unicode(o, p, cycle):
24 """A function to pretty print sympy Basic objects."""
25 if cycle:
26 return p.text('Basic(...)')
27 out = pretty(o, use_unicode=True)
28 if '\n' in out:
29 p.text(u'\n')
30 p.text(out)
31
32
33 _loaded = False
34
35
36 def load_ipython_extension(ip):
37 """Load the extension in IPython."""
38 global _loaded
39 if not _loaded:
40 plaintext_formatter = ip.display_formatter.formatters['text/plain']
41 plaintext_formatter.for_type_by_name(
42 'sympy.core.basic', 'Basic', print_basic_unicode
43 )
44 _loaded = True
45
@@ -15,7 +15,14 b" f, g, h = map(Function, 'fgh')"
15 # You have to make sure that attributes that are containers already
15 # You have to make sure that attributes that are containers already
16 # exist before using them. Simple assigning a new list will override
16 # exist before using them. Simple assigning a new list will override
17 # all previous values.
17 # all previous values.
18
18 if hasattr(c.Global, 'exec_lines'):
19 if hasattr(c.Global, 'exec_lines'):
19 c.Global.exec_lines.append(lines)
20 c.Global.exec_lines.append(lines)
20 else:
21 else:
21 c.Global.exec_lines = [lines]
22 c.Global.exec_lines = [lines]
23
24 if hasattr(c.Global, 'extensions'):
25 c.Global.extensions.append('IPython.extensions.sympy_printing')
26 else:
27 c.Global.extensions = ['IPython.extensions.sympy_printing']
28
@@ -1,10 +1,13 b''
1 # -*- coding: utf-8 -*-
1 # -*- coding: utf-8 -*-
2 """Displayhook for IPython.
2 """Displayhook for IPython.
3
3
4 This defines a callable class that IPython uses for `sys.displayhook`.
5
4 Authors:
6 Authors:
5
7
6 * Fernando Perez
8 * Fernando Perez
7 * Brian Granger
9 * Brian Granger
10 * Robert Kern
8 """
11 """
9
12
10 #-----------------------------------------------------------------------------
13 #-----------------------------------------------------------------------------
@@ -27,7 +30,6 b' import IPython.utils.generics'
27 import IPython.utils.io
30 import IPython.utils.io
28 from IPython.utils.traitlets import Instance, List
31 from IPython.utils.traitlets import Instance, List
29 from IPython.utils.warn import warn
32 from IPython.utils.warn import warn
30 from IPython.core.formatters import DefaultFormatter
31
33
32 #-----------------------------------------------------------------------------
34 #-----------------------------------------------------------------------------
33 # Main displayhook class
35 # Main displayhook class
@@ -54,19 +56,6 b' class DisplayHook(Configurable):'
54
56
55 shell = Instance('IPython.core.interactiveshell.InteractiveShellABC')
57 shell = Instance('IPython.core.interactiveshell.InteractiveShellABC')
56
58
57 # The default formatter.
58 default_formatter = Instance('IPython.core.formatters.FormatterABC')
59 def _default_formatter_default(self):
60 # FIXME: backwards compatibility for the InteractiveShell.pprint option?
61 return DefaultFormatter(config=self.config)
62
63 # Any additional FormatterABC instances we use.
64 # FIXME: currently unused.
65 extra_formatters = List(config=True)
66
67 # Each call to the In[] prompt raises it by 1, even the first.
68 #prompt_count = Int(0)
69
70 def __init__(self, shell=None, cache_size=1000,
59 def __init__(self, shell=None, cache_size=1000,
71 colors='NoColor', input_sep='\n',
60 colors='NoColor', input_sep='\n',
72 output_sep='\n', output_sep2='',
61 output_sep='\n', output_sep2='',
@@ -185,36 +174,64 b' class DisplayHook(Configurable):'
185 pass
174 pass
186
175
187 def write_output_prompt(self):
176 def write_output_prompt(self):
188 """Write the output prompt."""
177 """Write the output prompt.
178
179 The default implementation simply writes the prompt to
180 ``io.Term.cout``.
181 """
189 # Use write, not print which adds an extra space.
182 # Use write, not print which adds an extra space.
190 IPython.utils.io.Term.cout.write(self.output_sep)
183 IPython.utils.io.Term.cout.write(self.output_sep)
191 outprompt = str(self.prompt_out)
184 outprompt = str(self.prompt_out)
192 if self.do_full_cache:
185 if self.do_full_cache:
193 IPython.utils.io.Term.cout.write(outprompt)
186 IPython.utils.io.Term.cout.write(outprompt)
194
187
195 def compute_result_repr(self, result):
188 def compute_format_data(self, result):
196 """Compute and return the repr of the object to be displayed.
189 """Compute format data of the object to be displayed.
197
190
198 This method only compute the string form of the repr and should NOT
191 The format data is a generalization of the :func:`repr` of an object.
192 In the default implementation the format data is a :class:`dict` of
193 key value pair where the keys are valid MIME types and the values
194 are JSON'able data structure containing the raw data for that MIME
195 type. It is up to frontends to determine pick a MIME to to use and
196 display that data in an appropriate manner.
197
198 This method only compute the format data for the object and should NOT
199 actually print or write that to a stream.
199 actually print or write that to a stream.
200
201 Parameters
202 ----------
203 result : object
204 The Python object passed to the display hook, whose forat will be
205 computed.
206
207 Returns
208 -------
209 format_data : dict
210 A :class:`dict` whose keys are valid MIME types and values are
211 JSON'able raw data for that MIME type. It is recommended that
212 all return values of this should always include the "text/plain"
213 MIME type representation of the object.
200 """
214 """
201 result_repr = self.default_formatter(result)
215 format_dict = self.shell.display_formatter.format(result)
202 extra_formats = []
216 return format_dict
203 for f in self.extra_formatters:
204 try:
205 data = f(result)
206 except Exception:
207 # FIXME: log the exception.
208 continue
209 if data is not None:
210 extra_formats.append((f.id, f.format, data))
211
217
212 return result_repr, extra_formats
218 def write_format_data(self, format_dict):
219 """Write the format data dict to the frontend.
213
220
214 def write_result_repr(self, result_repr, extra_formats):
221 This default version of this method simply writes the plain text
222 representation of the object to ``io.Term.cout``. Subclasses should
223 override this method to send the entire `format_dict` to the
224 frontends.
225
226 Parameters
227 ----------
228 format_dict : dict
229 The format dict for the object passed to `sys.displayhook`.
230 """
215 # We want to print because we want to always make sure we have a
231 # We want to print because we want to always make sure we have a
216 # newline, even if all the prompt separators are ''. This is the
232 # newline, even if all the prompt separators are ''. This is the
217 # standard IPython behavior.
233 # standard IPython behavior.
234 result_repr = format_dict['text/plain']
218 if '\n' in result_repr:
235 if '\n' in result_repr:
219 # So that multi-line strings line up with the left column of
236 # So that multi-line strings line up with the left column of
220 # the screen, instead of having the output prompt mess up
237 # the screen, instead of having the output prompt mess up
@@ -278,8 +295,8 b' class DisplayHook(Configurable):'
278 if result is not None and not self.quiet():
295 if result is not None and not self.quiet():
279 self.start_displayhook()
296 self.start_displayhook()
280 self.write_output_prompt()
297 self.write_output_prompt()
281 result_repr, extra_formats = self.compute_result_repr(result)
298 format_dict = self.compute_format_data(result)
282 self.write_result_repr(result_repr, extra_formats)
299 self.write_format_data(format_dict)
283 self.update_user_ns(result)
300 self.update_user_ns(result)
284 self.log_output(result)
301 self.log_output(result)
285 self.finish_displayhook()
302 self.finish_displayhook()
@@ -300,5 +317,6 b' class DisplayHook(Configurable):'
300 if '_' not in __builtin__.__dict__:
317 if '_' not in __builtin__.__dict__:
301 self.shell.user_ns.update({'_':None,'__':None, '___':None})
318 self.shell.user_ns.update({'_':None,'__':None, '___':None})
302 import gc
319 import gc
303 gc.collect() # xxx needed?
320 # TODO: Is this really needed?
321 gc.collect()
304
322
@@ -1,6 +1,16 b''
1 # -*- coding: utf-8 -*-
2 """An interface for publishing rich data to frontends.
1 """An interface for publishing rich data to frontends.
3
2
3 There are two components of the display system:
4
5 * Display formatters, which take a Python object and compute the
6 representation of the object in various formats (text, HTML, SVg, etc.).
7 * The display publisher that is used to send the representation data to the
8 various frontends.
9
10 This module defines the logic display publishing. The display publisher uses
11 the ``display_data`` message type that is defined in the IPython messaging
12 spec.
13
4 Authors:
14 Authors:
5
15
6 * Brian Granger
16 * Brian Granger
@@ -24,8 +34,26 b' from IPython.config.configurable import Configurable'
24 #-----------------------------------------------------------------------------
34 #-----------------------------------------------------------------------------
25
35
26 class DisplayPublisher(Configurable):
36 class DisplayPublisher(Configurable):
37 """A traited class that publishes display data to frontends.
38
39 Instances of this class are created by the main IPython object and should
40 be accessed there.
41 """
27
42
28 def _validate_data(self, source, data, metadata=None):
43 def _validate_data(self, source, data, metadata=None):
44 """Validate the display data.
45
46 Parameters
47 ----------
48 source : str
49 The fully dotted name of the callable that created the data, like
50 :func:`foo.bar.my_formatter`.
51 data : dict
52 The formata data dictionary.
53 metadata : dict
54 Any metadata for the data.
55 """
56
29 if not isinstance(source, str):
57 if not isinstance(source, str):
30 raise TypeError('source must be a str, got: %r' % source)
58 raise TypeError('source must be a str, got: %r' % source)
31 if not isinstance(data, dict):
59 if not isinstance(data, dict):
@@ -40,6 +68,15 b' class DisplayPublisher(Configurable):'
40 See the ``display_data`` message in the messaging documentation for
68 See the ``display_data`` message in the messaging documentation for
41 more details about this message type.
69 more details about this message type.
42
70
71 The following MIME types are currently implemented:
72
73 * text/plain
74 * text/html
75 * text/latex
76 * application/json
77 * image/png
78 * immage/svg+xml
79
43 Parameters
80 Parameters
44 ----------
81 ----------
45 source : str
82 source : str
@@ -64,40 +101,43 b' class DisplayPublisher(Configurable):'
64 print >>io.Term.cout, data['text/plain']
101 print >>io.Term.cout, data['text/plain']
65
102
66
103
67 def publish_display_data(source, text, svg=None, png=None,
104 def publish_display_data(self, source, data, metadata=None):
68 html=None, metadata=None):
105 """Publish data and metadata to all frontends.
69 """Publish a display data to the frontends.
70
71 This function is a high level helper for the publishing of display data.
72 It handle a number of common MIME types in a clean API. For other MIME
73 types, use ``get_ipython().display_pub.publish`` directly.
74
106
75 Parameters
107 See the ``display_data`` message in the messaging documentation for
76 ----------
108 more details about this message type.
77 text : str/unicode
78 The string representation of the plot.
79
109
80 svn : str/unicode
110 The following MIME types are currently implemented:
81 The raw svg data of the plot.
82
111
83 png : ???
112 * text/plain
84 The raw png data of the plot.
113 * text/html
114 * text/latex
115 * application/json
116 * image/png
117 * immage/svg+xml
85
118
86 metadata : dict, optional [default empty]
119 Parameters
87 Allows for specification of additional information about the plot data.
120 ----------
121 source : str
122 A string that give the function or method that created the data,
123 such as 'IPython.core.page'.
124 data : dict
125 A dictionary having keys that are valid MIME types (like
126 'text/plain' or 'image/svg+xml') and values that are the data for
127 that MIME type. The data itself must be a JSON'able data
128 structure. Minimally all data should have the 'text/plain' data,
129 which can be displayed by all frontends. If more than the plain
130 text is given, it is up to the frontend to decide which
131 representation to use.
132 metadata : dict
133 A dictionary for metadata related to the data. This can contain
134 arbitrary key, value pairs that frontends can use to interpret
135 the data.
88 """
136 """
89 from IPython.core.interactiveshell import InteractiveShell
137 from IPython.core.interactiveshell import InteractiveShell
90
91 data_dict = {}
92 data_dict['text/plain'] = text
93 if svg is not None:
94 data_dict['image/svg+xml'] = svg
95 if png is not None:
96 data_dict['image/png'] = png
97 if html is not None:
98 data_dict['text/html'] = html
99 InteractiveShell.instance().display_pub.publish(
138 InteractiveShell.instance().display_pub.publish(
100 source,
139 source,
101 data_dict,
140 data,
102 metadata
141 metadata
103 )
142 )
143
@@ -1,36 +1,11 b''
1 # -*- coding: utf-8 -*-
1 # -*- coding: utf-8 -*-
2 """Displayhook formatters.
2 """Display formatters.
3
3
4 The DefaultFormatter is always present and may be configured from the
5 ipython_config.py file. For example, to add a pretty-printer for a numpy.dtype
6 object::
7
4
8 def dtype_pprinter(obj, p, cycle):
5 Authors:
9 if cycle:
10 return p.text('dtype(...)')
11 if hasattr(obj, 'fields'):
12 if obj.fields is None:
13 p.text(repr(obj))
14 else:
15 p.begin_group(7, 'dtype([')
16 for i, field in enumerate(obj.descr):
17 if i > 0:
18 p.text(',')
19 p.breakable()
20 p.pretty(field)
21 p.end_group(7, '])')
22
23 c.DefaultFormatter.deferred_pprinters = {
24 ('numpy', 'dtype'): dtype_pprinter,
25 }
26
6
27 The deferred_pprinters dictionary is the preferred way to configure these
7 * Robert Kern
28 pretty-printers. This allows you to define the pretty-printer without needing to
8 * Brian Granger
29 import the type itself. The dictionary maps (modulename, typename) pairs to
30 a function.
31
32 See the `IPython.external.pretty` documentation for how to write
33 pretty-printer functions.
34 """
9 """
35 #-----------------------------------------------------------------------------
10 #-----------------------------------------------------------------------------
36 # Copyright (c) 2010, IPython Development Team.
11 # Copyright (c) 2010, IPython Development Team.
@@ -42,7 +17,8 b' pretty-printer functions.'
42
17
43 # Stdlib imports
18 # Stdlib imports
44 import abc
19 import abc
45 from cStringIO import StringIO
20 # We must use StringIO, as cStringIO doesn't handle unicode properly.
21 from StringIO import StringIO
46
22
47 # Our own imports
23 # Our own imports
48 from IPython.config.configurable import Configurable
24 from IPython.config.configurable import Configurable
@@ -51,19 +27,268 b' from IPython.utils.traitlets import Bool, Dict, Int, Str'
51
27
52
28
53 #-----------------------------------------------------------------------------
29 #-----------------------------------------------------------------------------
54 # Classes and functions
30 # The main DisplayFormatter class
55 #-----------------------------------------------------------------------------
31 #-----------------------------------------------------------------------------
56
32
57 class DefaultFormatter(Configurable):
33
34 class DisplayFormatter(Configurable):
35
36 # A dict of formatter whose keys are format types (MIME types) and whose
37 # values are subclasses of BaseFormatter.
38 formatters = Dict(config=True)
39 def _formatters_default(self):
40 """Activate the default formatters."""
41 formatter_classes = [
42 PlainTextFormatter,
43 HTMLFormatter,
44 SVGFormatter,
45 PNGFormatter,
46 LatexFormatter,
47 JSONFormatter
48 ]
49 d = {}
50 for cls in formatter_classes:
51 f = cls(config=self.config)
52 d[f.format_type] = f
53 return d
54
55 def format(self, obj, include=None, exclude=None):
56 """Return a format data dict for an object.
57
58 By default all format types will be computed.
59
60 The following MIME types are currently implemented:
61
62 * text/plain
63 * text/html
64 * text/latex
65 * application/json
66 * image/png
67 * immage/svg+xml
68
69 Parameters
70 ----------
71 obj : object
72 The Python object whose format data will be computed.
73
74 Returns
75 -------
76 format_dict : dict
77 A dictionary of key/value pairs, one or each format that was
78 generated for the object. The keys are the format types, which
79 will usually be MIME type strings and the values and JSON'able
80 data structure containing the raw data for the representation in
81 that format.
82 include : list or tuple, optional
83 A list of format type strings (MIME types) to include in the
84 format data dict. If this is set *only* the format types included
85 in this list will be computed.
86 exclude : list or tuple, optional
87 A list of format type string (MIME types) to exclue in the format
88 data dict. If this is set all format types will be computed,
89 except for those included in this argument.
90 """
91 format_dict = {}
92 for format_type, formatter in self.formatters.items():
93 if include is not None:
94 if format_type not in include:
95 continue
96 if exclude is not None:
97 if format_type in exclude:
98 continue
99 try:
100 data = formatter(obj)
101 except:
102 # FIXME: log the exception
103 raise
104 if data is not None:
105 format_dict[format_type] = data
106 return format_dict
107
108 @property
109 def format_types(self):
110 """Return the format types (MIME types) of the active formatters."""
111 return self.formatters.keys()
112
113
114 #-----------------------------------------------------------------------------
115 # Formatters for specific format types (text, html, svg, etc.)
116 #-----------------------------------------------------------------------------
117
118
119 class FormatterABC(object):
120 """ Abstract base class for Formatters.
121
122 A formatter is a callable class that is responsible for computing the
123 raw format data for a particular format type (MIME type). For example,
124 an HTML formatter would have a format type of `text/html` and would return
125 the HTML representation of the object when called.
126 """
127 __metaclass__ = abc.ABCMeta
128
129 # The format type of the data returned, usually a MIME type.
130 format_type = 'text/plain'
131
132 @abc.abstractmethod
133 def __call__(self, obj):
134 """Return a JSON'able representation of the object.
135
136 If the object cannot be formatted by this formatter, then return None
137 """
138 try:
139 return repr(obj)
140 except TypeError:
141 return None
142
143
144 class BaseFormatter(Configurable):
145 """A base formatter class that is configurable.
146
147 This formatter should usually be used as the base class of all formatters.
148 It is a traited :class:`Configurable` class and includes an extensible
149 API for users to determine how their objects are formatted. The following
150 logic is used to find a function to format an given object.
151
152 1. The object is introspected to see if it has a method with the name
153 :attr:`print_method`. If is does, that object is passed to that method
154 for formatting.
155 2. If no print method is found, three internal dictionaries are consulted
156 to find print method: :attr:`singleton_printers`, :attr:`type_printers`
157 and :attr:`deferred_printers`.
158
159 Users should use these dictionarie to register functions that will be used
160 to compute the format data for their objects (if those objects don't have
161 the special print methods). The easiest way of using these dictionaries
162 is through the :meth:`for_type` and :meth:`for_type_by_name` methods.
163
164 If no function/callable is found to compute the format data, ``None`` is
165 returned and this format type is not used.
166 """
167
168 format_type = Str('text/plain')
169
170 print_method = Str('__repr__')
171
172 # The singleton printers.
173 # Maps the IDs of the builtin singleton objects to the format functions.
174 singleton_printers = Dict(config=True)
175 def _singleton_printers_default(self):
176 return {}
177
178 # The type-specific printers.
179 # Map type objects to the format functions.
180 type_printers = Dict(config=True)
181 def _type_printers_default(self):
182 return {}
183
184 # The deferred-import type-specific printers.
185 # Map (modulename, classname) pairs to the format functions.
186 deferred_printers = Dict(config=True)
187 def _deferred_printers_default(self):
188 return {}
189
190 def __call__(self, obj):
191 """Compute the format for an object."""
192 obj_id = id(obj)
193 try:
194 obj_class = getattr(obj, '__class__', None) or type(obj)
195 if hasattr(obj_class, self.print_method):
196 printer = getattr(obj_class, self.print_method)
197 return printer(obj)
198 try:
199 printer = self.singleton_printers[obj_id]
200 except (TypeError, KeyError):
201 pass
202 else:
203 return printer(obj)
204 for cls in pretty._get_mro(obj_class):
205 if cls in self.type_printers:
206 return self.type_printers[cls](obj)
207 else:
208 printer = self._in_deferred_types(cls)
209 if printer is not None:
210 return printer(obj)
211 return None
212 except Exception:
213 pass
214
215 def for_type(self, typ, func):
216 """Add a format function for a given type.
217
218 Parameteres
219 -----------
220 typ : class
221 The class of the object that will be formatted using `func`.
222 func : callable
223 The callable that will be called to compute the format data. The
224 call signature of this function is simple, it must take the
225 object to be formatted and return the raw data for the given
226 format. Subclasses may use a different call signature for the
227 `func` argument.
228 """
229 oldfunc = self.type_printers.get(typ, None)
230 if func is not None:
231 # To support easy restoration of old printers, we need to ignore
232 # Nones.
233 self.type_printers[typ] = func
234 return oldfunc
235
236 def for_type_by_name(self, type_module, type_name, func):
237 """Add a format function for a type specified by the full dotted
238 module and name of the type, rather than the type of the object.
239
240 Parameters
241 ----------
242 type_module : str
243 The full dotted name of the module the type is defined in, like
244 ``numpy``.
245 type_name : str
246 The name of the type (the class name), like ``dtype``
247 func : callable
248 The callable that will be called to compute the format data. The
249 call signature of this function is simple, it must take the
250 object to be formatted and return the raw data for the given
251 format. Subclasses may use a different call signature for the
252 `func` argument.
253 """
254 key = (type_module, type_name)
255 oldfunc = self.deferred_printers.get(key, None)
256 if func is not None:
257 # To support easy restoration of old printers, we need to ignore
258 # Nones.
259 self.deferred_printers[key] = func
260 return oldfunc
261
262
263 class PlainTextFormatter(BaseFormatter):
58 """ The default pretty-printer.
264 """The default pretty-printer.
265
266 This uses :mod:`IPython.external.pretty` to compute the format data of
267 the object. If the object cannot be pretty printed, :func:`repr` is used.
268 See the documentation of :mod:`IPython.external.pretty` for details on
269 how to write pretty printers. Here is a simple example::
270
271 def dtype_pprinter(obj, p, cycle):
272 if cycle:
273 return p.text('dtype(...)')
274 if hasattr(obj, 'fields'):
275 if obj.fields is None:
276 p.text(repr(obj))
277 else:
278 p.begin_group(7, 'dtype([')
279 for i, field in enumerate(obj.descr):
280 if i > 0:
281 p.text(',')
282 p.breakable()
283 p.pretty(field)
284 p.end_group(7, '])')
59 """
285 """
60
286
61 # The ID of the formatter.
287 # The format type of data returned.
62 id = Str('default')
288 format_type = Str('text/plain')
63
289
64 # The kind of data returned.
290 # Look for a __pretty__ methods to use for pretty printing.
65 # This is often, but not always a MIME type.
291 print_method = Str('__pretty__')
66 format = Str('text/plain')
67
292
68 # Whether to pretty-print or not.
293 # Whether to pretty-print or not.
69 pprint = Bool(True, config=True)
294 pprint = Bool(True, config=True)
@@ -77,93 +302,152 b' class DefaultFormatter(Configurable):'
77 # The newline character.
302 # The newline character.
78 newline = Str('\n', config=True)
303 newline = Str('\n', config=True)
79
304
80 # The singleton prettyprinters.
305 # Use the default pretty printers from IPython.external.pretty.
81 # Maps the IDs of the builtin singleton objects to the format functions.
306 def _singleton_printers_default(self):
82 singleton_pprinters = Dict(config=True)
83 def _singleton_pprinters_default(self):
84 return pretty._singleton_pprinters.copy()
307 return pretty._singleton_pprinters.copy()
85
308
86 # The type-specific prettyprinters.
309 def _type_printers_default(self):
87 # Map type objects to the format functions.
88 type_pprinters = Dict(config=True)
89 def _type_pprinters_default(self):
90 return pretty._type_pprinters.copy()
310 return pretty._type_pprinters.copy()
91
311
92 # The deferred-import type-specific prettyprinters.
312 def _deferred_printers_default(self):
93 # Map (modulename, classname) pairs to the format functions.
94 deferred_pprinters = Dict(config=True)
95 def _deferred_pprinters_default(self):
96 return pretty._deferred_type_pprinters.copy()
313 return pretty._deferred_type_pprinters.copy()
97
314
98 #### FormatterABC interface ####
315 #### FormatterABC interface ####
99
316
100 def __call__(self, obj):
317 def __call__(self, obj):
101 """ Format the object.
318 """Compute the pretty representation of the object."""
102 """
103 if not self.pprint:
319 if not self.pprint:
104 try:
320 try:
105 return repr(obj)
321 return repr(obj)
106 except TypeError:
322 except TypeError:
107 return ''
323 return ''
108 else:
324 else:
325 # This uses use StringIO, as cStringIO doesn't handle unicode.
109 stream = StringIO()
326 stream = StringIO()
110 printer = pretty.RepresentationPrinter(stream, self.verbose,
327 printer = pretty.RepresentationPrinter(stream, self.verbose,
111 self.max_width, self.newline,
328 self.max_width, self.newline,
112 singleton_pprinters=self.singleton_pprinters,
329 singleton_pprinters=self.singleton_printers,
113 type_pprinters=self.type_pprinters,
330 type_pprinters=self.type_printers,
114 deferred_pprinters=self.deferred_pprinters)
331 deferred_pprinters=self.deferred_printers)
115 printer.pretty(obj)
332 printer.pretty(obj)
116 printer.flush()
333 printer.flush()
117 return stream.getvalue()
334 return stream.getvalue()
118
335
119
336
120 #### DefaultFormatter interface ####
337 class HTMLFormatter(BaseFormatter):
338 """An HTML formatter.
121
339
122 def for_type(self, typ, func):
340 To define the callables that compute the HTML representation of your
123 """
341 objects, define a :meth:`__html__` method or use the :meth:`for_type`
124 Add a pretty printer for a given type.
342 or :meth:`for_type_by_name` methods to register functions that handle
343 this.
125 """
344 """
126 oldfunc = self.type_pprinters.get(typ, None)
345 format_type = Str('text/html')
127 if func is not None:
128 # To support easy restoration of old pprinters, we need to ignore
129 # Nones.
130 self.type_pprinters[typ] = func
131 return oldfunc
132
346
133 def for_type_by_name(self, type_module, type_name, func):
347 print_method = Str('__html__')
348
349
350 class SVGFormatter(BaseFormatter):
351 """An SVG formatter.
352
353 To define the callables that compute the SVG representation of your
354 objects, define a :meth:`__svg__` method or use the :meth:`for_type`
355 or :meth:`for_type_by_name` methods to register functions that handle
356 this.
134 """
357 """
135 Add a pretty printer for a type specified by the module and name of
358 format_type = Str('image/svg+xml')
136 a type rather than the type object itself.
359
360 print_method = Str('__svg__')
361
362
363 class PNGFormatter(BaseFormatter):
364 """A PNG formatter.
365
366 To define the callables that compute the PNG representation of your
367 objects, define a :meth:`__svg__` method or use the :meth:`for_type`
368 or :meth:`for_type_by_name` methods to register functions that handle
369 this. The raw data should be the base64 encoded raw png data.
137 """
370 """
138 key = (type_module, type_name)
371 format_type = Str('image/png')
139 oldfunc = self.deferred_pprinters.get(key, None)
140 if func is not None:
141 # To support easy restoration of old pprinters, we need to ignore
142 # Nones.
143 self.deferred_pprinters[key] = func
144 return oldfunc
145
372
373 print_method = Str('__png__')
146
374
147 class FormatterABC(object):
375
148 """ Abstract base class for Formatters.
376 class LatexFormatter(BaseFormatter):
377 """A LaTeX formatter.
378
379 To define the callables that compute the LaTeX representation of your
380 objects, define a :meth:`__latex__` method or use the :meth:`for_type`
381 or :meth:`for_type_by_name` methods to register functions that handle
382 this.
149 """
383 """
150 __metaclass__ = abc.ABCMeta
384 format_type = Str('text/latex')
151
385
152 # The ID of the formatter.
386 print_method = Str('__latex__')
153 id = 'abstract'
154
387
155 # The kind of data returned.
156 format = 'text/plain'
157
388
158 @abc.abstractmethod
389 class JSONFormatter(BaseFormatter):
159 def __call__(self, obj):
390 """A JSON string formatter.
160 """ Return a JSONable representation of the object.
161
391
162 If the object cannot be formatted by this formatter, then return None
392 To define the callables that compute the JSON string representation of
393 your objects, define a :meth:`__json__` method or use the :meth:`for_type`
394 or :meth:`for_type_by_name` methods to register functions that handle
395 this.
163 """
396 """
164 try:
397 format_type = Str('application/json')
165 return repr(obj)
398
166 except TypeError:
399 print_method = Str('__json__')
167 return None
400
401
402 FormatterABC.register(BaseFormatter)
403 FormatterABC.register(PlainTextFormatter)
404 FormatterABC.register(HTMLFormatter)
405 FormatterABC.register(SVGFormatter)
406 FormatterABC.register(PNGFormatter)
407 FormatterABC.register(LatexFormatter)
408 FormatterABC.register(JSONFormatter)
409
410
411 def format_display_data(obj, include=None, exclude=None):
412 """Return a format data dict for an object.
413
414 By default all format types will be computed.
415
416 The following MIME types are currently implemented:
417
418 * text/plain
419 * text/html
420 * text/latex
421 * application/json
422 * image/png
423 * immage/svg+xml
424
425 Parameters
426 ----------
427 obj : object
428 The Python object whose format data will be computed.
429
430 Returns
431 -------
432 format_dict : dict
433 A dictionary of key/value pairs, one or each format that was
434 generated for the object. The keys are the format types, which
435 will usually be MIME type strings and the values and JSON'able
436 data structure containing the raw data for the representation in
437 that format.
438 include : list or tuple, optional
439 A list of format type strings (MIME types) to include in the
440 format data dict. If this is set *only* the format types included
441 in this list will be computed.
442 exclude : list or tuple, optional
443 A list of format type string (MIME types) to exclue in the format
444 data dict. If this is set all format types will be computed,
445 except for those included in this argument.
446 """
447 from IPython.core.interactiveshell import InteractiveShell
168
448
169 FormatterABC.register(DefaultFormatter)
449 InteractiveShell.instance().display_formatter.format(
450 obj,
451 include,
452 exclude
453 )
@@ -45,6 +45,7 b' from IPython.core.displaypub import DisplayPublisher'
45 from IPython.core.error import TryNext, UsageError
45 from IPython.core.error import TryNext, UsageError
46 from IPython.core.extensions import ExtensionManager
46 from IPython.core.extensions import ExtensionManager
47 from IPython.core.fakemodule import FakeModule, init_fakemod_dict
47 from IPython.core.fakemodule import FakeModule, init_fakemod_dict
48 from IPython.core.formatters import DisplayFormatter
48 from IPython.core.history import HistoryManager
49 from IPython.core.history import HistoryManager
49 from IPython.core.inputsplitter import IPythonInputSplitter
50 from IPython.core.inputsplitter import IPythonInputSplitter
50 from IPython.core.logger import Logger
51 from IPython.core.logger import Logger
@@ -150,6 +151,7 b' class InteractiveShell(Configurable, Magic):'
150 default_value=get_default_colors(), config=True)
151 default_value=get_default_colors(), config=True)
151 debug = CBool(False, config=True)
152 debug = CBool(False, config=True)
152 deep_reload = CBool(False, config=True)
153 deep_reload = CBool(False, config=True)
154 display_formatter = Instance(DisplayFormatter)
153 displayhook_class = Type(DisplayHook)
155 displayhook_class = Type(DisplayHook)
154 display_pub_class = Type(DisplayPublisher)
156 display_pub_class = Type(DisplayPublisher)
155
157
@@ -287,6 +289,7 b' class InteractiveShell(Configurable, Magic):'
287 self.init_io()
289 self.init_io()
288 self.init_traceback_handlers(custom_exceptions)
290 self.init_traceback_handlers(custom_exceptions)
289 self.init_prompts()
291 self.init_prompts()
292 self.init_display_formatter()
290 self.init_display_pub()
293 self.init_display_pub()
291 self.init_displayhook()
294 self.init_displayhook()
292 self.init_reload_doctest()
295 self.init_reload_doctest()
@@ -485,6 +488,9 b' class InteractiveShell(Configurable, Magic):'
485 # will initialize that object and all prompt related information.
488 # will initialize that object and all prompt related information.
486 pass
489 pass
487
490
491 def init_display_formatter(self):
492 self.display_formatter = DisplayFormatter(config=self.config)
493
488 def init_display_pub(self):
494 def init_display_pub(self):
489 self.display_pub = self.display_pub_class(config=self.config)
495 self.display_pub = self.display_pub_class(config=self.config)
490
496
@@ -352,7 +352,7 b' class FrontendWidget(HistoryConsoleWidget, BaseFrontendMixin):'
352 """ Handle display hook output.
352 """ Handle display hook output.
353 """
353 """
354 if not self._hidden and self._is_from_this_session(msg):
354 if not self._hidden and self._is_from_this_session(msg):
355 self._append_plain_text(msg['content']['data'] + '\n')
355 self._append_plain_text(msg['content']['data']['text/plain'] + '\n')
356
356
357 def _handle_stream(self, msg):
357 def _handle_stream(self, msg):
358 """ Handle stdout, stderr, and stdin.
358 """ Handle stdout, stderr, and stdin.
@@ -179,9 +179,18 b' class IPythonWidget(FrontendWidget):'
179 if not self._hidden and self._is_from_this_session(msg):
179 if not self._hidden and self._is_from_this_session(msg):
180 content = msg['content']
180 content = msg['content']
181 prompt_number = content['execution_count']
181 prompt_number = content['execution_count']
182 data = content['data']
183 if data.has_key('text/html'):
182 self._append_plain_text(self.output_sep)
184 self._append_plain_text(self.output_sep)
183 self._append_html(self._make_out_prompt(prompt_number))
185 self._append_html(self._make_out_prompt(prompt_number))
184 self._append_plain_text(content['data']+self.output_sep2)
186 html = data['text/html']
187 self._append_plain_text('\n')
188 self._append_html(html + self.output_sep2)
189 elif data.has_key('text/plain'):
190 self._append_plain_text(self.output_sep)
191 self._append_html(self._make_out_prompt(prompt_number))
192 text = data['text/plain']
193 self._append_plain_text(text + self.output_sep2)
185
194
186 def _handle_display_data(self, msg):
195 def _handle_display_data(self, msg):
187 """ The base handler for the ``display_data`` message.
196 """ The base handler for the ``display_data`` message.
@@ -195,8 +204,12 b' class IPythonWidget(FrontendWidget):'
195 metadata = msg['content']['metadata']
204 metadata = msg['content']['metadata']
196 # In the regular IPythonWidget, we simply print the plain text
205 # In the regular IPythonWidget, we simply print the plain text
197 # representation.
206 # representation.
198 if data.has_key('text/plain'):
207 if data.has_key('text/html'):
199 self._append_plain_text(data['text/plain'])
208 html = data['text/html']
209 self._append_html(html)
210 elif data.has_key('text/plain'):
211 text = data['text/plain']
212 self._append_plain_text(text)
200
213
201 def _started_channels(self):
214 def _started_channels(self):
202 """ Reimplemented to make a history request.
215 """ Reimplemented to make a history request.
@@ -61,8 +61,25 b' class RichIPythonWidget(IPythonWidget):'
61 # 'BaseFrontendMixin' abstract interface
61 # 'BaseFrontendMixin' abstract interface
62 #---------------------------------------------------------------------------
62 #---------------------------------------------------------------------------
63
63
64 def _handle_pyout(self, msg):
65 """ Overridden to handle rich data types, like SVG.
66 """
67 if not self._hidden and self._is_from_this_session(msg):
68 content = msg['content']
69 prompt_number = content['execution_count']
70 data = content['data']
71 if data.has_key('image/svg+xml'):
72 self._append_plain_text(self.output_sep)
73 self._append_html(self._make_out_prompt(prompt_number))
74 # TODO: try/except this call.
75 self._append_svg(data['image/svg+xml'])
76 self._append_html(self.output_sep2)
77 else:
78 # Default back to the plain text representation.
79 return super(RichIPythonWidget, self)._handle_pyout(msg)
80
64 def _handle_display_data(self, msg):
81 def _handle_display_data(self, msg):
65 """ A handler for ``display_data`` message that handles html and svg.
82 """ Overridden to handle rich data types, like SVG.
66 """
83 """
67 if not self._hidden and self._is_from_this_session(msg):
84 if not self._hidden and self._is_from_this_session(msg):
68 source = msg['content']['source']
85 source = msg['content']['source']
@@ -74,9 +91,6 b' class RichIPythonWidget(IPythonWidget):'
74 svg = data['image/svg+xml']
91 svg = data['image/svg+xml']
75 # TODO: try/except this call.
92 # TODO: try/except this call.
76 self._append_svg(svg)
93 self._append_svg(svg)
77 elif data.has_key('text/html'):
78 html = data['text/html']
79 self._append_html(html)
80 else:
94 else:
81 # Default back to the plain text representation.
95 # Default back to the plain text representation.
82 return super(RichIPythonWidget, self)._handle_display_data(msg)
96 return super(RichIPythonWidget, self)._handle_display_data(msg)
@@ -88,9 +102,9 b' class RichIPythonWidget(IPythonWidget):'
88 def _process_execute_payload(self, item):
102 def _process_execute_payload(self, item):
89 """ Reimplemented to handle matplotlib plot payloads.
103 """ Reimplemented to handle matplotlib plot payloads.
90 """
104 """
91 if item['source'] == self._payload_source_plot:
92 # TODO: remove this as all plot data is coming back through the
105 # TODO: remove this as all plot data is coming back through the
93 # display_data message type.
106 # display_data message type.
107 if item['source'] == self._payload_source_plot:
94 if item['format'] == 'svg':
108 if item['format'] == 'svg':
95 svg = item['data']
109 svg = item['data']
96 self._append_svg(svg)
110 self._append_svg(svg)
@@ -88,7 +88,7 b' def _result_list_printer(obj, p, cycle):'
88 # ResultList is a list subclass and will use the default pretty printer.
88 # ResultList is a list subclass and will use the default pretty printer.
89 # This overrides that to use the __repr__ of ResultList.
89 # This overrides that to use the __repr__ of ResultList.
90 ip = get_ipython()
90 ip = get_ipython()
91 ip.displayhook.default_formatter.for_type_by_name(
91 ip.display_formatter.formatters['text/plain'].for_type_by_name(
92 'IPython.kernel.multiengineclient', 'ResultList', _result_list_printer
92 'IPython.kernel.multiengineclient', 'ResultList', _result_list_printer
93 )
93 )
94
94
@@ -87,8 +87,8 b' def send_svg_canvas(canvas):'
87 try:
87 try:
88 publish_display_data(
88 publish_display_data(
89 'IPython.zmq.pylab.backend_inline.send_svg_canvas',
89 'IPython.zmq.pylab.backend_inline.send_svg_canvas',
90 '<Matplotlib Plot>',
90 'Matplotlib Plot',
91 svg=svg_from_canvas(canvas)
91 {'image/svg+xml' : svg_from_canvas(canvas)}
92 )
92 )
93 finally:
93 finally:
94 canvas.figure.set_facecolor(fc)
94 canvas.figure.set_facecolor(fc)
@@ -49,6 +49,7 b' install_payload_page()'
49 #-----------------------------------------------------------------------------
49 #-----------------------------------------------------------------------------
50
50
51 class ZMQDisplayHook(DisplayHook):
51 class ZMQDisplayHook(DisplayHook):
52 """A displayhook subclass that publishes data using ZeroMQ."""
52
53
53 session = Instance(Session)
54 session = Instance(Session)
54 pub_socket = Instance('zmq.Socket')
55 pub_socket = Instance('zmq.Socket')
@@ -66,9 +67,8 b' class ZMQDisplayHook(DisplayHook):'
66 if self.do_full_cache:
67 if self.do_full_cache:
67 self.msg['content']['execution_count'] = self.prompt_count
68 self.msg['content']['execution_count'] = self.prompt_count
68
69
69 def write_result_repr(self, result_repr, extra_formats):
70 def write_format_data(self, format_dict):
70 self.msg['content']['data'] = result_repr
71 self.msg['content']['data'] = format_dict
71 self.msg['content']['extra_formats'] = extra_formats
72
72
73 def finish_displayhook(self):
73 def finish_displayhook(self):
74 """Finish up all displayhook activities."""
74 """Finish up all displayhook activities."""
@@ -77,7 +77,7 b' class ZMQDisplayHook(DisplayHook):'
77
77
78
78
79 class ZMQDisplayPublisher(DisplayPublisher):
79 class ZMQDisplayPublisher(DisplayPublisher):
80 """A ``DisplayPublisher`` that published data using a ZeroMQ PUB socket."""
80 """A display publisher that publishes data using a ZeroMQ PUB socket."""
81
81
82 session = Instance(Session)
82 session = Instance(Session)
83 pub_socket = Instance('zmq.Socket')
83 pub_socket = Instance('zmq.Socket')
@@ -719,30 +719,18 b' Some questions remain about this design:'
719 Message type: ``display_data``::
719 Message type: ``display_data``::
720
720
721 content = {
721 content = {
722 'source' : str # Who create the data
723 'data' : dict # {'mimetype1' : data1, 'mimetype2' : data2}
724 'metadata' : dict # Any metadata that describes the data
725 }
726
727 Other options for ``display_data`` content::
728
722
729 # Option 2: allowing for a different source for each representation,
723 # Who create the data
730 but not keyed by anything.
724 'source' : str,
731 content = {
732 'data' = [(source, type, data), (source, type, data)]
733 'metadata' = dict
734 }
735
725
736 # Option 3: like option 2, but keyed by the MIME types.
726 # The data dict contains key/value pairs, where the kids are MIME
737 content = {
727 # types and the values are the raw data of the representation in that
738 'data' = {'mimetype1' : (source, data), 'mimetype2' : (source, data)}
728 # format. The data dict must minimally contain the ``text/plain``
739 'metadata' = dict
729 # MIME type which is used as a backup representation.
740 }
730 'data' : dict,
741
731
742 # Option 4: like option 2, but keyed by the source.
732 # Any metadata that describes the data
743 content = {
733 'metadata' : dict
744 'data' = {'source' : (mimetype, data), 'source' : (mimetype, data)}
745 'metadata' = dict
746 }
734 }
747
735
748 Python inputs
736 Python inputs
@@ -784,20 +772,18 b' any JSON object and depends on the format. It is often, but not always a string.'
784 Message type: ``pyout``::
772 Message type: ``pyout``::
785
773
786 content = {
774 content = {
787 # The data is typically the repr() of the object. It should be displayed
788 # as monospaced text.
789 'data' : str,
790
775
791 # The counter for this execution is also provided so that clients can
776 # The counter for this execution is also provided so that clients can
792 # display it, since IPython automatically creates variables called _N
777 # display it, since IPython automatically creates variables called _N
793 # (for prompt N).
778 # (for prompt N).
794 'execution_count' : int,
779 'execution_count' : int,
795
780
796 # Any extra formats.
781 # The data dict contains key/value pairs, where the kids are MIME
797 # The tuples are of the form (ID, type, data).
782 # types and the values are the raw data of the representation in that
798 'extra_formats' : [
783 # format. The data dict must minimally contain the ``text/plain``
799 [str, str, object]
784 # MIME type which is used as a backup representation.
800 ]
785 'data' : dict,
786
801 }
787 }
802
788
803 Python errors
789 Python errors
General Comments 0
You need to be logged in to leave comments. Login now