Show More
@@ -5,25 +5,11 b' Inheritance diagram:' | |||||
5 |
|
5 | |||
6 | .. inheritance-diagram:: IPython.core.formatters |
|
6 | .. inheritance-diagram:: IPython.core.formatters | |
7 | :parts: 3 |
|
7 | :parts: 3 | |
8 |
|
||||
9 | Authors: |
|
|||
10 |
|
||||
11 | * Robert Kern |
|
|||
12 | * Brian Granger |
|
|||
13 | """ |
|
8 | """ | |
14 | #----------------------------------------------------------------------------- |
|
|||
15 | # Copyright (C) 2010-2011, IPython Development Team. |
|
|||
16 | # |
|
|||
17 | # Distributed under the terms of the Modified BSD License. |
|
|||
18 | # |
|
|||
19 | # The full license is in the file COPYING.txt, distributed with this software. |
|
|||
20 | #----------------------------------------------------------------------------- |
|
|||
21 |
|
9 | |||
22 | #----------------------------------------------------------------------------- |
|
10 | # Copyright (c) IPython Development Team. | |
23 | # Imports |
|
11 | # Distributed under the terms of the Modified BSD License. | |
24 | #----------------------------------------------------------------------------- |
|
|||
25 |
|
12 | |||
26 | # Stdlib imports |
|
|||
27 | import abc |
|
13 | import abc | |
28 | import inspect |
|
14 | import inspect | |
29 | import sys |
|
15 | import sys | |
@@ -32,8 +18,8 b' import warnings' | |||||
32 |
|
18 | |||
33 | from IPython.external.decorator import decorator |
|
19 | from IPython.external.decorator import decorator | |
34 |
|
20 | |||
35 | # Our own imports |
|
|||
36 | from IPython.config.configurable import Configurable |
|
21 | from IPython.config.configurable import Configurable | |
|
22 | from IPython.core.getipython import get_ipython | |||
37 | from IPython.lib import pretty |
|
23 | from IPython.lib import pretty | |
38 | from IPython.utils.traitlets import ( |
|
24 | from IPython.utils.traitlets import ( | |
39 | Bool, Dict, Integer, Unicode, CUnicode, ObjectName, List, |
|
25 | Bool, Dict, Integer, Unicode, CUnicode, ObjectName, List, | |
@@ -223,6 +209,18 b' class DisplayFormatter(Configurable):' | |||||
223 | # Formatters for specific format types (text, html, svg, etc.) |
|
209 | # Formatters for specific format types (text, html, svg, etc.) | |
224 | #----------------------------------------------------------------------------- |
|
210 | #----------------------------------------------------------------------------- | |
225 |
|
211 | |||
|
212 | ||||
|
213 | def _safe_repr(obj): | |||
|
214 | """Try to return a repr of an object | |||
|
215 | ||||
|
216 | always returns a string, at least. | |||
|
217 | """ | |||
|
218 | try: | |||
|
219 | return repr(obj) | |||
|
220 | except Exception as e: | |||
|
221 | return "un-repr-able object (%r)" % e | |||
|
222 | ||||
|
223 | ||||
226 | class FormatterWarning(UserWarning): |
|
224 | class FormatterWarning(UserWarning): | |
227 | """Warning class for errors in formatters""" |
|
225 | """Warning class for errors in formatters""" | |
228 |
|
226 | |||
@@ -234,10 +232,13 b' def warn_format_error(method, self, *args, **kwargs):' | |||||
234 | except NotImplementedError as e: |
|
232 | except NotImplementedError as e: | |
235 | # don't warn on NotImplementedErrors |
|
233 | # don't warn on NotImplementedErrors | |
236 | return None |
|
234 | return None | |
237 |
except Exception |
|
235 | except Exception: | |
238 | warnings.warn("Exception in %s formatter: %s" % (self.format_type, e), |
|
236 | exc_info = sys.exc_info() | |
239 | FormatterWarning, |
|
237 | ip = get_ipython() | |
240 | ) |
|
238 | if ip is not None: | |
|
239 | ip.showtraceback(exc_info) | |||
|
240 | else: | |||
|
241 | traceback.print_exception(*exc_info) | |||
241 | return None |
|
242 | return None | |
242 | if r is None or isinstance(r, self._return_type) or \ |
|
243 | if r is None or isinstance(r, self._return_type) or \ | |
243 | (isinstance(r, tuple) and r and isinstance(r[0], self._return_type)): |
|
244 | (isinstance(r, tuple) and r and isinstance(r[0], self._return_type)): | |
@@ -245,7 +246,7 b' def warn_format_error(method, self, *args, **kwargs):' | |||||
245 | else: |
|
246 | else: | |
246 | warnings.warn( |
|
247 | warnings.warn( | |
247 | "%s formatter returned invalid type %s (expected %s) for object: %s" % \ |
|
248 | "%s formatter returned invalid type %s (expected %s) for object: %s" % \ | |
248 |
(self.format_type, type(r), self._return_type, |
|
249 | (self.format_type, type(r), self._return_type, _safe_repr(args[0])), | |
249 | FormatterWarning |
|
250 | FormatterWarning | |
250 | ) |
|
251 | ) | |
251 |
|
252 | |||
@@ -672,7 +673,7 b' class PlainTextFormatter(BaseFormatter):' | |||||
672 | def __call__(self, obj): |
|
673 | def __call__(self, obj): | |
673 | """Compute the pretty representation of the object.""" |
|
674 | """Compute the pretty representation of the object.""" | |
674 | if not self.pprint: |
|
675 | if not self.pprint: | |
675 |
return |
|
676 | return repr(obj) | |
676 | else: |
|
677 | else: | |
677 | # This uses use StringIO, as cStringIO doesn't handle unicode. |
|
678 | # This uses use StringIO, as cStringIO doesn't handle unicode. | |
678 | stream = StringIO() |
|
679 | stream = StringIO() |
@@ -25,6 +25,10 b' class B(A):' | |||||
25 | class C: |
|
25 | class C: | |
26 | pass |
|
26 | pass | |
27 |
|
27 | |||
|
28 | class BadRepr(object): | |||
|
29 | def __repr__(self): | |||
|
30 | raise ValueError("bad repr") | |||
|
31 | ||||
28 | class BadPretty(object): |
|
32 | class BadPretty(object): | |
29 | _repr_pretty_ = None |
|
33 | _repr_pretty_ = None | |
30 |
|
34 | |||
@@ -234,30 +238,30 b' def test_pop_string():' | |||||
234 | nt.assert_is(f.pop(type_str, None), None) |
|
238 | nt.assert_is(f.pop(type_str, None), None) | |
235 |
|
239 | |||
236 |
|
240 | |||
237 |
def test_ |
|
241 | def test_error_method(): | |
238 | f = HTMLFormatter() |
|
242 | f = HTMLFormatter() | |
239 | class BadHTML(object): |
|
243 | class BadHTML(object): | |
240 | def _repr_html_(self): |
|
244 | def _repr_html_(self): | |
241 | return 1/0 |
|
245 | raise ValueError("Bad HTML") | |
242 | bad = BadHTML() |
|
246 | bad = BadHTML() | |
243 | with capture_output() as captured: |
|
247 | with capture_output() as captured: | |
244 | result = f(bad) |
|
248 | result = f(bad) | |
245 | nt.assert_is(result, None) |
|
249 | nt.assert_is(result, None) | |
246 |
nt.assert_in(" |
|
250 | nt.assert_in("Traceback", captured.stdout) | |
247 |
nt.assert_in(" |
|
251 | nt.assert_in("Bad HTML", captured.stdout) | |
248 |
nt.assert_in(" |
|
252 | nt.assert_in("_repr_html_", captured.stdout) | |
249 |
|
253 | |||
250 | def test_nowarn_notimplemented(): |
|
254 | def test_nowarn_notimplemented(): | |
251 | f = HTMLFormatter() |
|
255 | f = HTMLFormatter() | |
252 | class HTMLNotImplemented(object): |
|
256 | class HTMLNotImplemented(object): | |
253 | def _repr_html_(self): |
|
257 | def _repr_html_(self): | |
254 | raise NotImplementedError |
|
258 | raise NotImplementedError | |
255 | return 1/0 |
|
|||
256 | h = HTMLNotImplemented() |
|
259 | h = HTMLNotImplemented() | |
257 | with capture_output() as captured: |
|
260 | with capture_output() as captured: | |
258 | result = f(h) |
|
261 | result = f(h) | |
259 | nt.assert_is(result, None) |
|
262 | nt.assert_is(result, None) | |
260 |
nt.assert_ |
|
263 | nt.assert_equal("", captured.stderr) | |
|
264 | nt.assert_equal("", captured.stdout) | |||
261 |
|
265 | |||
262 | def test_warn_error_for_type(): |
|
266 | def test_warn_error_for_type(): | |
263 | f = HTMLFormatter() |
|
267 | f = HTMLFormatter() | |
@@ -265,11 +269,11 b' def test_warn_error_for_type():' | |||||
265 | with capture_output() as captured: |
|
269 | with capture_output() as captured: | |
266 | result = f(5) |
|
270 | result = f(5) | |
267 | nt.assert_is(result, None) |
|
271 | nt.assert_is(result, None) | |
268 |
nt.assert_in(" |
|
272 | nt.assert_in("Traceback", captured.stdout) | |
269 |
nt.assert_in(" |
|
273 | nt.assert_in("NameError", captured.stdout) | |
270 |
nt.assert_in("name_error", captured.std |
|
274 | nt.assert_in("name_error", captured.stdout) | |
271 |
|
275 | |||
272 |
def test_ |
|
276 | def test_error_pretty_method(): | |
273 | f = PlainTextFormatter() |
|
277 | f = PlainTextFormatter() | |
274 | class BadPretty(object): |
|
278 | class BadPretty(object): | |
275 | def _repr_pretty_(self): |
|
279 | def _repr_pretty_(self): | |
@@ -278,9 +282,23 b' def test_warn_error_pretty_method():' | |||||
278 | with capture_output() as captured: |
|
282 | with capture_output() as captured: | |
279 | result = f(bad) |
|
283 | result = f(bad) | |
280 | nt.assert_is(result, None) |
|
284 | nt.assert_is(result, None) | |
281 |
nt.assert_in(" |
|
285 | nt.assert_in("Traceback", captured.stdout) | |
282 |
nt.assert_in(" |
|
286 | nt.assert_in("_repr_pretty_", captured.stdout) | |
283 |
nt.assert_in(" |
|
287 | nt.assert_in("given", captured.stdout) | |
|
288 | nt.assert_in("argument", captured.stdout) | |||
|
289 | ||||
|
290 | ||||
|
291 | def test_bad_repr_traceback(): | |||
|
292 | f = PlainTextFormatter() | |||
|
293 | bad = BadRepr() | |||
|
294 | with capture_output() as captured: | |||
|
295 | result = f(bad) | |||
|
296 | # catches error, returns None | |||
|
297 | nt.assert_is(result, None) | |||
|
298 | nt.assert_in("Traceback", captured.stdout) | |||
|
299 | nt.assert_in("__repr__", captured.stdout) | |||
|
300 | nt.assert_in("ValueError", captured.stdout) | |||
|
301 | ||||
284 |
|
302 | |||
285 | class MakePDF(object): |
|
303 | class MakePDF(object): | |
286 | def _repr_pdf_(self): |
|
304 | def _repr_pdf_(self): |
General Comments 0
You need to be logged in to leave comments.
Login now