##// END OF EJS Templates
Do not record memory addresses of display objects in repr
Jessica B. Hamrick -
Show More
@@ -1,779 +1,788 b''
1 # -*- coding: utf-8 -*-
1 # -*- coding: utf-8 -*-
2 """Top-level display functions for displaying object in different formats.
2 """Top-level display functions for displaying object in different formats.
3
3
4 Authors:
4 Authors:
5
5
6 * Brian Granger
6 * Brian Granger
7 """
7 """
8
8
9 #-----------------------------------------------------------------------------
9 #-----------------------------------------------------------------------------
10 # Copyright (C) 2013 The IPython Development Team
10 # Copyright (C) 2013 The IPython Development Team
11 #
11 #
12 # Distributed under the terms of the BSD License. The full license is in
12 # Distributed under the terms of the BSD License. The full license is in
13 # the file COPYING, distributed as part of this software.
13 # the file COPYING, distributed as part of this software.
14 #-----------------------------------------------------------------------------
14 #-----------------------------------------------------------------------------
15
15
16 #-----------------------------------------------------------------------------
16 #-----------------------------------------------------------------------------
17 # Imports
17 # Imports
18 #-----------------------------------------------------------------------------
18 #-----------------------------------------------------------------------------
19
19
20 from __future__ import print_function
20 from __future__ import print_function
21
21
22 import os
22 import os
23 import struct
23 import struct
24
24
25 from IPython.core.formatters import _safe_get_formatter_method
25 from IPython.core.formatters import _safe_get_formatter_method
26 from IPython.utils.py3compat import (string_types, cast_bytes_py2, cast_unicode,
26 from IPython.utils.py3compat import (string_types, cast_bytes_py2, cast_unicode,
27 unicode_type)
27 unicode_type)
28 from IPython.testing.skipdoctest import skip_doctest
28 from IPython.testing.skipdoctest import skip_doctest
29 from .displaypub import publish_display_data
29 from .displaypub import publish_display_data
30
30
31 #-----------------------------------------------------------------------------
31 #-----------------------------------------------------------------------------
32 # utility functions
32 # utility functions
33 #-----------------------------------------------------------------------------
33 #-----------------------------------------------------------------------------
34
34
35 def _safe_exists(path):
35 def _safe_exists(path):
36 """Check path, but don't let exceptions raise"""
36 """Check path, but don't let exceptions raise"""
37 try:
37 try:
38 return os.path.exists(path)
38 return os.path.exists(path)
39 except Exception:
39 except Exception:
40 return False
40 return False
41
41
42 def _merge(d1, d2):
42 def _merge(d1, d2):
43 """Like update, but merges sub-dicts instead of clobbering at the top level.
43 """Like update, but merges sub-dicts instead of clobbering at the top level.
44
44
45 Updates d1 in-place
45 Updates d1 in-place
46 """
46 """
47
47
48 if not isinstance(d2, dict) or not isinstance(d1, dict):
48 if not isinstance(d2, dict) or not isinstance(d1, dict):
49 return d2
49 return d2
50 for key, value in d2.items():
50 for key, value in d2.items():
51 d1[key] = _merge(d1.get(key), value)
51 d1[key] = _merge(d1.get(key), value)
52 return d1
52 return d1
53
53
54 def _display_mimetype(mimetype, objs, raw=False, metadata=None):
54 def _display_mimetype(mimetype, objs, raw=False, metadata=None):
55 """internal implementation of all display_foo methods
55 """internal implementation of all display_foo methods
56
56
57 Parameters
57 Parameters
58 ----------
58 ----------
59 mimetype : str
59 mimetype : str
60 The mimetype to be published (e.g. 'image/png')
60 The mimetype to be published (e.g. 'image/png')
61 objs : tuple of objects
61 objs : tuple of objects
62 The Python objects to display, or if raw=True raw text data to
62 The Python objects to display, or if raw=True raw text data to
63 display.
63 display.
64 raw : bool
64 raw : bool
65 Are the data objects raw data or Python objects that need to be
65 Are the data objects raw data or Python objects that need to be
66 formatted before display? [default: False]
66 formatted before display? [default: False]
67 metadata : dict (optional)
67 metadata : dict (optional)
68 Metadata to be associated with the specific mimetype output.
68 Metadata to be associated with the specific mimetype output.
69 """
69 """
70 if metadata:
70 if metadata:
71 metadata = {mimetype: metadata}
71 metadata = {mimetype: metadata}
72 if raw:
72 if raw:
73 # turn list of pngdata into list of { 'image/png': pngdata }
73 # turn list of pngdata into list of { 'image/png': pngdata }
74 objs = [ {mimetype: obj} for obj in objs ]
74 objs = [ {mimetype: obj} for obj in objs ]
75 display(*objs, raw=raw, metadata=metadata, include=[mimetype])
75 display(*objs, raw=raw, metadata=metadata, include=[mimetype])
76
76
77 #-----------------------------------------------------------------------------
77 #-----------------------------------------------------------------------------
78 # Main functions
78 # Main functions
79 #-----------------------------------------------------------------------------
79 #-----------------------------------------------------------------------------
80
80
81 def display(*objs, **kwargs):
81 def display(*objs, **kwargs):
82 """Display a Python object in all frontends.
82 """Display a Python object in all frontends.
83
83
84 By default all representations will be computed and sent to the frontends.
84 By default all representations will be computed and sent to the frontends.
85 Frontends can decide which representation is used and how.
85 Frontends can decide which representation is used and how.
86
86
87 Parameters
87 Parameters
88 ----------
88 ----------
89 objs : tuple of objects
89 objs : tuple of objects
90 The Python objects to display.
90 The Python objects to display.
91 raw : bool, optional
91 raw : bool, optional
92 Are the objects to be displayed already mimetype-keyed dicts of raw display data,
92 Are the objects to be displayed already mimetype-keyed dicts of raw display data,
93 or Python objects that need to be formatted before display? [default: False]
93 or Python objects that need to be formatted before display? [default: False]
94 include : list or tuple, optional
94 include : list or tuple, optional
95 A list of format type strings (MIME types) to include in the
95 A list of format type strings (MIME types) to include in the
96 format data dict. If this is set *only* the format types included
96 format data dict. If this is set *only* the format types included
97 in this list will be computed.
97 in this list will be computed.
98 exclude : list or tuple, optional
98 exclude : list or tuple, optional
99 A list of format type strings (MIME types) to exclude in the format
99 A list of format type strings (MIME types) to exclude in the format
100 data dict. If this is set all format types will be computed,
100 data dict. If this is set all format types will be computed,
101 except for those included in this argument.
101 except for those included in this argument.
102 metadata : dict, optional
102 metadata : dict, optional
103 A dictionary of metadata to associate with the output.
103 A dictionary of metadata to associate with the output.
104 mime-type keys in this dictionary will be associated with the individual
104 mime-type keys in this dictionary will be associated with the individual
105 representation formats, if they exist.
105 representation formats, if they exist.
106 """
106 """
107 raw = kwargs.get('raw', False)
107 raw = kwargs.get('raw', False)
108 include = kwargs.get('include')
108 include = kwargs.get('include')
109 exclude = kwargs.get('exclude')
109 exclude = kwargs.get('exclude')
110 metadata = kwargs.get('metadata')
110 metadata = kwargs.get('metadata')
111
111
112 from IPython.core.interactiveshell import InteractiveShell
112 from IPython.core.interactiveshell import InteractiveShell
113
113
114 if not raw:
114 if not raw:
115 format = InteractiveShell.instance().display_formatter.format
115 format = InteractiveShell.instance().display_formatter.format
116
116
117 for obj in objs:
117 for obj in objs:
118
118
119 # If _ipython_display_ is defined, use that to display this object.
119 # If _ipython_display_ is defined, use that to display this object.
120 display_method = _safe_get_formatter_method(obj, '_ipython_display_')
120 display_method = _safe_get_formatter_method(obj, '_ipython_display_')
121 if display_method is not None:
121 if display_method is not None:
122 try:
122 try:
123 display_method(**kwargs)
123 display_method(**kwargs)
124 except NotImplementedError:
124 except NotImplementedError:
125 pass
125 pass
126 else:
126 else:
127 continue
127 continue
128 if raw:
128 if raw:
129 publish_display_data('display', obj, metadata)
129 publish_display_data('display', obj, metadata)
130 else:
130 else:
131 format_dict, md_dict = format(obj, include=include, exclude=exclude)
131 format_dict, md_dict = format(obj, include=include, exclude=exclude)
132 if metadata:
132 if metadata:
133 # kwarg-specified metadata gets precedence
133 # kwarg-specified metadata gets precedence
134 _merge(md_dict, metadata)
134 _merge(md_dict, metadata)
135 publish_display_data('display', format_dict, md_dict)
135 publish_display_data('display', format_dict, md_dict)
136
136
137
137
138 def display_pretty(*objs, **kwargs):
138 def display_pretty(*objs, **kwargs):
139 """Display the pretty (default) representation of an object.
139 """Display the pretty (default) representation of an object.
140
140
141 Parameters
141 Parameters
142 ----------
142 ----------
143 objs : tuple of objects
143 objs : tuple of objects
144 The Python objects to display, or if raw=True raw text data to
144 The Python objects to display, or if raw=True raw text data to
145 display.
145 display.
146 raw : bool
146 raw : bool
147 Are the data objects raw data or Python objects that need to be
147 Are the data objects raw data or Python objects that need to be
148 formatted before display? [default: False]
148 formatted before display? [default: False]
149 metadata : dict (optional)
149 metadata : dict (optional)
150 Metadata to be associated with the specific mimetype output.
150 Metadata to be associated with the specific mimetype output.
151 """
151 """
152 _display_mimetype('text/plain', objs, **kwargs)
152 _display_mimetype('text/plain', objs, **kwargs)
153
153
154
154
155 def display_html(*objs, **kwargs):
155 def display_html(*objs, **kwargs):
156 """Display the HTML representation of an object.
156 """Display the HTML representation of an object.
157
157
158 Parameters
158 Parameters
159 ----------
159 ----------
160 objs : tuple of objects
160 objs : tuple of objects
161 The Python objects to display, or if raw=True raw HTML data to
161 The Python objects to display, or if raw=True raw HTML data to
162 display.
162 display.
163 raw : bool
163 raw : bool
164 Are the data objects raw data or Python objects that need to be
164 Are the data objects raw data or Python objects that need to be
165 formatted before display? [default: False]
165 formatted before display? [default: False]
166 metadata : dict (optional)
166 metadata : dict (optional)
167 Metadata to be associated with the specific mimetype output.
167 Metadata to be associated with the specific mimetype output.
168 """
168 """
169 _display_mimetype('text/html', objs, **kwargs)
169 _display_mimetype('text/html', objs, **kwargs)
170
170
171
171
172 def display_svg(*objs, **kwargs):
172 def display_svg(*objs, **kwargs):
173 """Display the SVG representation of an object.
173 """Display the SVG representation of an object.
174
174
175 Parameters
175 Parameters
176 ----------
176 ----------
177 objs : tuple of objects
177 objs : tuple of objects
178 The Python objects to display, or if raw=True raw svg data to
178 The Python objects to display, or if raw=True raw svg data to
179 display.
179 display.
180 raw : bool
180 raw : bool
181 Are the data objects raw data or Python objects that need to be
181 Are the data objects raw data or Python objects that need to be
182 formatted before display? [default: False]
182 formatted before display? [default: False]
183 metadata : dict (optional)
183 metadata : dict (optional)
184 Metadata to be associated with the specific mimetype output.
184 Metadata to be associated with the specific mimetype output.
185 """
185 """
186 _display_mimetype('image/svg+xml', objs, **kwargs)
186 _display_mimetype('image/svg+xml', objs, **kwargs)
187
187
188
188
189 def display_png(*objs, **kwargs):
189 def display_png(*objs, **kwargs):
190 """Display the PNG representation of an object.
190 """Display the PNG representation of an object.
191
191
192 Parameters
192 Parameters
193 ----------
193 ----------
194 objs : tuple of objects
194 objs : tuple of objects
195 The Python objects to display, or if raw=True raw png data to
195 The Python objects to display, or if raw=True raw png data to
196 display.
196 display.
197 raw : bool
197 raw : bool
198 Are the data objects raw data or Python objects that need to be
198 Are the data objects raw data or Python objects that need to be
199 formatted before display? [default: False]
199 formatted before display? [default: False]
200 metadata : dict (optional)
200 metadata : dict (optional)
201 Metadata to be associated with the specific mimetype output.
201 Metadata to be associated with the specific mimetype output.
202 """
202 """
203 _display_mimetype('image/png', objs, **kwargs)
203 _display_mimetype('image/png', objs, **kwargs)
204
204
205
205
206 def display_jpeg(*objs, **kwargs):
206 def display_jpeg(*objs, **kwargs):
207 """Display the JPEG representation of an object.
207 """Display the JPEG representation of an object.
208
208
209 Parameters
209 Parameters
210 ----------
210 ----------
211 objs : tuple of objects
211 objs : tuple of objects
212 The Python objects to display, or if raw=True raw JPEG data to
212 The Python objects to display, or if raw=True raw JPEG data to
213 display.
213 display.
214 raw : bool
214 raw : bool
215 Are the data objects raw data or Python objects that need to be
215 Are the data objects raw data or Python objects that need to be
216 formatted before display? [default: False]
216 formatted before display? [default: False]
217 metadata : dict (optional)
217 metadata : dict (optional)
218 Metadata to be associated with the specific mimetype output.
218 Metadata to be associated with the specific mimetype output.
219 """
219 """
220 _display_mimetype('image/jpeg', objs, **kwargs)
220 _display_mimetype('image/jpeg', objs, **kwargs)
221
221
222
222
223 def display_latex(*objs, **kwargs):
223 def display_latex(*objs, **kwargs):
224 """Display the LaTeX representation of an object.
224 """Display the LaTeX representation of an object.
225
225
226 Parameters
226 Parameters
227 ----------
227 ----------
228 objs : tuple of objects
228 objs : tuple of objects
229 The Python objects to display, or if raw=True raw latex data to
229 The Python objects to display, or if raw=True raw latex data to
230 display.
230 display.
231 raw : bool
231 raw : bool
232 Are the data objects raw data or Python objects that need to be
232 Are the data objects raw data or Python objects that need to be
233 formatted before display? [default: False]
233 formatted before display? [default: False]
234 metadata : dict (optional)
234 metadata : dict (optional)
235 Metadata to be associated with the specific mimetype output.
235 Metadata to be associated with the specific mimetype output.
236 """
236 """
237 _display_mimetype('text/latex', objs, **kwargs)
237 _display_mimetype('text/latex', objs, **kwargs)
238
238
239
239
240 def display_json(*objs, **kwargs):
240 def display_json(*objs, **kwargs):
241 """Display the JSON representation of an object.
241 """Display the JSON representation of an object.
242
242
243 Note that not many frontends support displaying JSON.
243 Note that not many frontends support displaying JSON.
244
244
245 Parameters
245 Parameters
246 ----------
246 ----------
247 objs : tuple of objects
247 objs : tuple of objects
248 The Python objects to display, or if raw=True raw json data to
248 The Python objects to display, or if raw=True raw json data to
249 display.
249 display.
250 raw : bool
250 raw : bool
251 Are the data objects raw data or Python objects that need to be
251 Are the data objects raw data or Python objects that need to be
252 formatted before display? [default: False]
252 formatted before display? [default: False]
253 metadata : dict (optional)
253 metadata : dict (optional)
254 Metadata to be associated with the specific mimetype output.
254 Metadata to be associated with the specific mimetype output.
255 """
255 """
256 _display_mimetype('application/json', objs, **kwargs)
256 _display_mimetype('application/json', objs, **kwargs)
257
257
258
258
259 def display_javascript(*objs, **kwargs):
259 def display_javascript(*objs, **kwargs):
260 """Display the Javascript representation of an object.
260 """Display the Javascript representation of an object.
261
261
262 Parameters
262 Parameters
263 ----------
263 ----------
264 objs : tuple of objects
264 objs : tuple of objects
265 The Python objects to display, or if raw=True raw javascript data to
265 The Python objects to display, or if raw=True raw javascript data to
266 display.
266 display.
267 raw : bool
267 raw : bool
268 Are the data objects raw data or Python objects that need to be
268 Are the data objects raw data or Python objects that need to be
269 formatted before display? [default: False]
269 formatted before display? [default: False]
270 metadata : dict (optional)
270 metadata : dict (optional)
271 Metadata to be associated with the specific mimetype output.
271 Metadata to be associated with the specific mimetype output.
272 """
272 """
273 _display_mimetype('application/javascript', objs, **kwargs)
273 _display_mimetype('application/javascript', objs, **kwargs)
274
274
275
275
276 def display_pdf(*objs, **kwargs):
276 def display_pdf(*objs, **kwargs):
277 """Display the PDF representation of an object.
277 """Display the PDF representation of an object.
278
278
279 Parameters
279 Parameters
280 ----------
280 ----------
281 objs : tuple of objects
281 objs : tuple of objects
282 The Python objects to display, or if raw=True raw javascript data to
282 The Python objects to display, or if raw=True raw javascript data to
283 display.
283 display.
284 raw : bool
284 raw : bool
285 Are the data objects raw data or Python objects that need to be
285 Are the data objects raw data or Python objects that need to be
286 formatted before display? [default: False]
286 formatted before display? [default: False]
287 metadata : dict (optional)
287 metadata : dict (optional)
288 Metadata to be associated with the specific mimetype output.
288 Metadata to be associated with the specific mimetype output.
289 """
289 """
290 _display_mimetype('application/pdf', objs, **kwargs)
290 _display_mimetype('application/pdf', objs, **kwargs)
291
291
292
292
293 #-----------------------------------------------------------------------------
293 #-----------------------------------------------------------------------------
294 # Smart classes
294 # Smart classes
295 #-----------------------------------------------------------------------------
295 #-----------------------------------------------------------------------------
296
296
297
297
298 class DisplayObject(object):
298 class DisplayObject(object):
299 """An object that wraps data to be displayed."""
299 """An object that wraps data to be displayed."""
300
300
301 _read_flags = 'r'
301 _read_flags = 'r'
302 _show_mem_addr = False
302
303
303 def __init__(self, data=None, url=None, filename=None):
304 def __init__(self, data=None, url=None, filename=None):
304 """Create a display object given raw data.
305 """Create a display object given raw data.
305
306
306 When this object is returned by an expression or passed to the
307 When this object is returned by an expression or passed to the
307 display function, it will result in the data being displayed
308 display function, it will result in the data being displayed
308 in the frontend. The MIME type of the data should match the
309 in the frontend. The MIME type of the data should match the
309 subclasses used, so the Png subclass should be used for 'image/png'
310 subclasses used, so the Png subclass should be used for 'image/png'
310 data. If the data is a URL, the data will first be downloaded
311 data. If the data is a URL, the data will first be downloaded
311 and then displayed. If
312 and then displayed. If
312
313
313 Parameters
314 Parameters
314 ----------
315 ----------
315 data : unicode, str or bytes
316 data : unicode, str or bytes
316 The raw data or a URL or file to load the data from
317 The raw data or a URL or file to load the data from
317 url : unicode
318 url : unicode
318 A URL to download the data from.
319 A URL to download the data from.
319 filename : unicode
320 filename : unicode
320 Path to a local file to load the data from.
321 Path to a local file to load the data from.
321 """
322 """
322 if data is not None and isinstance(data, string_types):
323 if data is not None and isinstance(data, string_types):
323 if data.startswith('http') and url is None:
324 if data.startswith('http') and url is None:
324 url = data
325 url = data
325 filename = None
326 filename = None
326 data = None
327 data = None
327 elif _safe_exists(data) and filename is None:
328 elif _safe_exists(data) and filename is None:
328 url = None
329 url = None
329 filename = data
330 filename = data
330 data = None
331 data = None
331
332
332 self.data = data
333 self.data = data
333 self.url = url
334 self.url = url
334 self.filename = None if filename is None else unicode_type(filename)
335 self.filename = None if filename is None else unicode_type(filename)
335
336
336 self.reload()
337 self.reload()
337 self._check_data()
338 self._check_data()
338
339
340 def __repr__(self):
341 if not self._show_mem_addr:
342 cls = self.__class__
343 r = "<%s.%s object>" % (cls.__module__, cls.__name__)
344 else:
345 r = super(DisplayObject, self).__repr__()
346 return r
347
339 def _check_data(self):
348 def _check_data(self):
340 """Override in subclasses if there's something to check."""
349 """Override in subclasses if there's something to check."""
341 pass
350 pass
342
351
343 def reload(self):
352 def reload(self):
344 """Reload the raw data from file or URL."""
353 """Reload the raw data from file or URL."""
345 if self.filename is not None:
354 if self.filename is not None:
346 with open(self.filename, self._read_flags) as f:
355 with open(self.filename, self._read_flags) as f:
347 self.data = f.read()
356 self.data = f.read()
348 elif self.url is not None:
357 elif self.url is not None:
349 try:
358 try:
350 try:
359 try:
351 from urllib.request import urlopen # Py3
360 from urllib.request import urlopen # Py3
352 except ImportError:
361 except ImportError:
353 from urllib2 import urlopen
362 from urllib2 import urlopen
354 response = urlopen(self.url)
363 response = urlopen(self.url)
355 self.data = response.read()
364 self.data = response.read()
356 # extract encoding from header, if there is one:
365 # extract encoding from header, if there is one:
357 encoding = None
366 encoding = None
358 for sub in response.headers['content-type'].split(';'):
367 for sub in response.headers['content-type'].split(';'):
359 sub = sub.strip()
368 sub = sub.strip()
360 if sub.startswith('charset'):
369 if sub.startswith('charset'):
361 encoding = sub.split('=')[-1].strip()
370 encoding = sub.split('=')[-1].strip()
362 break
371 break
363 # decode data, if an encoding was specified
372 # decode data, if an encoding was specified
364 if encoding:
373 if encoding:
365 self.data = self.data.decode(encoding, 'replace')
374 self.data = self.data.decode(encoding, 'replace')
366 except:
375 except:
367 self.data = None
376 self.data = None
368
377
369 class TextDisplayObject(DisplayObject):
378 class TextDisplayObject(DisplayObject):
370 """Validate that display data is text"""
379 """Validate that display data is text"""
371 def _check_data(self):
380 def _check_data(self):
372 if self.data is not None and not isinstance(self.data, string_types):
381 if self.data is not None and not isinstance(self.data, string_types):
373 raise TypeError("%s expects text, not %r" % (self.__class__.__name__, self.data))
382 raise TypeError("%s expects text, not %r" % (self.__class__.__name__, self.data))
374
383
375 class Pretty(TextDisplayObject):
384 class Pretty(TextDisplayObject):
376
385
377 def _repr_pretty_(self):
386 def _repr_pretty_(self):
378 return self.data
387 return self.data
379
388
380
389
381 class HTML(TextDisplayObject):
390 class HTML(TextDisplayObject):
382
391
383 def _repr_html_(self):
392 def _repr_html_(self):
384 return self.data
393 return self.data
385
394
386 def __html__(self):
395 def __html__(self):
387 """
396 """
388 This method exists to inform other HTML-using modules (e.g. Markupsafe,
397 This method exists to inform other HTML-using modules (e.g. Markupsafe,
389 htmltag, etc) that this object is HTML and does not need things like
398 htmltag, etc) that this object is HTML and does not need things like
390 special characters (<>&) escaped.
399 special characters (<>&) escaped.
391 """
400 """
392 return self._repr_html_()
401 return self._repr_html_()
393
402
394
403
395 class Math(TextDisplayObject):
404 class Math(TextDisplayObject):
396
405
397 def _repr_latex_(self):
406 def _repr_latex_(self):
398 s = self.data.strip('$')
407 s = self.data.strip('$')
399 return "$$%s$$" % s
408 return "$$%s$$" % s
400
409
401
410
402 class Latex(TextDisplayObject):
411 class Latex(TextDisplayObject):
403
412
404 def _repr_latex_(self):
413 def _repr_latex_(self):
405 return self.data
414 return self.data
406
415
407
416
408 class SVG(DisplayObject):
417 class SVG(DisplayObject):
409
418
410 # wrap data in a property, which extracts the <svg> tag, discarding
419 # wrap data in a property, which extracts the <svg> tag, discarding
411 # document headers
420 # document headers
412 _data = None
421 _data = None
413
422
414 @property
423 @property
415 def data(self):
424 def data(self):
416 return self._data
425 return self._data
417
426
418 @data.setter
427 @data.setter
419 def data(self, svg):
428 def data(self, svg):
420 if svg is None:
429 if svg is None:
421 self._data = None
430 self._data = None
422 return
431 return
423 # parse into dom object
432 # parse into dom object
424 from xml.dom import minidom
433 from xml.dom import minidom
425 svg = cast_bytes_py2(svg)
434 svg = cast_bytes_py2(svg)
426 x = minidom.parseString(svg)
435 x = minidom.parseString(svg)
427 # get svg tag (should be 1)
436 # get svg tag (should be 1)
428 found_svg = x.getElementsByTagName('svg')
437 found_svg = x.getElementsByTagName('svg')
429 if found_svg:
438 if found_svg:
430 svg = found_svg[0].toxml()
439 svg = found_svg[0].toxml()
431 else:
440 else:
432 # fallback on the input, trust the user
441 # fallback on the input, trust the user
433 # but this is probably an error.
442 # but this is probably an error.
434 pass
443 pass
435 svg = cast_unicode(svg)
444 svg = cast_unicode(svg)
436 self._data = svg
445 self._data = svg
437
446
438 def _repr_svg_(self):
447 def _repr_svg_(self):
439 return self.data
448 return self.data
440
449
441
450
442 class JSON(TextDisplayObject):
451 class JSON(TextDisplayObject):
443
452
444 def _repr_json_(self):
453 def _repr_json_(self):
445 return self.data
454 return self.data
446
455
447 css_t = """$("head").append($("<link/>").attr({
456 css_t = """$("head").append($("<link/>").attr({
448 rel: "stylesheet",
457 rel: "stylesheet",
449 type: "text/css",
458 type: "text/css",
450 href: "%s"
459 href: "%s"
451 }));
460 }));
452 """
461 """
453
462
454 lib_t1 = """$.getScript("%s", function () {
463 lib_t1 = """$.getScript("%s", function () {
455 """
464 """
456 lib_t2 = """});
465 lib_t2 = """});
457 """
466 """
458
467
459 class Javascript(TextDisplayObject):
468 class Javascript(TextDisplayObject):
460
469
461 def __init__(self, data=None, url=None, filename=None, lib=None, css=None):
470 def __init__(self, data=None, url=None, filename=None, lib=None, css=None):
462 """Create a Javascript display object given raw data.
471 """Create a Javascript display object given raw data.
463
472
464 When this object is returned by an expression or passed to the
473 When this object is returned by an expression or passed to the
465 display function, it will result in the data being displayed
474 display function, it will result in the data being displayed
466 in the frontend. If the data is a URL, the data will first be
475 in the frontend. If the data is a URL, the data will first be
467 downloaded and then displayed.
476 downloaded and then displayed.
468
477
469 In the Notebook, the containing element will be available as `element`,
478 In the Notebook, the containing element will be available as `element`,
470 and jQuery will be available. The output area starts hidden, so if
479 and jQuery will be available. The output area starts hidden, so if
471 the js appends content to `element` that should be visible, then
480 the js appends content to `element` that should be visible, then
472 it must call `container.show()` to unhide the area.
481 it must call `container.show()` to unhide the area.
473
482
474 Parameters
483 Parameters
475 ----------
484 ----------
476 data : unicode, str or bytes
485 data : unicode, str or bytes
477 The Javascript source code or a URL to download it from.
486 The Javascript source code or a URL to download it from.
478 url : unicode
487 url : unicode
479 A URL to download the data from.
488 A URL to download the data from.
480 filename : unicode
489 filename : unicode
481 Path to a local file to load the data from.
490 Path to a local file to load the data from.
482 lib : list or str
491 lib : list or str
483 A sequence of Javascript library URLs to load asynchronously before
492 A sequence of Javascript library URLs to load asynchronously before
484 running the source code. The full URLs of the libraries should
493 running the source code. The full URLs of the libraries should
485 be given. A single Javascript library URL can also be given as a
494 be given. A single Javascript library URL can also be given as a
486 string.
495 string.
487 css: : list or str
496 css: : list or str
488 A sequence of css files to load before running the source code.
497 A sequence of css files to load before running the source code.
489 The full URLs of the css files should be given. A single css URL
498 The full URLs of the css files should be given. A single css URL
490 can also be given as a string.
499 can also be given as a string.
491 """
500 """
492 if isinstance(lib, string_types):
501 if isinstance(lib, string_types):
493 lib = [lib]
502 lib = [lib]
494 elif lib is None:
503 elif lib is None:
495 lib = []
504 lib = []
496 if isinstance(css, string_types):
505 if isinstance(css, string_types):
497 css = [css]
506 css = [css]
498 elif css is None:
507 elif css is None:
499 css = []
508 css = []
500 if not isinstance(lib, (list,tuple)):
509 if not isinstance(lib, (list,tuple)):
501 raise TypeError('expected sequence, got: %r' % lib)
510 raise TypeError('expected sequence, got: %r' % lib)
502 if not isinstance(css, (list,tuple)):
511 if not isinstance(css, (list,tuple)):
503 raise TypeError('expected sequence, got: %r' % css)
512 raise TypeError('expected sequence, got: %r' % css)
504 self.lib = lib
513 self.lib = lib
505 self.css = css
514 self.css = css
506 super(Javascript, self).__init__(data=data, url=url, filename=filename)
515 super(Javascript, self).__init__(data=data, url=url, filename=filename)
507
516
508 def _repr_javascript_(self):
517 def _repr_javascript_(self):
509 r = ''
518 r = ''
510 for c in self.css:
519 for c in self.css:
511 r += css_t % c
520 r += css_t % c
512 for l in self.lib:
521 for l in self.lib:
513 r += lib_t1 % l
522 r += lib_t1 % l
514 r += self.data
523 r += self.data
515 r += lib_t2*len(self.lib)
524 r += lib_t2*len(self.lib)
516 return r
525 return r
517
526
518 # constants for identifying png/jpeg data
527 # constants for identifying png/jpeg data
519 _PNG = b'\x89PNG\r\n\x1a\n'
528 _PNG = b'\x89PNG\r\n\x1a\n'
520 _JPEG = b'\xff\xd8'
529 _JPEG = b'\xff\xd8'
521
530
522 def _pngxy(data):
531 def _pngxy(data):
523 """read the (width, height) from a PNG header"""
532 """read the (width, height) from a PNG header"""
524 ihdr = data.index(b'IHDR')
533 ihdr = data.index(b'IHDR')
525 # next 8 bytes are width/height
534 # next 8 bytes are width/height
526 w4h4 = data[ihdr+4:ihdr+12]
535 w4h4 = data[ihdr+4:ihdr+12]
527 return struct.unpack('>ii', w4h4)
536 return struct.unpack('>ii', w4h4)
528
537
529 def _jpegxy(data):
538 def _jpegxy(data):
530 """read the (width, height) from a JPEG header"""
539 """read the (width, height) from a JPEG header"""
531 # adapted from http://www.64lines.com/jpeg-width-height
540 # adapted from http://www.64lines.com/jpeg-width-height
532
541
533 idx = 4
542 idx = 4
534 while True:
543 while True:
535 block_size = struct.unpack('>H', data[idx:idx+2])[0]
544 block_size = struct.unpack('>H', data[idx:idx+2])[0]
536 idx = idx + block_size
545 idx = idx + block_size
537 if data[idx:idx+2] == b'\xFF\xC0':
546 if data[idx:idx+2] == b'\xFF\xC0':
538 # found Start of Frame
547 # found Start of Frame
539 iSOF = idx
548 iSOF = idx
540 break
549 break
541 else:
550 else:
542 # read another block
551 # read another block
543 idx += 2
552 idx += 2
544
553
545 h, w = struct.unpack('>HH', data[iSOF+5:iSOF+9])
554 h, w = struct.unpack('>HH', data[iSOF+5:iSOF+9])
546 return w, h
555 return w, h
547
556
548 class Image(DisplayObject):
557 class Image(DisplayObject):
549
558
550 _read_flags = 'rb'
559 _read_flags = 'rb'
551 _FMT_JPEG = u'jpeg'
560 _FMT_JPEG = u'jpeg'
552 _FMT_PNG = u'png'
561 _FMT_PNG = u'png'
553 _ACCEPTABLE_EMBEDDINGS = [_FMT_JPEG, _FMT_PNG]
562 _ACCEPTABLE_EMBEDDINGS = [_FMT_JPEG, _FMT_PNG]
554
563
555 def __init__(self, data=None, url=None, filename=None, format=u'png', embed=None, width=None, height=None, retina=False):
564 def __init__(self, data=None, url=None, filename=None, format=u'png', embed=None, width=None, height=None, retina=False):
556 """Create a PNG/JPEG image object given raw data.
565 """Create a PNG/JPEG image object given raw data.
557
566
558 When this object is returned by an input cell or passed to the
567 When this object is returned by an input cell or passed to the
559 display function, it will result in the image being displayed
568 display function, it will result in the image being displayed
560 in the frontend.
569 in the frontend.
561
570
562 Parameters
571 Parameters
563 ----------
572 ----------
564 data : unicode, str or bytes
573 data : unicode, str or bytes
565 The raw image data or a URL or filename to load the data from.
574 The raw image data or a URL or filename to load the data from.
566 This always results in embedded image data.
575 This always results in embedded image data.
567 url : unicode
576 url : unicode
568 A URL to download the data from. If you specify `url=`,
577 A URL to download the data from. If you specify `url=`,
569 the image data will not be embedded unless you also specify `embed=True`.
578 the image data will not be embedded unless you also specify `embed=True`.
570 filename : unicode
579 filename : unicode
571 Path to a local file to load the data from.
580 Path to a local file to load the data from.
572 Images from a file are always embedded.
581 Images from a file are always embedded.
573 format : unicode
582 format : unicode
574 The format of the image data (png/jpeg/jpg). If a filename or URL is given
583 The format of the image data (png/jpeg/jpg). If a filename or URL is given
575 for format will be inferred from the filename extension.
584 for format will be inferred from the filename extension.
576 embed : bool
585 embed : bool
577 Should the image data be embedded using a data URI (True) or be
586 Should the image data be embedded using a data URI (True) or be
578 loaded using an <img> tag. Set this to True if you want the image
587 loaded using an <img> tag. Set this to True if you want the image
579 to be viewable later with no internet connection in the notebook.
588 to be viewable later with no internet connection in the notebook.
580
589
581 Default is `True`, unless the keyword argument `url` is set, then
590 Default is `True`, unless the keyword argument `url` is set, then
582 default value is `False`.
591 default value is `False`.
583
592
584 Note that QtConsole is not able to display images if `embed` is set to `False`
593 Note that QtConsole is not able to display images if `embed` is set to `False`
585 width : int
594 width : int
586 Width to which to constrain the image in html
595 Width to which to constrain the image in html
587 height : int
596 height : int
588 Height to which to constrain the image in html
597 Height to which to constrain the image in html
589 retina : bool
598 retina : bool
590 Automatically set the width and height to half of the measured
599 Automatically set the width and height to half of the measured
591 width and height.
600 width and height.
592 This only works for embedded images because it reads the width/height
601 This only works for embedded images because it reads the width/height
593 from image data.
602 from image data.
594 For non-embedded images, you can just set the desired display width
603 For non-embedded images, you can just set the desired display width
595 and height directly.
604 and height directly.
596
605
597 Examples
606 Examples
598 --------
607 --------
599 # embedded image data, works in qtconsole and notebook
608 # embedded image data, works in qtconsole and notebook
600 # when passed positionally, the first arg can be any of raw image data,
609 # when passed positionally, the first arg can be any of raw image data,
601 # a URL, or a filename from which to load image data.
610 # a URL, or a filename from which to load image data.
602 # The result is always embedding image data for inline images.
611 # The result is always embedding image data for inline images.
603 Image('http://www.google.fr/images/srpr/logo3w.png')
612 Image('http://www.google.fr/images/srpr/logo3w.png')
604 Image('/path/to/image.jpg')
613 Image('/path/to/image.jpg')
605 Image(b'RAW_PNG_DATA...')
614 Image(b'RAW_PNG_DATA...')
606
615
607 # Specifying Image(url=...) does not embed the image data,
616 # Specifying Image(url=...) does not embed the image data,
608 # it only generates `<img>` tag with a link to the source.
617 # it only generates `<img>` tag with a link to the source.
609 # This will not work in the qtconsole or offline.
618 # This will not work in the qtconsole or offline.
610 Image(url='http://www.google.fr/images/srpr/logo3w.png')
619 Image(url='http://www.google.fr/images/srpr/logo3w.png')
611
620
612 """
621 """
613 if filename is not None:
622 if filename is not None:
614 ext = self._find_ext(filename)
623 ext = self._find_ext(filename)
615 elif url is not None:
624 elif url is not None:
616 ext = self._find_ext(url)
625 ext = self._find_ext(url)
617 elif data is None:
626 elif data is None:
618 raise ValueError("No image data found. Expecting filename, url, or data.")
627 raise ValueError("No image data found. Expecting filename, url, or data.")
619 elif isinstance(data, string_types) and (
628 elif isinstance(data, string_types) and (
620 data.startswith('http') or _safe_exists(data)
629 data.startswith('http') or _safe_exists(data)
621 ):
630 ):
622 ext = self._find_ext(data)
631 ext = self._find_ext(data)
623 else:
632 else:
624 ext = None
633 ext = None
625
634
626 if ext is not None:
635 if ext is not None:
627 format = ext.lower()
636 format = ext.lower()
628 if ext == u'jpg' or ext == u'jpeg':
637 if ext == u'jpg' or ext == u'jpeg':
629 format = self._FMT_JPEG
638 format = self._FMT_JPEG
630 if ext == u'png':
639 if ext == u'png':
631 format = self._FMT_PNG
640 format = self._FMT_PNG
632 elif isinstance(data, bytes) and format == 'png':
641 elif isinstance(data, bytes) and format == 'png':
633 # infer image type from image data header,
642 # infer image type from image data header,
634 # only if format might not have been specified.
643 # only if format might not have been specified.
635 if data[:2] == _JPEG:
644 if data[:2] == _JPEG:
636 format = 'jpeg'
645 format = 'jpeg'
637
646
638 self.format = unicode_type(format).lower()
647 self.format = unicode_type(format).lower()
639 self.embed = embed if embed is not None else (url is None)
648 self.embed = embed if embed is not None else (url is None)
640
649
641 if self.embed and self.format not in self._ACCEPTABLE_EMBEDDINGS:
650 if self.embed and self.format not in self._ACCEPTABLE_EMBEDDINGS:
642 raise ValueError("Cannot embed the '%s' image format" % (self.format))
651 raise ValueError("Cannot embed the '%s' image format" % (self.format))
643 self.width = width
652 self.width = width
644 self.height = height
653 self.height = height
645 self.retina = retina
654 self.retina = retina
646 super(Image, self).__init__(data=data, url=url, filename=filename)
655 super(Image, self).__init__(data=data, url=url, filename=filename)
647
656
648 if retina:
657 if retina:
649 self._retina_shape()
658 self._retina_shape()
650
659
651 def _retina_shape(self):
660 def _retina_shape(self):
652 """load pixel-doubled width and height from image data"""
661 """load pixel-doubled width and height from image data"""
653 if not self.embed:
662 if not self.embed:
654 return
663 return
655 if self.format == 'png':
664 if self.format == 'png':
656 w, h = _pngxy(self.data)
665 w, h = _pngxy(self.data)
657 elif self.format == 'jpeg':
666 elif self.format == 'jpeg':
658 w, h = _jpegxy(self.data)
667 w, h = _jpegxy(self.data)
659 else:
668 else:
660 # retina only supports png
669 # retina only supports png
661 return
670 return
662 self.width = w // 2
671 self.width = w // 2
663 self.height = h // 2
672 self.height = h // 2
664
673
665 def reload(self):
674 def reload(self):
666 """Reload the raw data from file or URL."""
675 """Reload the raw data from file or URL."""
667 if self.embed:
676 if self.embed:
668 super(Image,self).reload()
677 super(Image,self).reload()
669 if self.retina:
678 if self.retina:
670 self._retina_shape()
679 self._retina_shape()
671
680
672 def _repr_html_(self):
681 def _repr_html_(self):
673 if not self.embed:
682 if not self.embed:
674 width = height = ''
683 width = height = ''
675 if self.width:
684 if self.width:
676 width = ' width="%d"' % self.width
685 width = ' width="%d"' % self.width
677 if self.height:
686 if self.height:
678 height = ' height="%d"' % self.height
687 height = ' height="%d"' % self.height
679 return u'<img src="%s"%s%s/>' % (self.url, width, height)
688 return u'<img src="%s"%s%s/>' % (self.url, width, height)
680
689
681 def _data_and_metadata(self):
690 def _data_and_metadata(self):
682 """shortcut for returning metadata with shape information, if defined"""
691 """shortcut for returning metadata with shape information, if defined"""
683 md = {}
692 md = {}
684 if self.width:
693 if self.width:
685 md['width'] = self.width
694 md['width'] = self.width
686 if self.height:
695 if self.height:
687 md['height'] = self.height
696 md['height'] = self.height
688 if md:
697 if md:
689 return self.data, md
698 return self.data, md
690 else:
699 else:
691 return self.data
700 return self.data
692
701
693 def _repr_png_(self):
702 def _repr_png_(self):
694 if self.embed and self.format == u'png':
703 if self.embed and self.format == u'png':
695 return self._data_and_metadata()
704 return self._data_and_metadata()
696
705
697 def _repr_jpeg_(self):
706 def _repr_jpeg_(self):
698 if self.embed and (self.format == u'jpeg' or self.format == u'jpg'):
707 if self.embed and (self.format == u'jpeg' or self.format == u'jpg'):
699 return self._data_and_metadata()
708 return self._data_and_metadata()
700
709
701 def _find_ext(self, s):
710 def _find_ext(self, s):
702 return unicode_type(s.split('.')[-1].lower())
711 return unicode_type(s.split('.')[-1].lower())
703
712
704
713
705 def clear_output(wait=False):
714 def clear_output(wait=False):
706 """Clear the output of the current cell receiving output.
715 """Clear the output of the current cell receiving output.
707
716
708 Parameters
717 Parameters
709 ----------
718 ----------
710 wait : bool [default: false]
719 wait : bool [default: false]
711 Wait to clear the output until new output is available to replace it."""
720 Wait to clear the output until new output is available to replace it."""
712 from IPython.core.interactiveshell import InteractiveShell
721 from IPython.core.interactiveshell import InteractiveShell
713 if InteractiveShell.initialized():
722 if InteractiveShell.initialized():
714 InteractiveShell.instance().display_pub.clear_output(wait)
723 InteractiveShell.instance().display_pub.clear_output(wait)
715 else:
724 else:
716 from IPython.utils import io
725 from IPython.utils import io
717 print('\033[2K\r', file=io.stdout, end='')
726 print('\033[2K\r', file=io.stdout, end='')
718 io.stdout.flush()
727 io.stdout.flush()
719 print('\033[2K\r', file=io.stderr, end='')
728 print('\033[2K\r', file=io.stderr, end='')
720 io.stderr.flush()
729 io.stderr.flush()
721
730
722
731
723 @skip_doctest
732 @skip_doctest
724 def set_matplotlib_formats(*formats, **kwargs):
733 def set_matplotlib_formats(*formats, **kwargs):
725 """Select figure formats for the inline backend. Optionally pass quality for JPEG.
734 """Select figure formats for the inline backend. Optionally pass quality for JPEG.
726
735
727 For example, this enables PNG and JPEG output with a JPEG quality of 90%::
736 For example, this enables PNG and JPEG output with a JPEG quality of 90%::
728
737
729 In [1]: set_matplotlib_formats('png', 'jpeg', quality=90)
738 In [1]: set_matplotlib_formats('png', 'jpeg', quality=90)
730
739
731 To set this in your config files use the following::
740 To set this in your config files use the following::
732
741
733 c.InlineBackend.figure_formats = {'png', 'jpeg'}
742 c.InlineBackend.figure_formats = {'png', 'jpeg'}
734 c.InlineBackend.print_figure_kwargs.update({'quality' : 90})
743 c.InlineBackend.print_figure_kwargs.update({'quality' : 90})
735
744
736 Parameters
745 Parameters
737 ----------
746 ----------
738 *formats : strs
747 *formats : strs
739 One or more figure formats to enable: 'png', 'retina', 'jpeg', 'svg', 'pdf'.
748 One or more figure formats to enable: 'png', 'retina', 'jpeg', 'svg', 'pdf'.
740 **kwargs :
749 **kwargs :
741 Keyword args will be relayed to ``figure.canvas.print_figure``.
750 Keyword args will be relayed to ``figure.canvas.print_figure``.
742 """
751 """
743 from IPython.core.interactiveshell import InteractiveShell
752 from IPython.core.interactiveshell import InteractiveShell
744 from IPython.core.pylabtools import select_figure_formats
753 from IPython.core.pylabtools import select_figure_formats
745 from IPython.kernel.zmq.pylab.config import InlineBackend
754 from IPython.kernel.zmq.pylab.config import InlineBackend
746 # build kwargs, starting with InlineBackend config
755 # build kwargs, starting with InlineBackend config
747 kw = {}
756 kw = {}
748 cfg = InlineBackend.instance()
757 cfg = InlineBackend.instance()
749 kw.update(cfg.print_figure_kwargs)
758 kw.update(cfg.print_figure_kwargs)
750 kw.update(**kwargs)
759 kw.update(**kwargs)
751 shell = InteractiveShell.instance()
760 shell = InteractiveShell.instance()
752 select_figure_formats(shell, formats, **kw)
761 select_figure_formats(shell, formats, **kw)
753
762
754 @skip_doctest
763 @skip_doctest
755 def set_matplotlib_close(close=True):
764 def set_matplotlib_close(close=True):
756 """Set whether the inline backend closes all figures automatically or not.
765 """Set whether the inline backend closes all figures automatically or not.
757
766
758 By default, the inline backend used in the IPython Notebook will close all
767 By default, the inline backend used in the IPython Notebook will close all
759 matplotlib figures automatically after each cell is run. This means that
768 matplotlib figures automatically after each cell is run. This means that
760 plots in different cells won't interfere. Sometimes, you may want to make
769 plots in different cells won't interfere. Sometimes, you may want to make
761 a plot in one cell and then refine it in later cells. This can be accomplished
770 a plot in one cell and then refine it in later cells. This can be accomplished
762 by::
771 by::
763
772
764 In [1]: set_matplotlib_close(False)
773 In [1]: set_matplotlib_close(False)
765
774
766 To set this in your config files use the following::
775 To set this in your config files use the following::
767
776
768 c.InlineBackend.close_figures = False
777 c.InlineBackend.close_figures = False
769
778
770 Parameters
779 Parameters
771 ----------
780 ----------
772 close : bool
781 close : bool
773 Should all matplotlib figures be automatically closed after each cell is
782 Should all matplotlib figures be automatically closed after each cell is
774 run?
783 run?
775 """
784 """
776 from IPython.kernel.zmq.pylab.config import InlineBackend
785 from IPython.kernel.zmq.pylab.config import InlineBackend
777 cfg = InlineBackend.instance()
786 cfg = InlineBackend.instance()
778 cfg.close_figures = close
787 cfg.close_figures = close
779
788
General Comments 0
You need to be logged in to leave comments. Login now