##// END OF EJS Templates
Merge pull request #2231 from Carreau/ja...
Bussonnier Matthias -
r8116:19feb23c merge
parent child Browse files
Show More
@@ -0,0 +1,38 b''
1 #-----------------------------------------------------------------------------
2 # Copyright (C) 2010-2011 The IPython Development Team.
3 #
4 # Distributed under the terms of the BSD License.
5 #
6 # The full license is in the file COPYING.txt, distributed with this software.
7 #-----------------------------------------------------------------------------
8 import os
9
10 import nose.tools as nt
11
12 from IPython.core import display
13 from IPython.utils import path as ipath
14
15 def test_image_size():
16 """Simple test for display.Image(args, width=x,height=y)"""
17 thisurl = 'http://www.google.fr/images/srpr/logo3w.png'
18 img = display.Image(url=thisurl, width=200, height=200)
19 nt.assert_equal(u'<img src="%s" width="200" height="200"/>' % (thisurl), img._repr_html_())
20 img = display.Image(url=thisurl, width=200)
21 nt.assert_equal(u'<img src="%s" width="200"/>' % (thisurl), img._repr_html_())
22 img = display.Image(url=thisurl)
23 nt.assert_equal(u'<img src="%s"/>' % (thisurl), img._repr_html_())
24
25 def test_image_filename_defaults():
26 '''test format constraint, and validity of jpeg and png'''
27 tpath = ipath.get_ipython_package_dir()
28 nt.assert_raises(ValueError, display.Image, filename=os.path.join(tpath, 'testing/tests/badformat.gif'),
29 embed=True)
30 nt.assert_raises(ValueError, display.Image)
31 nt.assert_raises(ValueError, display.Image, data='this is not an image', format='badformat', embed=True)
32 imgfile = os.path.join(tpath, 'frontend/html/notebook/static/ipynblogo.png')
33 img = display.Image(filename=imgfile)
34 nt.assert_equal('png', img.format)
35 nt.assert_is_not_none(img._repr_png_())
36 img = display.Image(filename=os.path.join(tpath, 'testing/tests/logo.jpg'), embed=False)
37 nt.assert_equal('jpeg', img.format)
38 nt.assert_is_none(img._repr_jpeg_())
@@ -1,534 +1,556 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) 2008-2011 The IPython Development Team
10 # Copyright (C) 2008-2011 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 from xml.dom import minidom
22 from xml.dom import minidom
23
23
24 from .displaypub import (
24 from .displaypub import (
25 publish_pretty, publish_html,
25 publish_pretty, publish_html,
26 publish_latex, publish_svg,
26 publish_latex, publish_svg,
27 publish_png, publish_json,
27 publish_png, publish_json,
28 publish_javascript, publish_jpeg
28 publish_javascript, publish_jpeg
29 )
29 )
30
30
31 #-----------------------------------------------------------------------------
31 #-----------------------------------------------------------------------------
32 # Main functions
32 # Main functions
33 #-----------------------------------------------------------------------------
33 #-----------------------------------------------------------------------------
34
34
35 def display(*objs, **kwargs):
35 def display(*objs, **kwargs):
36 """Display a Python object in all frontends.
36 """Display a Python object in all frontends.
37
37
38 By default all representations will be computed and sent to the frontends.
38 By default all representations will be computed and sent to the frontends.
39 Frontends can decide which representation is used and how.
39 Frontends can decide which representation is used and how.
40
40
41 Parameters
41 Parameters
42 ----------
42 ----------
43 objs : tuple of objects
43 objs : tuple of objects
44 The Python objects to display.
44 The Python objects to display.
45 include : list or tuple, optional
45 include : list or tuple, optional
46 A list of format type strings (MIME types) to include in the
46 A list of format type strings (MIME types) to include in the
47 format data dict. If this is set *only* the format types included
47 format data dict. If this is set *only* the format types included
48 in this list will be computed.
48 in this list will be computed.
49 exclude : list or tuple, optional
49 exclude : list or tuple, optional
50 A list of format type string (MIME types) to exclue in the format
50 A list of format type string (MIME types) to exclue in the format
51 data dict. If this is set all format types will be computed,
51 data dict. If this is set all format types will be computed,
52 except for those included in this argument.
52 except for those included in this argument.
53 """
53 """
54 include = kwargs.get('include')
54 include = kwargs.get('include')
55 exclude = kwargs.get('exclude')
55 exclude = kwargs.get('exclude')
56
56
57 from IPython.core.interactiveshell import InteractiveShell
57 from IPython.core.interactiveshell import InteractiveShell
58 inst = InteractiveShell.instance()
58 inst = InteractiveShell.instance()
59 format = inst.display_formatter.format
59 format = inst.display_formatter.format
60 publish = inst.display_pub.publish
60 publish = inst.display_pub.publish
61
61
62 for obj in objs:
62 for obj in objs:
63 format_dict = format(obj, include=include, exclude=exclude)
63 format_dict = format(obj, include=include, exclude=exclude)
64 publish('IPython.core.display.display', format_dict)
64 publish('IPython.core.display.display', format_dict)
65
65
66
66
67 def display_pretty(*objs, **kwargs):
67 def display_pretty(*objs, **kwargs):
68 """Display the pretty (default) representation of an object.
68 """Display the pretty (default) representation of an object.
69
69
70 Parameters
70 Parameters
71 ----------
71 ----------
72 objs : tuple of objects
72 objs : tuple of objects
73 The Python objects to display, or if raw=True raw text data to
73 The Python objects to display, or if raw=True raw text data to
74 display.
74 display.
75 raw : bool
75 raw : bool
76 Are the data objects raw data or Python objects that need to be
76 Are the data objects raw data or Python objects that need to be
77 formatted before display? [default: False]
77 formatted before display? [default: False]
78 """
78 """
79 raw = kwargs.pop('raw',False)
79 raw = kwargs.pop('raw',False)
80 if raw:
80 if raw:
81 for obj in objs:
81 for obj in objs:
82 publish_pretty(obj)
82 publish_pretty(obj)
83 else:
83 else:
84 display(*objs, include=['text/plain'])
84 display(*objs, include=['text/plain'])
85
85
86
86
87 def display_html(*objs, **kwargs):
87 def display_html(*objs, **kwargs):
88 """Display the HTML representation of an object.
88 """Display the HTML representation of an object.
89
89
90 Parameters
90 Parameters
91 ----------
91 ----------
92 objs : tuple of objects
92 objs : tuple of objects
93 The Python objects to display, or if raw=True raw HTML data to
93 The Python objects to display, or if raw=True raw HTML data to
94 display.
94 display.
95 raw : bool
95 raw : bool
96 Are the data objects raw data or Python objects that need to be
96 Are the data objects raw data or Python objects that need to be
97 formatted before display? [default: False]
97 formatted before display? [default: False]
98 """
98 """
99 raw = kwargs.pop('raw',False)
99 raw = kwargs.pop('raw',False)
100 if raw:
100 if raw:
101 for obj in objs:
101 for obj in objs:
102 publish_html(obj)
102 publish_html(obj)
103 else:
103 else:
104 display(*objs, include=['text/plain','text/html'])
104 display(*objs, include=['text/plain','text/html'])
105
105
106
106
107 def display_svg(*objs, **kwargs):
107 def display_svg(*objs, **kwargs):
108 """Display the SVG representation of an object.
108 """Display the SVG representation of an object.
109
109
110 Parameters
110 Parameters
111 ----------
111 ----------
112 objs : tuple of objects
112 objs : tuple of objects
113 The Python objects to display, or if raw=True raw svg data to
113 The Python objects to display, or if raw=True raw svg data to
114 display.
114 display.
115 raw : bool
115 raw : bool
116 Are the data objects raw data or Python objects that need to be
116 Are the data objects raw data or Python objects that need to be
117 formatted before display? [default: False]
117 formatted before display? [default: False]
118 """
118 """
119 raw = kwargs.pop('raw',False)
119 raw = kwargs.pop('raw',False)
120 if raw:
120 if raw:
121 for obj in objs:
121 for obj in objs:
122 publish_svg(obj)
122 publish_svg(obj)
123 else:
123 else:
124 display(*objs, include=['text/plain','image/svg+xml'])
124 display(*objs, include=['text/plain','image/svg+xml'])
125
125
126
126
127 def display_png(*objs, **kwargs):
127 def display_png(*objs, **kwargs):
128 """Display the PNG representation of an object.
128 """Display the PNG representation of an object.
129
129
130 Parameters
130 Parameters
131 ----------
131 ----------
132 objs : tuple of objects
132 objs : tuple of objects
133 The Python objects to display, or if raw=True raw png data to
133 The Python objects to display, or if raw=True raw png data to
134 display.
134 display.
135 raw : bool
135 raw : bool
136 Are the data objects raw data or Python objects that need to be
136 Are the data objects raw data or Python objects that need to be
137 formatted before display? [default: False]
137 formatted before display? [default: False]
138 """
138 """
139 raw = kwargs.pop('raw',False)
139 raw = kwargs.pop('raw',False)
140 if raw:
140 if raw:
141 for obj in objs:
141 for obj in objs:
142 publish_png(obj)
142 publish_png(obj)
143 else:
143 else:
144 display(*objs, include=['text/plain','image/png'])
144 display(*objs, include=['text/plain','image/png'])
145
145
146
146
147 def display_jpeg(*objs, **kwargs):
147 def display_jpeg(*objs, **kwargs):
148 """Display the JPEG representation of an object.
148 """Display the JPEG representation of an object.
149
149
150 Parameters
150 Parameters
151 ----------
151 ----------
152 objs : tuple of objects
152 objs : tuple of objects
153 The Python objects to display, or if raw=True raw JPEG data to
153 The Python objects to display, or if raw=True raw JPEG data to
154 display.
154 display.
155 raw : bool
155 raw : bool
156 Are the data objects raw data or Python objects that need to be
156 Are the data objects raw data or Python objects that need to be
157 formatted before display? [default: False]
157 formatted before display? [default: False]
158 """
158 """
159 raw = kwargs.pop('raw',False)
159 raw = kwargs.pop('raw',False)
160 if raw:
160 if raw:
161 for obj in objs:
161 for obj in objs:
162 publish_jpeg(obj)
162 publish_jpeg(obj)
163 else:
163 else:
164 display(*objs, include=['text/plain','image/jpeg'])
164 display(*objs, include=['text/plain','image/jpeg'])
165
165
166
166
167 def display_latex(*objs, **kwargs):
167 def display_latex(*objs, **kwargs):
168 """Display the LaTeX representation of an object.
168 """Display the LaTeX representation of an object.
169
169
170 Parameters
170 Parameters
171 ----------
171 ----------
172 objs : tuple of objects
172 objs : tuple of objects
173 The Python objects to display, or if raw=True raw latex data to
173 The Python objects to display, or if raw=True raw latex data to
174 display.
174 display.
175 raw : bool
175 raw : bool
176 Are the data objects raw data or Python objects that need to be
176 Are the data objects raw data or Python objects that need to be
177 formatted before display? [default: False]
177 formatted before display? [default: False]
178 """
178 """
179 raw = kwargs.pop('raw',False)
179 raw = kwargs.pop('raw',False)
180 if raw:
180 if raw:
181 for obj in objs:
181 for obj in objs:
182 publish_latex(obj)
182 publish_latex(obj)
183 else:
183 else:
184 display(*objs, include=['text/plain','text/latex'])
184 display(*objs, include=['text/plain','text/latex'])
185
185
186
186
187 def display_json(*objs, **kwargs):
187 def display_json(*objs, **kwargs):
188 """Display the JSON representation of an object.
188 """Display the JSON representation of an object.
189
189
190 Note that not many frontends support displaying JSON.
190 Note that not many frontends support displaying JSON.
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 json data to
195 The Python objects to display, or if raw=True raw json 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 """
200 """
201 raw = kwargs.pop('raw',False)
201 raw = kwargs.pop('raw',False)
202 if raw:
202 if raw:
203 for obj in objs:
203 for obj in objs:
204 publish_json(obj)
204 publish_json(obj)
205 else:
205 else:
206 display(*objs, include=['text/plain','application/json'])
206 display(*objs, include=['text/plain','application/json'])
207
207
208
208
209 def display_javascript(*objs, **kwargs):
209 def display_javascript(*objs, **kwargs):
210 """Display the Javascript representation of an object.
210 """Display the Javascript representation of an object.
211
211
212 Parameters
212 Parameters
213 ----------
213 ----------
214 objs : tuple of objects
214 objs : tuple of objects
215 The Python objects to display, or if raw=True raw javascript data to
215 The Python objects to display, or if raw=True raw javascript data to
216 display.
216 display.
217 raw : bool
217 raw : bool
218 Are the data objects raw data or Python objects that need to be
218 Are the data objects raw data or Python objects that need to be
219 formatted before display? [default: False]
219 formatted before display? [default: False]
220 """
220 """
221 raw = kwargs.pop('raw',False)
221 raw = kwargs.pop('raw',False)
222 if raw:
222 if raw:
223 for obj in objs:
223 for obj in objs:
224 publish_javascript(obj)
224 publish_javascript(obj)
225 else:
225 else:
226 display(*objs, include=['text/plain','application/javascript'])
226 display(*objs, include=['text/plain','application/javascript'])
227
227
228 #-----------------------------------------------------------------------------
228 #-----------------------------------------------------------------------------
229 # Smart classes
229 # Smart classes
230 #-----------------------------------------------------------------------------
230 #-----------------------------------------------------------------------------
231
231
232
232
233 class DisplayObject(object):
233 class DisplayObject(object):
234 """An object that wraps data to be displayed."""
234 """An object that wraps data to be displayed."""
235
235
236 _read_flags = 'r'
236 _read_flags = 'r'
237
237
238 def __init__(self, data=None, url=None, filename=None):
238 def __init__(self, data=None, url=None, filename=None):
239 """Create a display object given raw data.
239 """Create a display object given raw data.
240
240
241 When this object is returned by an expression or passed to the
241 When this object is returned by an expression or passed to the
242 display function, it will result in the data being displayed
242 display function, it will result in the data being displayed
243 in the frontend. The MIME type of the data should match the
243 in the frontend. The MIME type of the data should match the
244 subclasses used, so the Png subclass should be used for 'image/png'
244 subclasses used, so the Png subclass should be used for 'image/png'
245 data. If the data is a URL, the data will first be downloaded
245 data. If the data is a URL, the data will first be downloaded
246 and then displayed. If
246 and then displayed. If
247
247
248 Parameters
248 Parameters
249 ----------
249 ----------
250 data : unicode, str or bytes
250 data : unicode, str or bytes
251 The raw data or a URL to download the data from.
251 The raw data or a URL to download the data from.
252 url : unicode
252 url : unicode
253 A URL to download the data from.
253 A URL to download the data from.
254 filename : unicode
254 filename : unicode
255 Path to a local file to load the data from.
255 Path to a local file to load the data from.
256 """
256 """
257 if data is not None and data.startswith('http'):
257 if data is not None and data.startswith('http'):
258 self.url = data
258 self.url = data
259 self.filename = None
259 self.filename = None
260 self.data = None
260 self.data = None
261 else:
261 else:
262 self.data = data
262 self.data = data
263 self.url = url
263 self.url = url
264 self.filename = None if filename is None else unicode(filename)
264 self.filename = None if filename is None else unicode(filename)
265 self.reload()
265 self.reload()
266
266
267 def reload(self):
267 def reload(self):
268 """Reload the raw data from file or URL."""
268 """Reload the raw data from file or URL."""
269 if self.filename is not None:
269 if self.filename is not None:
270 with open(self.filename, self._read_flags) as f:
270 with open(self.filename, self._read_flags) as f:
271 self.data = f.read()
271 self.data = f.read()
272 elif self.url is not None:
272 elif self.url is not None:
273 try:
273 try:
274 import urllib2
274 import urllib2
275 response = urllib2.urlopen(self.url)
275 response = urllib2.urlopen(self.url)
276 self.data = response.read()
276 self.data = response.read()
277 # extract encoding from header, if there is one:
277 # extract encoding from header, if there is one:
278 encoding = None
278 encoding = None
279 for sub in response.headers['content-type'].split(';'):
279 for sub in response.headers['content-type'].split(';'):
280 sub = sub.strip()
280 sub = sub.strip()
281 if sub.startswith('charset'):
281 if sub.startswith('charset'):
282 encoding = sub.split('=')[-1].strip()
282 encoding = sub.split('=')[-1].strip()
283 break
283 break
284 # decode data, if an encoding was specified
284 # decode data, if an encoding was specified
285 if encoding:
285 if encoding:
286 self.data = self.data.decode(encoding, 'replace')
286 self.data = self.data.decode(encoding, 'replace')
287 except:
287 except:
288 self.data = None
288 self.data = None
289
289
290 class Pretty(DisplayObject):
290 class Pretty(DisplayObject):
291
291
292 def _repr_pretty_(self):
292 def _repr_pretty_(self):
293 return self.data
293 return self.data
294
294
295
295
296 class HTML(DisplayObject):
296 class HTML(DisplayObject):
297
297
298 def _repr_html_(self):
298 def _repr_html_(self):
299 return self.data
299 return self.data
300
300
301
301
302 class Math(DisplayObject):
302 class Math(DisplayObject):
303
303
304 def _repr_latex_(self):
304 def _repr_latex_(self):
305 s = self.data.strip('$')
305 s = self.data.strip('$')
306 return "$$%s$$" % s
306 return "$$%s$$" % s
307
307
308
308
309 class Latex(DisplayObject):
309 class Latex(DisplayObject):
310
310
311 def _repr_latex_(self):
311 def _repr_latex_(self):
312 return self.data
312 return self.data
313
313
314
314
315 class SVG(DisplayObject):
315 class SVG(DisplayObject):
316
316
317 # wrap data in a property, which extracts the <svg> tag, discarding
317 # wrap data in a property, which extracts the <svg> tag, discarding
318 # document headers
318 # document headers
319 _data = None
319 _data = None
320
320
321 @property
321 @property
322 def data(self):
322 def data(self):
323 return self._data
323 return self._data
324
324
325 @data.setter
325 @data.setter
326 def data(self, svg):
326 def data(self, svg):
327 if svg is None:
327 if svg is None:
328 self._data = None
328 self._data = None
329 return
329 return
330 # parse into dom object
330 # parse into dom object
331 x = minidom.parseString(svg)
331 x = minidom.parseString(svg)
332 # get svg tag (should be 1)
332 # get svg tag (should be 1)
333 found_svg = x.getElementsByTagName('svg')
333 found_svg = x.getElementsByTagName('svg')
334 if found_svg:
334 if found_svg:
335 svg = found_svg[0].toxml()
335 svg = found_svg[0].toxml()
336 else:
336 else:
337 # fallback on the input, trust the user
337 # fallback on the input, trust the user
338 # but this is probably an error.
338 # but this is probably an error.
339 pass
339 pass
340 self._data = svg
340 self._data = svg
341
341
342 def _repr_svg_(self):
342 def _repr_svg_(self):
343 return self.data
343 return self.data
344
344
345
345
346 class JSON(DisplayObject):
346 class JSON(DisplayObject):
347
347
348 def _repr_json_(self):
348 def _repr_json_(self):
349 return self.data
349 return self.data
350
350
351 css_t = """$("head").append($("<link/>").attr({
351 css_t = """$("head").append($("<link/>").attr({
352 rel: "stylesheet",
352 rel: "stylesheet",
353 type: "text/css",
353 type: "text/css",
354 href: "%s"
354 href: "%s"
355 }));
355 }));
356 """
356 """
357
357
358 lib_t1 = """$.getScript("%s", function () {
358 lib_t1 = """$.getScript("%s", function () {
359 """
359 """
360 lib_t2 = """});
360 lib_t2 = """});
361 """
361 """
362
362
363 class Javascript(DisplayObject):
363 class Javascript(DisplayObject):
364
364
365 def __init__(self, data=None, url=None, filename=None, lib=None, css=None):
365 def __init__(self, data=None, url=None, filename=None, lib=None, css=None):
366 """Create a Javascript display object given raw data.
366 """Create a Javascript display object given raw data.
367
367
368 When this object is returned by an expression or passed to the
368 When this object is returned by an expression or passed to the
369 display function, it will result in the data being displayed
369 display function, it will result in the data being displayed
370 in the frontend. If the data is a URL, the data will first be
370 in the frontend. If the data is a URL, the data will first be
371 downloaded and then displayed.
371 downloaded and then displayed.
372
372
373 In the Notebook, the containing element will be available as `element`,
373 In the Notebook, the containing element will be available as `element`,
374 and jQuery will be available. The output area starts hidden, so if
374 and jQuery will be available. The output area starts hidden, so if
375 the js appends content to `element` that should be visible, then
375 the js appends content to `element` that should be visible, then
376 it must call `container.show()` to unhide the area.
376 it must call `container.show()` to unhide the area.
377
377
378 Parameters
378 Parameters
379 ----------
379 ----------
380 data : unicode, str or bytes
380 data : unicode, str or bytes
381 The Javascript source code or a URL to download it from.
381 The Javascript source code or a URL to download it from.
382 url : unicode
382 url : unicode
383 A URL to download the data from.
383 A URL to download the data from.
384 filename : unicode
384 filename : unicode
385 Path to a local file to load the data from.
385 Path to a local file to load the data from.
386 lib : list or str
386 lib : list or str
387 A sequence of Javascript library URLs to load asynchronously before
387 A sequence of Javascript library URLs to load asynchronously before
388 running the source code. The full URLs of the libraries should
388 running the source code. The full URLs of the libraries should
389 be given. A single Javascript library URL can also be given as a
389 be given. A single Javascript library URL can also be given as a
390 string.
390 string.
391 css: : list or str
391 css: : list or str
392 A sequence of css files to load before running the source code.
392 A sequence of css files to load before running the source code.
393 The full URLs of the css files should be give. A single css URL
393 The full URLs of the css files should be give. A single css URL
394 can also be given as a string.
394 can also be given as a string.
395 """
395 """
396 if isinstance(lib, basestring):
396 if isinstance(lib, basestring):
397 lib = [lib]
397 lib = [lib]
398 elif lib is None:
398 elif lib is None:
399 lib = []
399 lib = []
400 if isinstance(css, basestring):
400 if isinstance(css, basestring):
401 css = [css]
401 css = [css]
402 elif css is None:
402 elif css is None:
403 css = []
403 css = []
404 if not isinstance(lib, (list,tuple)):
404 if not isinstance(lib, (list,tuple)):
405 raise TypeError('expected sequence, got: %r' % lib)
405 raise TypeError('expected sequence, got: %r' % lib)
406 if not isinstance(css, (list,tuple)):
406 if not isinstance(css, (list,tuple)):
407 raise TypeError('expected sequence, got: %r' % css)
407 raise TypeError('expected sequence, got: %r' % css)
408 self.lib = lib
408 self.lib = lib
409 self.css = css
409 self.css = css
410 super(Javascript, self).__init__(data=data, url=url, filename=filename)
410 super(Javascript, self).__init__(data=data, url=url, filename=filename)
411
411
412 def _repr_javascript_(self):
412 def _repr_javascript_(self):
413 r = ''
413 r = ''
414 for c in self.css:
414 for c in self.css:
415 r += css_t % c
415 r += css_t % c
416 for l in self.lib:
416 for l in self.lib:
417 r += lib_t1 % l
417 r += lib_t1 % l
418 r += self.data
418 r += self.data
419 r += lib_t2*len(self.lib)
419 r += lib_t2*len(self.lib)
420 return r
420 return r
421
421
422
422
423 class Image(DisplayObject):
423 class Image(DisplayObject):
424
424
425 _read_flags = 'rb'
425 _read_flags = 'rb'
426 _FMT_JPEG = u'jpeg'
427 _FMT_PNG = u'png'
428 _ACCEPTABLE_EMBEDDINGS = [_FMT_JPEG, _FMT_PNG]
426
429
427 def __init__(self, data=None, url=None, filename=None, format=u'png', embed=None):
430 def __init__(self, data=None, url=None, filename=None, format=u'png', embed=None, width=None, height=None):
428 """Create a display an PNG/JPEG image given raw data.
431 """Create a display an PNG/JPEG image given raw data.
429
432
430 When this object is returned by an expression or passed to the
433 When this object is returned by an expression or passed to the
431 display function, it will result in the image being displayed
434 display function, it will result in the image being displayed
432 in the frontend.
435 in the frontend.
433
436
434 Parameters
437 Parameters
435 ----------
438 ----------
436 data : unicode, str or bytes
439 data : unicode, str or bytes
437 The raw data or a URL to download the data from.
440 The raw data or a URL to download the data from.
438 url : unicode
441 url : unicode
439 A URL to download the data from.
442 A URL to download the data from.
440 filename : unicode
443 filename : unicode
441 Path to a local file to load the data from.
444 Path to a local file to load the data from.
442 format : unicode
445 format : unicode
443 The format of the image data (png/jpeg/jpg). If a filename or URL is given
446 The format of the image data (png/jpeg/jpg). If a filename or URL is given
444 for format will be inferred from the filename extension.
447 for format will be inferred from the filename extension.
445 embed : bool
448 embed : bool
446 Should the image data be embedded using a data URI (True) or be
449 Should the image data be embedded using a data URI (True) or be
447 loaded using an <img> tag. Set this to True if you want the image
450 loaded using an <img> tag. Set this to True if you want the image
448 to be viewable later with no internet connection in the notebook.
451 to be viewable later with no internet connection in the notebook.
449
452
450 Default is `True`, unless the keyword argument `url` is set, then
453 Default is `True`, unless the keyword argument `url` is set, then
451 default value is `False`.
454 default value is `False`.
452
455
453 Note that QtConsole is not able to display images if `embed` is set to `False`
456 Note that QtConsole is not able to display images if `embed` is set to `False`
457 width : int
458 Width to which to constrain the image in html
459 height : int
460 Height to which to constrain the image in html
454
461
455 Examples
462 Examples
456 --------
463 --------
457 # embed implicitly True, works in qtconsole and notebook
464 # embed implicitly True, works in qtconsole and notebook
458 Image('http://www.google.fr/images/srpr/logo3w.png')
465 Image('http://www.google.fr/images/srpr/logo3w.png')
459
466
460 # embed implicitly False, does not works in qtconsole but works in notebook if
467 # embed implicitly False, does not works in qtconsole but works in notebook if
461 # internet connection available
468 # internet connection available
462 Image(url='http://www.google.fr/images/srpr/logo3w.png')
469 Image(url='http://www.google.fr/images/srpr/logo3w.png')
463
470
464 """
471 """
465 if filename is not None:
472 if filename is not None:
466 ext = self._find_ext(filename)
473 ext = self._find_ext(filename)
467 elif url is not None:
474 elif url is not None:
468 ext = self._find_ext(url)
475 ext = self._find_ext(url)
476 elif data is None:
477 raise ValueError("No image data found. Expecting filename, url, or data.")
469 elif data.startswith('http'):
478 elif data.startswith('http'):
470 ext = self._find_ext(data)
479 ext = self._find_ext(data)
471 else:
480 else:
472 ext = None
481 ext = None
482
473 if ext is not None:
483 if ext is not None:
484 format = ext.lower()
474 if ext == u'jpg' or ext == u'jpeg':
485 if ext == u'jpg' or ext == u'jpeg':
475 format = u'jpeg'
486 format = self._FMT_JPEG
476 if ext == u'png':
487 if ext == u'png':
477 format = u'png'
488 format = self._FMT_PNG
489
478 self.format = unicode(format).lower()
490 self.format = unicode(format).lower()
479 self.embed = embed if embed is not None else (url is None)
491 self.embed = embed if embed is not None else (url is None)
492
493 if self.embed and self.format not in self._ACCEPTABLE_EMBEDDINGS:
494 raise ValueError("Cannot embed the '%s' image format" % (self.format))
495 self.width = width
496 self.height = height
480 super(Image, self).__init__(data=data, url=url, filename=filename)
497 super(Image, self).__init__(data=data, url=url, filename=filename)
481
498
482 def reload(self):
499 def reload(self):
483 """Reload the raw data from file or URL."""
500 """Reload the raw data from file or URL."""
484 if self.embed:
501 if self.embed:
485 super(Image,self).reload()
502 super(Image,self).reload()
486
503
487 def _repr_html_(self):
504 def _repr_html_(self):
488 if not self.embed:
505 if not self.embed:
489 return u'<img src="%s" />' % self.url
506 width = height = ''
507 if self.width:
508 width = ' width="%d"' % self.width
509 if self.height:
510 height = ' height="%d"' % self.height
511 return u'<img src="%s"%s%s/>' % (self.url, width, height)
490
512
491 def _repr_png_(self):
513 def _repr_png_(self):
492 if self.embed and self.format == u'png':
514 if self.embed and self.format == u'png':
493 return self.data
515 return self.data
494
516
495 def _repr_jpeg_(self):
517 def _repr_jpeg_(self):
496 if self.embed and (self.format == u'jpeg' or self.format == u'jpg'):
518 if self.embed and (self.format == u'jpeg' or self.format == u'jpg'):
497 return self.data
519 return self.data
498
520
499 def _find_ext(self, s):
521 def _find_ext(self, s):
500 return unicode(s.split('.')[-1].lower())
522 return unicode(s.split('.')[-1].lower())
501
523
502
524
503 def clear_output(stdout=True, stderr=True, other=True):
525 def clear_output(stdout=True, stderr=True, other=True):
504 """Clear the output of the current cell receiving output.
526 """Clear the output of the current cell receiving output.
505
527
506 Optionally, each of stdout/stderr or other non-stream data (e.g. anything
528 Optionally, each of stdout/stderr or other non-stream data (e.g. anything
507 produced by display()) can be excluded from the clear event.
529 produced by display()) can be excluded from the clear event.
508
530
509 By default, everything is cleared.
531 By default, everything is cleared.
510
532
511 Parameters
533 Parameters
512 ----------
534 ----------
513 stdout : bool [default: True]
535 stdout : bool [default: True]
514 Whether to clear stdout.
536 Whether to clear stdout.
515 stderr : bool [default: True]
537 stderr : bool [default: True]
516 Whether to clear stderr.
538 Whether to clear stderr.
517 other : bool [default: True]
539 other : bool [default: True]
518 Whether to clear everything else that is not stdout/stderr
540 Whether to clear everything else that is not stdout/stderr
519 (e.g. figures,images,HTML, any result of display()).
541 (e.g. figures,images,HTML, any result of display()).
520 """
542 """
521 from IPython.core.interactiveshell import InteractiveShell
543 from IPython.core.interactiveshell import InteractiveShell
522 if InteractiveShell.initialized():
544 if InteractiveShell.initialized():
523 InteractiveShell.instance().display_pub.clear_output(
545 InteractiveShell.instance().display_pub.clear_output(
524 stdout=stdout, stderr=stderr, other=other,
546 stdout=stdout, stderr=stderr, other=other,
525 )
547 )
526 else:
548 else:
527 from IPython.utils import io
549 from IPython.utils import io
528 if stdout:
550 if stdout:
529 print('\033[2K\r', file=io.stdout, end='')
551 print('\033[2K\r', file=io.stdout, end='')
530 io.stdout.flush()
552 io.stdout.flush()
531 if stderr:
553 if stderr:
532 print('\033[2K\r', file=io.stderr, end='')
554 print('\033[2K\r', file=io.stderr, end='')
533 io.stderr.flush()
555 io.stderr.flush()
534
556
@@ -1,17 +1,29 b''
1 """Add some assert methods to nose.tools. These were added in Python 2.7/3.1, so
1 """Add some assert methods to nose.tools. These were added in Python 2.7/3.1, so
2 once we stop testing on Python 2.6, this file can be removed.
2 once we stop testing on Python 2.6, this file can be removed.
3 """
3 """
4
4
5 import nose.tools as nt
5 import nose.tools as nt
6
6
7 def assert_in(item, collection):
7 def assert_in(item, collection):
8 assert item in collection, '%r not in %r' % (item, collection)
8 assert item in collection, '%r not in %r' % (item, collection)
9
9
10 if not hasattr(nt, 'assert_in'):
10 if not hasattr(nt, 'assert_in'):
11 nt.assert_in = assert_in
11 nt.assert_in = assert_in
12
12
13 def assert_not_in(item, collection):
13 def assert_not_in(item, collection):
14 assert item not in collection, '%r in %r' % (item, collection)
14 assert item not in collection, '%r in %r' % (item, collection)
15
15
16 if not hasattr(nt, 'assert_not_in'):
16 if not hasattr(nt, 'assert_not_in'):
17 nt.assert_not_in = assert_not_in
17 nt.assert_not_in = assert_not_in
18
19 def assert_is_none(obj):
20 assert obj is None, '%r is not None' % obj
21
22 if not hasattr(nt, 'assert_is_none'):
23 nt.assert_is_none = assert_is_none
24
25 def assert_is_not_none(obj):
26 assert obj is not None, '%r is None' % obj
27
28 if not hasattr(nt, 'assert_is_not_none'):
29 nt.assert_is_not_none = assert_is_not_none
General Comments 0
You need to be logged in to leave comments. Login now