##// END OF EJS Templates
Updates to the display system....
Brian E. Granger -
Show More
@@ -1,130 +1,274
1 1 # -*- coding: utf-8 -*-
2 2 """Top-level display functions for displaying object in different formats.
3 3
4 4 Authors:
5 5
6 6 * Brian Granger
7 7 """
8 8
9 9 #-----------------------------------------------------------------------------
10 10 # Copyright (C) 2008-2010 The IPython Development Team
11 11 #
12 12 # Distributed under the terms of the BSD License. The full license is in
13 13 # the file COPYING, distributed as part of this software.
14 14 #-----------------------------------------------------------------------------
15 15
16 16 #-----------------------------------------------------------------------------
17 17 # Imports
18 18 #-----------------------------------------------------------------------------
19 19
20 from .displaypub import (
21 publish_pretty, publish_html,
22 publish_latex, publish_svg,
23 publish_png, publish_json,
24 publish_javascript
25 )
26
20 27 #-----------------------------------------------------------------------------
21 28 # Main functions
22 29 #-----------------------------------------------------------------------------
23 30
24 31 def display(*objs, **kwargs):
25 32 """Display a Python object in all frontends.
26 33
27 34 By default all representations will be computed and sent to the frontends.
28 35 Frontends can decide which representation is used and how.
29 36
30 37 Parameters
31 38 ----------
32 39 objs : tuple of objects
33 40 The Python objects to display.
34 41 include : list or tuple, optional
35 42 A list of format type strings (MIME types) to include in the
36 43 format data dict. If this is set *only* the format types included
37 44 in this list will be computed.
38 45 exclude : list or tuple, optional
39 46 A list of format type string (MIME types) to exclue in the format
40 47 data dict. If this is set all format types will be computed,
41 48 except for those included in this argument.
42 49 """
43 50 include = kwargs.get('include')
44 51 exclude = kwargs.get('exclude')
45 52
46 53 from IPython.core.interactiveshell import InteractiveShell
47 54 inst = InteractiveShell.instance()
48 55 format = inst.display_formatter.format
49 56 publish = inst.display_pub.publish
50 57
51 58 for obj in objs:
52 59 format_dict = format(obj, include=include, exclude=exclude)
53 60 publish('IPython.core.display.display', format_dict)
54 61
55 62
56 def display_pretty(*objs):
63 def display_pretty(*objs, **kwargs):
57 64 """Display the pretty (default) representation of an object.
58 65
59 66 Parameters
60 67 ----------
61 68 objs : tuple of objects
62 The Python objects to display.
69 The Python objects to display, or if raw=True raw text data to
70 display.
71 raw : bool
72 Are the data objects raw data or Python objects that need to be
73 formatted before display? [default: False]
63 74 """
64 display(*objs, include=['text/plain'])
75 raw = kwargs.pop('raw',False)
76 if raw:
77 for obj in objs:
78 publish_pretty(obj)
79 else:
80 display(*objs, include=['text/plain'])
65 81
66 82
67 def display_html(*objs):
83 def display_html(*objs, **kwargs):
68 84 """Display the HTML representation of an object.
69 85
70 86 Parameters
71 87 ----------
72 88 objs : tuple of objects
73 The Python objects to display.
74 """
75 display(*objs, include=['text/plain','text/html'])
89 The Python objects to display, or if raw=True raw html data to
90 display.
91 raw : bool
92 Are the data objects raw data or Python objects that need to be
93 formatted before display? [default: False]
94 """
95 raw = kwargs.pop('raw',False)
96 if raw:
97 for obj in objs:
98 publish_html(obj)
99 else:
100 display(*objs, include=['text/plain','text/html'])
76 101
77 102
78 def display_svg(*objs):
103 def display_svg(*objs, **kwargs):
79 104 """Display the SVG representation of an object.
80 105
81 106 Parameters
82 107 ----------
83 108 objs : tuple of objects
84 The Python objects to display.
109 The Python objects to display, or if raw=True raw svg data to
110 display.
111 raw : bool
112 Are the data objects raw data or Python objects that need to be
113 formatted before display? [default: False]
85 114 """
86 display(*objs, include=['text/plain','image/svg+xml'])
115 raw = kwargs.pop('raw',False)
116 if raw:
117 for obj in objs:
118 publish_svg(obj)
119 else:
120 display(*objs, include=['text/plain','image/svg+xml'])
87 121
88 122
89 def display_png(*objs):
123 def display_png(*objs, **kwargs):
90 124 """Display the PNG representation of an object.
91 125
92 126 Parameters
93 127 ----------
94 128 objs : tuple of objects
95 The Python objects to display.
129 The Python objects to display, or if raw=True raw png data to
130 display.
131 raw : bool
132 Are the data objects raw data or Python objects that need to be
133 formatted before display? [default: False]
96 134 """
97 display(*objs, include=['text/plain','image/png'])
135 raw = kwargs.pop('raw',False)
136 if raw:
137 for obj in objs:
138 publish_png(obj)
139 else:
140 display(*objs, include=['text/plain','image/png'])
98 141
99 142
100 def display_latex(*objs):
143 def display_latex(*objs, **kwargs):
101 144 """Display the LaTeX representation of an object.
102 145
103 146 Parameters
104 147 ----------
105 148 objs : tuple of objects
106 The Python objects to display.
149 The Python objects to display, or if raw=True raw latex data to
150 display.
151 raw : bool
152 Are the data objects raw data or Python objects that need to be
153 formatted before display? [default: False]
107 154 """
108 display(*objs, include=['text/plain','text/latex'])
155 raw = kwargs.pop('raw',False)
156 if raw:
157 for obj in objs:
158 publish_latex(obj)
159 else:
160 display(*objs, include=['text/plain','text/latex'])
109 161
110 162
111 def display_json(*objs):
163 def display_json(*objs, **kwargs):
112 164 """Display the JSON representation of an object.
113 165
114 166 Parameters
115 167 ----------
116 168 objs : tuple of objects
117 The Python objects to display.
169 The Python objects to display, or if raw=True raw json data to
170 display.
171 raw : bool
172 Are the data objects raw data or Python objects that need to be
173 formatted before display? [default: False]
118 174 """
119 display(*objs, include=['text/plain','application/json'])
175 raw = kwargs.pop('raw',False)
176 if raw:
177 for obj in objs:
178 publish_json(obj)
179 else:
180 display(*objs, include=['text/plain','application/json'])
120 181
121 182
122 def display_javascript(*objs):
183 def display_javascript(*objs, **kwargs):
123 184 """Display the Javascript representation of an object.
124 185
125 186 Parameters
126 187 ----------
127 188 objs : tuple of objects
128 The Python objects to display.
189 The Python objects to display, or if raw=True raw javascript data to
190 display.
191 raw : bool
192 Are the data objects raw data or Python objects that need to be
193 formatted before display? [default: False]
129 194 """
130 display(*objs, include=['text/plain','application/javascript'])
195 raw = kwargs.pop('raw',False)
196 if raw:
197 for obj in objs:
198 publish_javascript(obj)
199 else:
200 display(*objs, include=['text/plain','application/javascript'])
201
202 #-----------------------------------------------------------------------------
203 # Smart classes
204 #-----------------------------------------------------------------------------
205
206
207 class DisplayObject(object):
208 """An object that wraps data to be displayed."""
209
210 def __init__(self, data):
211 """Create a display object given raw data of a MIME type or a URL.
212
213 When this object is returned by an expression or passed to the
214 display function, it will result in the data being displayed
215 in the frontend. The MIME type of the data should match the
216 subclasses used, so the Png subclass should be used for 'image/png'
217 data. If the data is a URL, the data will first be downloaded
218 and then displayed.
219
220 Parameters
221 ----------
222 data : unicode, str or bytes
223 The raw data or a URL to download the data from.
224 """
225 if data.startswith('http'):
226 import urllib2
227 response = urllib2.urlopen(data)
228 self.data = response.read()
229 else:
230 self.data = data
231
232
233 class Pretty(DisplayObject):
234
235 def _repr_pretty_(self):
236 return self.data
237
238
239 class Html(DisplayObject):
240
241 def _repr_html_(self):
242 return self.data
243
244
245 class Latex(DisplayObject):
246
247 def _repr_latex_(self):
248 return self.data
249
250
251 class Png(DisplayObject):
252
253 def _repr_png_(self):
254 return self.data
255
256
257 class Svg(DisplayObject):
258
259 def _repr_svg_(self):
260 return self.data
261
262
263 class Json(DisplayObject):
264
265 def _repr_json_(self):
266 return self.data
267
268
269 class Javscript(DisplayObject):
270
271 def _repr_javascript_(self):
272 return self.data
273
274
@@ -1,145 +1,276
1 1 """An interface for publishing rich data to frontends.
2 2
3 3 There are two components of the display system:
4 4
5 5 * Display formatters, which take a Python object and compute the
6 6 representation of the object in various formats (text, HTML, SVg, etc.).
7 7 * The display publisher that is used to send the representation data to the
8 8 various frontends.
9 9
10 10 This module defines the logic display publishing. The display publisher uses
11 11 the ``display_data`` message type that is defined in the IPython messaging
12 12 spec.
13 13
14 14 Authors:
15 15
16 16 * Brian Granger
17 17 """
18 18
19 19 #-----------------------------------------------------------------------------
20 20 # Copyright (C) 2008-2010 The IPython Development Team
21 21 #
22 22 # Distributed under the terms of the BSD License. The full license is in
23 23 # the file COPYING, distributed as part of this software.
24 24 #-----------------------------------------------------------------------------
25 25
26 26 #-----------------------------------------------------------------------------
27 27 # Imports
28 28 #-----------------------------------------------------------------------------
29 29
30 30 from __future__ import print_function
31 31
32 32 from IPython.config.configurable import Configurable
33 33
34 34 #-----------------------------------------------------------------------------
35 35 # Main payload class
36 36 #-----------------------------------------------------------------------------
37 37
38 38 class DisplayPublisher(Configurable):
39 39 """A traited class that publishes display data to frontends.
40 40
41 41 Instances of this class are created by the main IPython object and should
42 42 be accessed there.
43 43 """
44 44
45 45 def _validate_data(self, source, data, metadata=None):
46 46 """Validate the display data.
47 47
48 48 Parameters
49 49 ----------
50 50 source : str
51 51 The fully dotted name of the callable that created the data, like
52 52 :func:`foo.bar.my_formatter`.
53 53 data : dict
54 54 The formata data dictionary.
55 55 metadata : dict
56 56 Any metadata for the data.
57 57 """
58 58
59 if not isinstance(source, str):
59 if not isinstance(source, (str,unicode)):
60 60 raise TypeError('source must be a str, got: %r' % source)
61 61 if not isinstance(data, dict):
62 62 raise TypeError('data must be a dict, got: %r' % data)
63 63 if metadata is not None:
64 64 if not isinstance(metadata, dict):
65 65 raise TypeError('metadata must be a dict, got: %r' % data)
66 66
67 67 def publish(self, source, data, metadata=None):
68 68 """Publish data and metadata to all frontends.
69 69
70 70 See the ``display_data`` message in the messaging documentation for
71 71 more details about this message type.
72 72
73 73 The following MIME types are currently implemented:
74 74
75 75 * text/plain
76 76 * text/html
77 77 * text/latex
78 78 * application/json
79 * application/javascript
79 80 * image/png
80 * immage/svg+xml
81 * image/svg+xml
81 82
82 83 Parameters
83 84 ----------
84 85 source : str
85 86 A string that give the function or method that created the data,
86 87 such as 'IPython.core.page'.
87 88 data : dict
88 89 A dictionary having keys that are valid MIME types (like
89 90 'text/plain' or 'image/svg+xml') and values that are the data for
90 91 that MIME type. The data itself must be a JSON'able data
91 92 structure. Minimally all data should have the 'text/plain' data,
92 93 which can be displayed by all frontends. If more than the plain
93 94 text is given, it is up to the frontend to decide which
94 95 representation to use.
95 96 metadata : dict
96 97 A dictionary for metadata related to the data. This can contain
97 98 arbitrary key, value pairs that frontends can use to interpret
98 99 the data.
99 100 """
100 101 from IPython.utils import io
101 102 # The default is to simply write the plain text data using io.stdout.
102 103 if data.has_key('text/plain'):
103 104 print(data['text/plain'], file=io.stdout)
104 105
105 106
106 def publish_display_data(self, source, data, metadata=None):
107 def publish_display_data(source, data, metadata=None):
107 108 """Publish data and metadata to all frontends.
108 109
109 110 See the ``display_data`` message in the messaging documentation for
110 111 more details about this message type.
111 112
112 113 The following MIME types are currently implemented:
113 114
114 115 * text/plain
115 116 * text/html
116 117 * text/latex
117 118 * application/json
119 * application/javascript
118 120 * image/png
119 * immage/svg+xml
121 * image/svg+xml
120 122
121 123 Parameters
122 124 ----------
123 125 source : str
124 126 A string that give the function or method that created the data,
125 127 such as 'IPython.core.page'.
126 128 data : dict
127 129 A dictionary having keys that are valid MIME types (like
128 130 'text/plain' or 'image/svg+xml') and values that are the data for
129 131 that MIME type. The data itself must be a JSON'able data
130 132 structure. Minimally all data should have the 'text/plain' data,
131 133 which can be displayed by all frontends. If more than the plain
132 134 text is given, it is up to the frontend to decide which
133 135 representation to use.
134 136 metadata : dict
135 137 A dictionary for metadata related to the data. This can contain
136 138 arbitrary key, value pairs that frontends can use to interpret
137 139 the data.
138 140 """
139 141 from IPython.core.interactiveshell import InteractiveShell
140 142 InteractiveShell.instance().display_pub.publish(
141 143 source,
142 144 data,
143 145 metadata
144 146 )
145 147
148
149 def publish_pretty(data, metadata=None):
150 """Publish raw text data to all frontends.
151
152 Parameters
153 ----------
154 data : unicode
155 The raw text data to publish.
156 metadata : dict
157 A dictionary for metadata related to the data. This can contain
158 arbitrary key, value pairs that frontends can use to interpret
159 the data.
160 """
161 publish_display_data(
162 u'IPython.core.displaypub.publish_pretty',
163 {'text/plain':data},
164 metadata=metadata
165 )
166
167
168 def publish_html(data, metadata=None):
169 """Publish raw html data to all frontends.
170
171 Parameters
172 ----------
173 data : unicode
174 The raw html data to publish.
175 metadata : dict
176 A dictionary for metadata related to the data. This can contain
177 arbitrary key, value pairs that frontends can use to interpret
178 the data.
179 """
180 publish_display_data(
181 u'IPython.core.displaypub.publish_html',
182 {'text/html':data},
183 metadata=metadata
184 )
185
186
187 def publish_latex(data, metadata=None):
188 """Publish raw latex data to all frontends.
189
190 Parameters
191 ----------
192 data : unicode
193 The raw latex data to publish.
194 metadata : dict
195 A dictionary for metadata related to the data. This can contain
196 arbitrary key, value pairs that frontends can use to interpret
197 the data.
198 """
199 publish_display_data(
200 u'IPython.core.displaypub.publish_latex',
201 {'text/latex':data},
202 metadata=metadata
203 )
204
205 def publish_png(data, metadata=None):
206 """Publish raw binary png data to all frontends.
207
208 Parameters
209 ----------
210 data : str/bytes
211 The raw binary png data to publish.
212 metadata : dict
213 A dictionary for metadata related to the data. This can contain
214 arbitrary key, value pairs that frontends can use to interpret
215 the data.
216 """
217 publish_display_data(
218 u'IPython.core.displaypub.publish_png',
219 {'image/png':data},
220 metadata=metadata
221 )
222
223 def publish_svg(data, metadata=None):
224 """Publish raw svg data to all frontends.
225
226 Parameters
227 ----------
228 data : unicode
229 The raw svg data to publish.
230 metadata : dict
231 A dictionary for metadata related to the data. This can contain
232 arbitrary key, value pairs that frontends can use to interpret
233 the data.
234 """
235 publish_display_data(
236 u'IPython.core.displaypub.publish_svg',
237 {'image/svg+xml':data},
238 metadata=metadata
239 )
240
241 def publish_json(data, metadata=None):
242 """Publish raw json data to all frontends.
243
244 Parameters
245 ----------
246 data : unicode
247 The raw json data to publish.
248 metadata : dict
249 A dictionary for metadata related to the data. This can contain
250 arbitrary key, value pairs that frontends can use to interpret
251 the data.
252 """
253 publish_display_data(
254 u'IPython.core.displaypub.publish_json',
255 {'application/json':data},
256 metadata=metadata
257 )
258
259 def publish_javascript(data, metadata=None):
260 """Publish raw javascript data to all frontends.
261
262 Parameters
263 ----------
264 data : unicode
265 The raw javascript data to publish.
266 metadata : dict
267 A dictionary for metadata related to the data. This can contain
268 arbitrary key, value pairs that frontends can use to interpret
269 the data.
270 """
271 publish_display_data(
272 u'IPython.core.displaypub.publish_javascript',
273 {'application/javascript':data},
274 metadata=metadata
275 )
276
@@ -1,596 +1,598
1 1 # -*- coding: utf-8 -*-
2 2 """Display formatters.
3 3
4 4
5 5 Authors:
6 6
7 7 * Robert Kern
8 8 * Brian Granger
9 9 """
10 10 #-----------------------------------------------------------------------------
11 11 # Copyright (c) 2010, IPython Development Team.
12 12 #
13 13 # Distributed under the terms of the Modified BSD License.
14 14 #
15 15 # The full license is in the file COPYING.txt, distributed with this software.
16 16 #-----------------------------------------------------------------------------
17 17
18 18 #-----------------------------------------------------------------------------
19 19 # Imports
20 20 #-----------------------------------------------------------------------------
21 21
22 22 # Stdlib imports
23 23 import abc
24 24 import sys
25 25 # We must use StringIO, as cStringIO doesn't handle unicode properly.
26 26 from StringIO import StringIO
27 27
28 28 # Our own imports
29 29 from IPython.config.configurable import Configurable
30 30 from IPython.lib import pretty
31 31 from IPython.utils.traitlets import Bool, Dict, Int, Unicode, CUnicode, ObjectName
32 32
33 33
34 34 #-----------------------------------------------------------------------------
35 35 # The main DisplayFormatter class
36 36 #-----------------------------------------------------------------------------
37 37
38 38
39 39 class DisplayFormatter(Configurable):
40 40
41 41 # When set to true only the default plain text formatter will be used.
42 42 plain_text_only = Bool(False, config=True)
43 43
44 44 # A dict of formatter whose keys are format types (MIME types) and whose
45 45 # values are subclasses of BaseFormatter.
46 46 formatters = Dict(config=True)
47 47 def _formatters_default(self):
48 48 """Activate the default formatters."""
49 49 formatter_classes = [
50 50 PlainTextFormatter,
51 51 HTMLFormatter,
52 52 SVGFormatter,
53 53 PNGFormatter,
54 54 LatexFormatter,
55 55 JSONFormatter,
56 56 JavascriptFormatter
57 57 ]
58 58 d = {}
59 59 for cls in formatter_classes:
60 60 f = cls(config=self.config)
61 61 d[f.format_type] = f
62 62 return d
63 63
64 64 def format(self, obj, include=None, exclude=None):
65 65 """Return a format data dict for an object.
66 66
67 67 By default all format types will be computed.
68 68
69 69 The following MIME types are currently implemented:
70 70
71 71 * text/plain
72 72 * text/html
73 73 * text/latex
74 74 * application/json
75 * application/javascript
75 76 * image/png
76 * immage/svg+xml
77 * image/svg+xml
77 78
78 79 Parameters
79 80 ----------
80 81 obj : object
81 82 The Python object whose format data will be computed.
82 83 include : list or tuple, optional
83 84 A list of format type strings (MIME types) to include in the
84 85 format data dict. If this is set *only* the format types included
85 86 in this list will be computed.
86 87 exclude : list or tuple, optional
87 88 A list of format type string (MIME types) to exclue in the format
88 89 data dict. If this is set all format types will be computed,
89 90 except for those included in this argument.
90 91
91 92 Returns
92 93 -------
93 94 format_dict : dict
94 95 A dictionary of key/value pairs, one or each format that was
95 96 generated for the object. The keys are the format types, which
96 97 will usually be MIME type strings and the values and JSON'able
97 98 data structure containing the raw data for the representation in
98 99 that format.
99 100 """
100 101 format_dict = {}
101 102
102 103 # If plain text only is active
103 104 if self.plain_text_only:
104 105 formatter = self.formatters['text/plain']
105 106 try:
106 107 data = formatter(obj)
107 108 except:
108 109 # FIXME: log the exception
109 110 raise
110 111 if data is not None:
111 112 format_dict['text/plain'] = data
112 113 return format_dict
113 114
114 115 for format_type, formatter in self.formatters.items():
115 116 if include is not None:
116 117 if format_type not in include:
117 118 continue
118 119 if exclude is not None:
119 120 if format_type in exclude:
120 121 continue
121 122 try:
122 123 data = formatter(obj)
123 124 except:
124 125 # FIXME: log the exception
125 126 raise
126 127 if data is not None:
127 128 format_dict[format_type] = data
128 129 return format_dict
129 130
130 131 @property
131 132 def format_types(self):
132 133 """Return the format types (MIME types) of the active formatters."""
133 134 return self.formatters.keys()
134 135
135 136
136 137 #-----------------------------------------------------------------------------
137 138 # Formatters for specific format types (text, html, svg, etc.)
138 139 #-----------------------------------------------------------------------------
139 140
140 141
141 142 class FormatterABC(object):
142 143 """ Abstract base class for Formatters.
143 144
144 145 A formatter is a callable class that is responsible for computing the
145 146 raw format data for a particular format type (MIME type). For example,
146 147 an HTML formatter would have a format type of `text/html` and would return
147 148 the HTML representation of the object when called.
148 149 """
149 150 __metaclass__ = abc.ABCMeta
150 151
151 152 # The format type of the data returned, usually a MIME type.
152 153 format_type = 'text/plain'
153 154
154 155 # Is the formatter enabled...
155 156 enabled = True
156 157
157 158 @abc.abstractmethod
158 159 def __call__(self, obj):
159 160 """Return a JSON'able representation of the object.
160 161
161 162 If the object cannot be formatted by this formatter, then return None
162 163 """
163 164 try:
164 165 return repr(obj)
165 166 except TypeError:
166 167 return None
167 168
168 169
169 170 class BaseFormatter(Configurable):
170 171 """A base formatter class that is configurable.
171 172
172 173 This formatter should usually be used as the base class of all formatters.
173 174 It is a traited :class:`Configurable` class and includes an extensible
174 175 API for users to determine how their objects are formatted. The following
175 176 logic is used to find a function to format an given object.
176 177
177 178 1. The object is introspected to see if it has a method with the name
178 179 :attr:`print_method`. If is does, that object is passed to that method
179 180 for formatting.
180 181 2. If no print method is found, three internal dictionaries are consulted
181 182 to find print method: :attr:`singleton_printers`, :attr:`type_printers`
182 183 and :attr:`deferred_printers`.
183 184
184 185 Users should use these dictionaries to register functions that will be
185 186 used to compute the format data for their objects (if those objects don't
186 187 have the special print methods). The easiest way of using these
187 188 dictionaries is through the :meth:`for_type` and :meth:`for_type_by_name`
188 189 methods.
189 190
190 191 If no function/callable is found to compute the format data, ``None`` is
191 192 returned and this format type is not used.
192 193 """
193 194
194 195 format_type = Unicode('text/plain')
195 196
196 197 enabled = Bool(True, config=True)
197 198
198 199 print_method = ObjectName('__repr__')
199 200
200 201 # The singleton printers.
201 202 # Maps the IDs of the builtin singleton objects to the format functions.
202 203 singleton_printers = Dict(config=True)
203 204 def _singleton_printers_default(self):
204 205 return {}
205 206
206 207 # The type-specific printers.
207 208 # Map type objects to the format functions.
208 209 type_printers = Dict(config=True)
209 210 def _type_printers_default(self):
210 211 return {}
211 212
212 213 # The deferred-import type-specific printers.
213 214 # Map (modulename, classname) pairs to the format functions.
214 215 deferred_printers = Dict(config=True)
215 216 def _deferred_printers_default(self):
216 217 return {}
217 218
218 219 def __call__(self, obj):
219 220 """Compute the format for an object."""
220 221 if self.enabled:
221 222 obj_id = id(obj)
222 223 try:
223 224 obj_class = getattr(obj, '__class__', None) or type(obj)
224 225 # First try to find registered singleton printers for the type.
225 226 try:
226 227 printer = self.singleton_printers[obj_id]
227 228 except (TypeError, KeyError):
228 229 pass
229 230 else:
230 231 return printer(obj)
231 232 # Next look for type_printers.
232 233 for cls in pretty._get_mro(obj_class):
233 234 if cls in self.type_printers:
234 235 return self.type_printers[cls](obj)
235 236 else:
236 237 printer = self._in_deferred_types(cls)
237 238 if printer is not None:
238 239 return printer(obj)
239 240 # Finally look for special method names.
240 241 if hasattr(obj_class, self.print_method):
241 242 printer = getattr(obj_class, self.print_method)
242 243 return printer(obj)
243 244 return None
244 245 except Exception:
245 246 pass
246 247 else:
247 248 return None
248 249
249 250 def for_type(self, typ, func):
250 251 """Add a format function for a given type.
251 252
252 253 Parameters
253 254 -----------
254 255 typ : class
255 256 The class of the object that will be formatted using `func`.
256 257 func : callable
257 258 The callable that will be called to compute the format data. The
258 259 call signature of this function is simple, it must take the
259 260 object to be formatted and return the raw data for the given
260 261 format. Subclasses may use a different call signature for the
261 262 `func` argument.
262 263 """
263 264 oldfunc = self.type_printers.get(typ, None)
264 265 if func is not None:
265 266 # To support easy restoration of old printers, we need to ignore
266 267 # Nones.
267 268 self.type_printers[typ] = func
268 269 return oldfunc
269 270
270 271 def for_type_by_name(self, type_module, type_name, func):
271 272 """Add a format function for a type specified by the full dotted
272 273 module and name of the type, rather than the type of the object.
273 274
274 275 Parameters
275 276 ----------
276 277 type_module : str
277 278 The full dotted name of the module the type is defined in, like
278 279 ``numpy``.
279 280 type_name : str
280 281 The name of the type (the class name), like ``dtype``
281 282 func : callable
282 283 The callable that will be called to compute the format data. The
283 284 call signature of this function is simple, it must take the
284 285 object to be formatted and return the raw data for the given
285 286 format. Subclasses may use a different call signature for the
286 287 `func` argument.
287 288 """
288 289 key = (type_module, type_name)
289 290 oldfunc = self.deferred_printers.get(key, None)
290 291 if func is not None:
291 292 # To support easy restoration of old printers, we need to ignore
292 293 # Nones.
293 294 self.deferred_printers[key] = func
294 295 return oldfunc
295 296
296 297 def _in_deferred_types(self, cls):
297 298 """
298 299 Check if the given class is specified in the deferred type registry.
299 300
300 301 Returns the printer from the registry if it exists, and None if the
301 302 class is not in the registry. Successful matches will be moved to the
302 303 regular type registry for future use.
303 304 """
304 305 mod = getattr(cls, '__module__', None)
305 306 name = getattr(cls, '__name__', None)
306 307 key = (mod, name)
307 308 printer = None
308 309 if key in self.deferred_printers:
309 310 # Move the printer over to the regular registry.
310 311 printer = self.deferred_printers.pop(key)
311 312 self.type_printers[cls] = printer
312 313 return printer
313 314
314 315
315 316 class PlainTextFormatter(BaseFormatter):
316 317 """The default pretty-printer.
317 318
318 319 This uses :mod:`IPython.external.pretty` to compute the format data of
319 320 the object. If the object cannot be pretty printed, :func:`repr` is used.
320 321 See the documentation of :mod:`IPython.external.pretty` for details on
321 322 how to write pretty printers. Here is a simple example::
322 323
323 324 def dtype_pprinter(obj, p, cycle):
324 325 if cycle:
325 326 return p.text('dtype(...)')
326 327 if hasattr(obj, 'fields'):
327 328 if obj.fields is None:
328 329 p.text(repr(obj))
329 330 else:
330 331 p.begin_group(7, 'dtype([')
331 332 for i, field in enumerate(obj.descr):
332 333 if i > 0:
333 334 p.text(',')
334 335 p.breakable()
335 336 p.pretty(field)
336 337 p.end_group(7, '])')
337 338 """
338 339
339 340 # The format type of data returned.
340 341 format_type = Unicode('text/plain')
341 342
342 343 # This subclass ignores this attribute as it always need to return
343 344 # something.
344 345 enabled = Bool(True, config=False)
345 346
346 347 # Look for a _repr_pretty_ methods to use for pretty printing.
347 348 print_method = ObjectName('_repr_pretty_')
348 349
349 350 # Whether to pretty-print or not.
350 351 pprint = Bool(True, config=True)
351 352
352 353 # Whether to be verbose or not.
353 354 verbose = Bool(False, config=True)
354 355
355 356 # The maximum width.
356 357 max_width = Int(79, config=True)
357 358
358 359 # The newline character.
359 360 newline = Unicode('\n', config=True)
360 361
361 362 # format-string for pprinting floats
362 363 float_format = Unicode('%r')
363 364 # setter for float precision, either int or direct format-string
364 365 float_precision = CUnicode('', config=True)
365 366
366 367 def _float_precision_changed(self, name, old, new):
367 368 """float_precision changed, set float_format accordingly.
368 369
369 370 float_precision can be set by int or str.
370 371 This will set float_format, after interpreting input.
371 372 If numpy has been imported, numpy print precision will also be set.
372 373
373 374 integer `n` sets format to '%.nf', otherwise, format set directly.
374 375
375 376 An empty string returns to defaults (repr for float, 8 for numpy).
376 377
377 378 This parameter can be set via the '%precision' magic.
378 379 """
379 380
380 381 if '%' in new:
381 382 # got explicit format string
382 383 fmt = new
383 384 try:
384 385 fmt%3.14159
385 386 except Exception:
386 387 raise ValueError("Precision must be int or format string, not %r"%new)
387 388 elif new:
388 389 # otherwise, should be an int
389 390 try:
390 391 i = int(new)
391 392 assert i >= 0
392 393 except ValueError:
393 394 raise ValueError("Precision must be int or format string, not %r"%new)
394 395 except AssertionError:
395 396 raise ValueError("int precision must be non-negative, not %r"%i)
396 397
397 398 fmt = '%%.%if'%i
398 399 if 'numpy' in sys.modules:
399 400 # set numpy precision if it has been imported
400 401 import numpy
401 402 numpy.set_printoptions(precision=i)
402 403 else:
403 404 # default back to repr
404 405 fmt = '%r'
405 406 if 'numpy' in sys.modules:
406 407 import numpy
407 408 # numpy default is 8
408 409 numpy.set_printoptions(precision=8)
409 410 self.float_format = fmt
410 411
411 412 # Use the default pretty printers from IPython.external.pretty.
412 413 def _singleton_printers_default(self):
413 414 return pretty._singleton_pprinters.copy()
414 415
415 416 def _type_printers_default(self):
416 417 d = pretty._type_pprinters.copy()
417 418 d[float] = lambda obj,p,cycle: p.text(self.float_format%obj)
418 419 return d
419 420
420 421 def _deferred_printers_default(self):
421 422 return pretty._deferred_type_pprinters.copy()
422 423
423 424 #### FormatterABC interface ####
424 425
425 426 def __call__(self, obj):
426 427 """Compute the pretty representation of the object."""
427 428 if not self.pprint:
428 429 try:
429 430 return repr(obj)
430 431 except TypeError:
431 432 return ''
432 433 else:
433 434 # This uses use StringIO, as cStringIO doesn't handle unicode.
434 435 stream = StringIO()
435 436 # self.newline.encode() is a quick fix for issue gh-597. We need to
436 437 # ensure that stream does not get a mix of unicode and bytestrings,
437 438 # or it will cause trouble.
438 439 printer = pretty.RepresentationPrinter(stream, self.verbose,
439 440 self.max_width, self.newline.encode(),
440 441 singleton_pprinters=self.singleton_printers,
441 442 type_pprinters=self.type_printers,
442 443 deferred_pprinters=self.deferred_printers)
443 444 printer.pretty(obj)
444 445 printer.flush()
445 446 return stream.getvalue()
446 447
447 448
448 449 class HTMLFormatter(BaseFormatter):
449 450 """An HTML formatter.
450 451
451 452 To define the callables that compute the HTML representation of your
452 453 objects, define a :meth:`_repr_html_` method or use the :meth:`for_type`
453 454 or :meth:`for_type_by_name` methods to register functions that handle
454 455 this.
455 456
456 457 The return value of this formatter should be a valid HTML snippet that
457 458 could be injected into an existing DOM. It should *not* include the
458 459 ```<html>`` or ```<body>`` tags.
459 460 """
460 461 format_type = Unicode('text/html')
461 462
462 463 print_method = ObjectName('_repr_html_')
463 464
464 465
465 466 class SVGFormatter(BaseFormatter):
466 467 """An SVG formatter.
467 468
468 469 To define the callables that compute the SVG representation of your
469 470 objects, define a :meth:`_repr_svg_` method or use the :meth:`for_type`
470 471 or :meth:`for_type_by_name` methods to register functions that handle
471 472 this.
472 473
473 474 The return value of this formatter should be valid SVG enclosed in
474 475 ```<svg>``` tags, that could be injected into an existing DOM. It should
475 476 *not* include the ```<html>`` or ```<body>`` tags.
476 477 """
477 478 format_type = Unicode('image/svg+xml')
478 479
479 480 print_method = ObjectName('_repr_svg_')
480 481
481 482
482 483 class PNGFormatter(BaseFormatter):
483 484 """A PNG formatter.
484 485
485 486 To define the callables that compute the PNG representation of your
486 487 objects, define a :meth:`_repr_png_` method or use the :meth:`for_type`
487 488 or :meth:`for_type_by_name` methods to register functions that handle
488 489 this.
489 490
490 491 The return value of this formatter should be raw PNG data, *not*
491 492 base64 encoded.
492 493 """
493 494 format_type = Unicode('image/png')
494 495
495 496 print_method = ObjectName('_repr_png_')
496 497
497 498
498 499 class LatexFormatter(BaseFormatter):
499 500 """A LaTeX formatter.
500 501
501 502 To define the callables that compute the LaTeX representation of your
502 503 objects, define a :meth:`_repr_latex_` method or use the :meth:`for_type`
503 504 or :meth:`for_type_by_name` methods to register functions that handle
504 505 this.
505 506
506 507 The return value of this formatter should be a valid LaTeX equation,
507 508 enclosed in either ```$``` or ```$$```.
508 509 """
509 510 format_type = Unicode('text/latex')
510 511
511 512 print_method = ObjectName('_repr_latex_')
512 513
513 514
514 515 class JSONFormatter(BaseFormatter):
515 516 """A JSON string formatter.
516 517
517 518 To define the callables that compute the JSON string representation of
518 519 your objects, define a :meth:`_repr_json_` method or use the :meth:`for_type`
519 520 or :meth:`for_type_by_name` methods to register functions that handle
520 521 this.
521 522
522 523 The return value of this formatter should be a valid JSON string.
523 524 """
524 525 format_type = Unicode('application/json')
525 526
526 527 print_method = ObjectName('_repr_json_')
527 528
528 529
529 530 class JavascriptFormatter(BaseFormatter):
530 531 """A Javascript formatter.
531 532
532 533 To define the callables that compute the Javascript representation of
533 534 your objects, define a :meth:`_repr_javascript_` method or use the
534 535 :meth:`for_type` or :meth:`for_type_by_name` methods to register functions
535 536 that handle this.
536 537
537 538 The return value of this formatter should be valid Javascript code and
538 539 should *not* be enclosed in ```<script>``` tags.
539 540 """
540 541 format_type = Unicode('application/javascript')
541 542
542 543 print_method = ObjectName('_repr_javascript_')
543 544
544 545 FormatterABC.register(BaseFormatter)
545 546 FormatterABC.register(PlainTextFormatter)
546 547 FormatterABC.register(HTMLFormatter)
547 548 FormatterABC.register(SVGFormatter)
548 549 FormatterABC.register(PNGFormatter)
549 550 FormatterABC.register(LatexFormatter)
550 551 FormatterABC.register(JSONFormatter)
551 552 FormatterABC.register(JavascriptFormatter)
552 553
553 554
554 555 def format_display_data(obj, include=None, exclude=None):
555 556 """Return a format data dict for an object.
556 557
557 558 By default all format types will be computed.
558 559
559 560 The following MIME types are currently implemented:
560 561
561 562 * text/plain
562 563 * text/html
563 564 * text/latex
564 565 * application/json
566 * application/javascript
565 567 * image/png
566 * immage/svg+xml
568 * image/svg+xml
567 569
568 570 Parameters
569 571 ----------
570 572 obj : object
571 573 The Python object whose format data will be computed.
572 574
573 575 Returns
574 576 -------
575 577 format_dict : dict
576 578 A dictionary of key/value pairs, one or each format that was
577 579 generated for the object. The keys are the format types, which
578 580 will usually be MIME type strings and the values and JSON'able
579 581 data structure containing the raw data for the representation in
580 582 that format.
581 583 include : list or tuple, optional
582 584 A list of format type strings (MIME types) to include in the
583 585 format data dict. If this is set *only* the format types included
584 586 in this list will be computed.
585 587 exclude : list or tuple, optional
586 588 A list of format type string (MIME types) to exclue in the format
587 589 data dict. If this is set all format types will be computed,
588 590 except for those included in this argument.
589 591 """
590 592 from IPython.core.interactiveshell import InteractiveShell
591 593
592 594 InteractiveShell.instance().display_formatter.format(
593 595 obj,
594 596 include,
595 597 exclude
596 598 )
General Comments 0
You need to be logged in to leave comments. Login now