##// 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 15 # You have to make sure that attributes that are containers already
16 16 # exist before using them. Simple assigning a new list will override
17 17 # all previous values.
18
18 19 if hasattr(c.Global, 'exec_lines'):
19 20 c.Global.exec_lines.append(lines)
20 21 else:
21 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 1 # -*- coding: utf-8 -*-
2 2 """Displayhook for IPython.
3 3
4 This defines a callable class that IPython uses for `sys.displayhook`.
5
4 6 Authors:
5 7
6 8 * Fernando Perez
7 9 * Brian Granger
10 * Robert Kern
8 11 """
9 12
10 13 #-----------------------------------------------------------------------------
@@ -27,7 +30,6 b' import IPython.utils.generics'
27 30 import IPython.utils.io
28 31 from IPython.utils.traitlets import Instance, List
29 32 from IPython.utils.warn import warn
30 from IPython.core.formatters import DefaultFormatter
31 33
32 34 #-----------------------------------------------------------------------------
33 35 # Main displayhook class
@@ -54,19 +56,6 b' class DisplayHook(Configurable):'
54 56
55 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 59 def __init__(self, shell=None, cache_size=1000,
71 60 colors='NoColor', input_sep='\n',
72 61 output_sep='\n', output_sep2='',
@@ -185,36 +174,64 b' class DisplayHook(Configurable):'
185 174 pass
186 175
187 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 182 # Use write, not print which adds an extra space.
190 183 IPython.utils.io.Term.cout.write(self.output_sep)
191 184 outprompt = str(self.prompt_out)
192 185 if self.do_full_cache:
193 186 IPython.utils.io.Term.cout.write(outprompt)
194 187
195 def compute_result_repr(self, result):
196 """Compute and return the repr of the object to be displayed.
188 def compute_format_data(self, result):
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 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)
202 extra_formats = []
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))
215 format_dict = self.shell.display_formatter.format(result)
216 return format_dict
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 231 # We want to print because we want to always make sure we have a
216 232 # newline, even if all the prompt separators are ''. This is the
217 233 # standard IPython behavior.
234 result_repr = format_dict['text/plain']
218 235 if '\n' in result_repr:
219 236 # So that multi-line strings line up with the left column of
220 237 # the screen, instead of having the output prompt mess up
@@ -278,8 +295,8 b' class DisplayHook(Configurable):'
278 295 if result is not None and not self.quiet():
279 296 self.start_displayhook()
280 297 self.write_output_prompt()
281 result_repr, extra_formats = self.compute_result_repr(result)
282 self.write_result_repr(result_repr, extra_formats)
298 format_dict = self.compute_format_data(result)
299 self.write_format_data(format_dict)
283 300 self.update_user_ns(result)
284 301 self.log_output(result)
285 302 self.finish_displayhook()
@@ -300,5 +317,6 b' class DisplayHook(Configurable):'
300 317 if '_' not in __builtin__.__dict__:
301 318 self.shell.user_ns.update({'_':None,'__':None, '___':None})
302 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 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 14 Authors:
5 15
6 16 * Brian Granger
@@ -24,8 +34,26 b' from IPython.config.configurable import Configurable'
24 34 #-----------------------------------------------------------------------------
25 35
26 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 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 57 if not isinstance(source, str):
30 58 raise TypeError('source must be a str, got: %r' % source)
31 59 if not isinstance(data, dict):
@@ -40,6 +68,15 b' class DisplayPublisher(Configurable):'
40 68 See the ``display_data`` message in the messaging documentation for
41 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 80 Parameters
44 81 ----------
45 82 source : str
@@ -64,40 +101,43 b' class DisplayPublisher(Configurable):'
64 101 print >>io.Term.cout, data['text/plain']
65 102
66 103
67 def publish_display_data(source, text, svg=None, png=None,
68 html=None, metadata=None):
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.
104 def publish_display_data(self, source, data, metadata=None):
105 """Publish data and metadata to all frontends.
74 106
75 Parameters
76 ----------
77 text : str/unicode
78 The string representation of the plot.
107 See the ``display_data`` message in the messaging documentation for
108 more details about this message type.
79 109
80 svn : str/unicode
81 The raw svg data of the plot.
110 The following MIME types are currently implemented:
82 111
83 png : ???
84 The raw png data of the plot.
112 * text/plain
113 * text/html
114 * text/latex
115 * application/json
116 * image/png
117 * immage/svg+xml
85 118
86 metadata : dict, optional [default empty]
87 Allows for specification of additional information about the plot data.
119 Parameters
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 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 138 InteractiveShell.instance().display_pub.publish(
100 139 source,
101 data_dict,
140 data,
102 141 metadata
103 142 )
143
@@ -1,36 +1,11 b''
1 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):
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 }
5 Authors:
26 6
27 The deferred_pprinters dictionary is the preferred way to configure these
28 pretty-printers. This allows you to define the pretty-printer without needing to
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.
7 * Robert Kern
8 * Brian Granger
34 9 """
35 10 #-----------------------------------------------------------------------------
36 11 # Copyright (c) 2010, IPython Development Team.
@@ -42,7 +17,8 b' pretty-printer functions.'
42 17
43 18 # Stdlib imports
44 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 23 # Our own imports
48 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 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.
62 id = Str('default')
287 # The format type of data returned.
288 format_type = Str('text/plain')
63 289
64 # The kind of data returned.
65 # This is often, but not always a MIME type.
66 format = Str('text/plain')
290 # Look for a __pretty__ methods to use for pretty printing.
291 print_method = Str('__pretty__')
67 292
68 293 # Whether to pretty-print or not.
69 294 pprint = Bool(True, config=True)
@@ -77,93 +302,152 b' class DefaultFormatter(Configurable):'
77 302 # The newline character.
78 303 newline = Str('\n', config=True)
79 304
80 # The singleton prettyprinters.
81 # Maps the IDs of the builtin singleton objects to the format functions.
82 singleton_pprinters = Dict(config=True)
83 def _singleton_pprinters_default(self):
305 # Use the default pretty printers from IPython.external.pretty.
306 def _singleton_printers_default(self):
84 307 return pretty._singleton_pprinters.copy()
85 308
86 # The type-specific prettyprinters.
87 # Map type objects to the format functions.
88 type_pprinters = Dict(config=True)
89 def _type_pprinters_default(self):
309 def _type_printers_default(self):
90 310 return pretty._type_pprinters.copy()
91 311
92 # The deferred-import type-specific prettyprinters.
93 # Map (modulename, classname) pairs to the format functions.
94 deferred_pprinters = Dict(config=True)
95 def _deferred_pprinters_default(self):
312 def _deferred_printers_default(self):
96 313 return pretty._deferred_type_pprinters.copy()
97 314
98 315 #### FormatterABC interface ####
99 316
100 317 def __call__(self, obj):
101 """ Format the object.
102 """
318 """Compute the pretty representation of the object."""
103 319 if not self.pprint:
104 320 try:
105 321 return repr(obj)
106 322 except TypeError:
107 323 return ''
108 324 else:
325 # This uses use StringIO, as cStringIO doesn't handle unicode.
109 326 stream = StringIO()
110 327 printer = pretty.RepresentationPrinter(stream, self.verbose,
111 328 self.max_width, self.newline,
112 singleton_pprinters=self.singleton_pprinters,
113 type_pprinters=self.type_pprinters,
114 deferred_pprinters=self.deferred_pprinters)
329 singleton_pprinters=self.singleton_printers,
330 type_pprinters=self.type_printers,
331 deferred_pprinters=self.deferred_printers)
115 332 printer.pretty(obj)
116 333 printer.flush()
117 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):
123 """
124 Add a pretty printer for a given type.
340 To define the callables that compute the HTML representation of your
341 objects, define a :meth:`__html__` method or use the :meth:`for_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)
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
345 format_type = Str('text/html')
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
136 a type rather than the type object itself.
358 format_type = Str('image/svg+xml')
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)
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
371 format_type = Str('image/png')
145 372
373 print_method = Str('__png__')
146 374
147 class FormatterABC(object):
148 """ Abstract base class for Formatters.
375
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.
153 id = 'abstract'
386 print_method = Str('__latex__')
154 387
155 # The kind of data returned.
156 format = 'text/plain'
157 388
158 @abc.abstractmethod
159 def __call__(self, obj):
160 """ Return a JSONable representation of the object.
389 class JSONFormatter(BaseFormatter):
390 """A JSON string formatter.
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:
165 return repr(obj)
166 except TypeError:
167 return None
397 format_type = Str('application/json')
398
399 print_method = Str('__json__')
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 45 from IPython.core.error import TryNext, UsageError
46 46 from IPython.core.extensions import ExtensionManager
47 47 from IPython.core.fakemodule import FakeModule, init_fakemod_dict
48 from IPython.core.formatters import DisplayFormatter
48 49 from IPython.core.history import HistoryManager
49 50 from IPython.core.inputsplitter import IPythonInputSplitter
50 51 from IPython.core.logger import Logger
@@ -150,6 +151,7 b' class InteractiveShell(Configurable, Magic):'
150 151 default_value=get_default_colors(), config=True)
151 152 debug = CBool(False, config=True)
152 153 deep_reload = CBool(False, config=True)
154 display_formatter = Instance(DisplayFormatter)
153 155 displayhook_class = Type(DisplayHook)
154 156 display_pub_class = Type(DisplayPublisher)
155 157
@@ -287,6 +289,7 b' class InteractiveShell(Configurable, Magic):'
287 289 self.init_io()
288 290 self.init_traceback_handlers(custom_exceptions)
289 291 self.init_prompts()
292 self.init_display_formatter()
290 293 self.init_display_pub()
291 294 self.init_displayhook()
292 295 self.init_reload_doctest()
@@ -485,6 +488,9 b' class InteractiveShell(Configurable, Magic):'
485 488 # will initialize that object and all prompt related information.
486 489 pass
487 490
491 def init_display_formatter(self):
492 self.display_formatter = DisplayFormatter(config=self.config)
493
488 494 def init_display_pub(self):
489 495 self.display_pub = self.display_pub_class(config=self.config)
490 496
@@ -352,7 +352,7 b' class FrontendWidget(HistoryConsoleWidget, BaseFrontendMixin):'
352 352 """ Handle display hook output.
353 353 """
354 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 357 def _handle_stream(self, msg):
358 358 """ Handle stdout, stderr, and stdin.
@@ -179,9 +179,18 b' class IPythonWidget(FrontendWidget):'
179 179 if not self._hidden and self._is_from_this_session(msg):
180 180 content = msg['content']
181 181 prompt_number = content['execution_count']
182 data = content['data']
183 if data.has_key('text/html'):
182 184 self._append_plain_text(self.output_sep)
183 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 195 def _handle_display_data(self, msg):
187 196 """ The base handler for the ``display_data`` message.
@@ -195,8 +204,12 b' class IPythonWidget(FrontendWidget):'
195 204 metadata = msg['content']['metadata']
196 205 # In the regular IPythonWidget, we simply print the plain text
197 206 # representation.
198 if data.has_key('text/plain'):
199 self._append_plain_text(data['text/plain'])
207 if data.has_key('text/html'):
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 214 def _started_channels(self):
202 215 """ Reimplemented to make a history request.
@@ -61,8 +61,25 b' class RichIPythonWidget(IPythonWidget):'
61 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 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 84 if not self._hidden and self._is_from_this_session(msg):
68 85 source = msg['content']['source']
@@ -74,9 +91,6 b' class RichIPythonWidget(IPythonWidget):'
74 91 svg = data['image/svg+xml']
75 92 # TODO: try/except this call.
76 93 self._append_svg(svg)
77 elif data.has_key('text/html'):
78 html = data['text/html']
79 self._append_html(html)
80 94 else:
81 95 # Default back to the plain text representation.
82 96 return super(RichIPythonWidget, self)._handle_display_data(msg)
@@ -88,9 +102,9 b' class RichIPythonWidget(IPythonWidget):'
88 102 def _process_execute_payload(self, item):
89 103 """ Reimplemented to handle matplotlib plot payloads.
90 104 """
91 if item['source'] == self._payload_source_plot:
92 105 # TODO: remove this as all plot data is coming back through the
93 106 # display_data message type.
107 if item['source'] == self._payload_source_plot:
94 108 if item['format'] == 'svg':
95 109 svg = item['data']
96 110 self._append_svg(svg)
@@ -88,7 +88,7 b' def _result_list_printer(obj, p, cycle):'
88 88 # ResultList is a list subclass and will use the default pretty printer.
89 89 # This overrides that to use the __repr__ of ResultList.
90 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 92 'IPython.kernel.multiengineclient', 'ResultList', _result_list_printer
93 93 )
94 94
@@ -87,8 +87,8 b' def send_svg_canvas(canvas):'
87 87 try:
88 88 publish_display_data(
89 89 'IPython.zmq.pylab.backend_inline.send_svg_canvas',
90 '<Matplotlib Plot>',
91 svg=svg_from_canvas(canvas)
90 'Matplotlib Plot',
91 {'image/svg+xml' : svg_from_canvas(canvas)}
92 92 )
93 93 finally:
94 94 canvas.figure.set_facecolor(fc)
@@ -49,6 +49,7 b' install_payload_page()'
49 49 #-----------------------------------------------------------------------------
50 50
51 51 class ZMQDisplayHook(DisplayHook):
52 """A displayhook subclass that publishes data using ZeroMQ."""
52 53
53 54 session = Instance(Session)
54 55 pub_socket = Instance('zmq.Socket')
@@ -66,9 +67,8 b' class ZMQDisplayHook(DisplayHook):'
66 67 if self.do_full_cache:
67 68 self.msg['content']['execution_count'] = self.prompt_count
68 69
69 def write_result_repr(self, result_repr, extra_formats):
70 self.msg['content']['data'] = result_repr
71 self.msg['content']['extra_formats'] = extra_formats
70 def write_format_data(self, format_dict):
71 self.msg['content']['data'] = format_dict
72 72
73 73 def finish_displayhook(self):
74 74 """Finish up all displayhook activities."""
@@ -77,7 +77,7 b' class ZMQDisplayHook(DisplayHook):'
77 77
78 78
79 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 82 session = Instance(Session)
83 83 pub_socket = Instance('zmq.Socket')
@@ -719,30 +719,18 b' Some questions remain about this design:'
719 719 Message type: ``display_data``::
720 720
721 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,
730 but not keyed by anything.
731 content = {
732 'data' = [(source, type, data), (source, type, data)]
733 'metadata' = dict
734 }
723 # Who create the data
724 'source' : str,
735 725
736 # Option 3: like option 2, but keyed by the MIME types.
737 content = {
738 'data' = {'mimetype1' : (source, data), 'mimetype2' : (source, data)}
739 'metadata' = dict
740 }
726 # The data dict contains key/value pairs, where the kids are MIME
727 # types and the values are the raw data of the representation in that
728 # format. The data dict must minimally contain the ``text/plain``
729 # MIME type which is used as a backup representation.
730 'data' : dict,
741 731
742 # Option 4: like option 2, but keyed by the source.
743 content = {
744 'data' = {'source' : (mimetype, data), 'source' : (mimetype, data)}
745 'metadata' = dict
732 # Any metadata that describes the data
733 'metadata' : dict
746 734 }
747 735
748 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 772 Message type: ``pyout``::
785 773
786 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 776 # The counter for this execution is also provided so that clients can
792 777 # display it, since IPython automatically creates variables called _N
793 778 # (for prompt N).
794 779 'execution_count' : int,
795 780
796 # Any extra formats.
797 # The tuples are of the form (ID, type, data).
798 'extra_formats' : [
799 [str, str, object]
800 ]
781 # The data dict contains key/value pairs, where the kids are MIME
782 # types and the values are the raw data of the representation in that
783 # format. The data dict must minimally contain the ``text/plain``
784 # MIME type which is used as a backup representation.
785 'data' : dict,
786
801 787 }
802 788
803 789 Python errors
General Comments 0
You need to be logged in to leave comments. Login now