Show More
@@ -5,25 +5,11 b' Inheritance diagram:' | |||
|
5 | 5 | |
|
6 | 6 | .. inheritance-diagram:: IPython.core.formatters |
|
7 | 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 | #----------------------------------------------------------------------------- | |
|
23 | # Imports | |
|
24 | #----------------------------------------------------------------------------- | |
|
10 | # Copyright (c) IPython Development Team. | |
|
11 | # Distributed under the terms of the Modified BSD License. | |
|
25 | 12 | |
|
26 | # Stdlib imports | |
|
27 | 13 | import abc |
|
28 | 14 | import inspect |
|
29 | 15 | import sys |
@@ -32,8 +18,8 b' import warnings' | |||
|
32 | 18 | |
|
33 | 19 | from IPython.external.decorator import decorator |
|
34 | 20 | |
|
35 | # Our own imports | |
|
36 | 21 | from IPython.config.configurable import Configurable |
|
22 | from IPython.core.getipython import get_ipython | |
|
37 | 23 | from IPython.lib import pretty |
|
38 | 24 | from IPython.utils.traitlets import ( |
|
39 | 25 | Bool, Dict, Integer, Unicode, CUnicode, ObjectName, List, |
@@ -223,6 +209,18 b' class DisplayFormatter(Configurable):' | |||
|
223 | 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 | 224 | class FormatterWarning(UserWarning): |
|
227 | 225 | """Warning class for errors in formatters""" |
|
228 | 226 | |
@@ -234,10 +232,13 b' def warn_format_error(method, self, *args, **kwargs):' | |||
|
234 | 232 | except NotImplementedError as e: |
|
235 | 233 | # don't warn on NotImplementedErrors |
|
236 | 234 | return None |
|
237 |
except Exception |
|
|
238 | warnings.warn("Exception in %s formatter: %s" % (self.format_type, e), | |
|
239 | FormatterWarning, | |
|
240 | ) | |
|
235 | except Exception: | |
|
236 | exc_info = sys.exc_info() | |
|
237 | ip = get_ipython() | |
|
238 | if ip is not None: | |
|
239 | ip.showtraceback(exc_info) | |
|
240 | else: | |
|
241 | traceback.print_exception(*exc_info) | |
|
241 | 242 | return None |
|
242 | 243 | if r is None or isinstance(r, self._return_type) or \ |
|
243 | 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 | 246 | else: |
|
246 | 247 | warnings.warn( |
|
247 | 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 | 250 | FormatterWarning |
|
250 | 251 | ) |
|
251 | 252 | |
@@ -672,7 +673,7 b' class PlainTextFormatter(BaseFormatter):' | |||
|
672 | 673 | def __call__(self, obj): |
|
673 | 674 | """Compute the pretty representation of the object.""" |
|
674 | 675 | if not self.pprint: |
|
675 |
return |
|
|
676 | return repr(obj) | |
|
676 | 677 | else: |
|
677 | 678 | # This uses use StringIO, as cStringIO doesn't handle unicode. |
|
678 | 679 | stream = StringIO() |
@@ -25,6 +25,10 b' class B(A):' | |||
|
25 | 25 | class C: |
|
26 | 26 | pass |
|
27 | 27 | |
|
28 | class BadRepr(object): | |
|
29 | def __repr__(self): | |
|
30 | raise ValueError("bad repr") | |
|
31 | ||
|
28 | 32 | class BadPretty(object): |
|
29 | 33 | _repr_pretty_ = None |
|
30 | 34 | |
@@ -234,30 +238,30 b' def test_pop_string():' | |||
|
234 | 238 | nt.assert_is(f.pop(type_str, None), None) |
|
235 | 239 | |
|
236 | 240 | |
|
237 |
def test_ |
|
|
241 | def test_error_method(): | |
|
238 | 242 | f = HTMLFormatter() |
|
239 | 243 | class BadHTML(object): |
|
240 | 244 | def _repr_html_(self): |
|
241 | return 1/0 | |
|
245 | raise ValueError("Bad HTML") | |
|
242 | 246 | bad = BadHTML() |
|
243 | 247 | with capture_output() as captured: |
|
244 | 248 | result = f(bad) |
|
245 | 249 | nt.assert_is(result, None) |
|
246 |
nt.assert_in(" |
|
|
247 |
nt.assert_in(" |
|
|
248 |
nt.assert_in(" |
|
|
250 | nt.assert_in("Traceback", captured.stdout) | |
|
251 | nt.assert_in("Bad HTML", captured.stdout) | |
|
252 | nt.assert_in("_repr_html_", captured.stdout) | |
|
249 | 253 | |
|
250 | 254 | def test_nowarn_notimplemented(): |
|
251 | 255 | f = HTMLFormatter() |
|
252 | 256 | class HTMLNotImplemented(object): |
|
253 | 257 | def _repr_html_(self): |
|
254 | 258 | raise NotImplementedError |
|
255 | return 1/0 | |
|
256 | 259 | h = HTMLNotImplemented() |
|
257 | 260 | with capture_output() as captured: |
|
258 | 261 | result = f(h) |
|
259 | 262 | nt.assert_is(result, None) |
|
260 |
nt.assert_ |
|
|
263 | nt.assert_equal("", captured.stderr) | |
|
264 | nt.assert_equal("", captured.stdout) | |
|
261 | 265 | |
|
262 | 266 | def test_warn_error_for_type(): |
|
263 | 267 | f = HTMLFormatter() |
@@ -265,11 +269,11 b' def test_warn_error_for_type():' | |||
|
265 | 269 | with capture_output() as captured: |
|
266 | 270 | result = f(5) |
|
267 | 271 | nt.assert_is(result, None) |
|
268 |
nt.assert_in(" |
|
|
269 |
nt.assert_in(" |
|
|
270 |
nt.assert_in("name_error", captured.std |
|
|
272 | nt.assert_in("Traceback", captured.stdout) | |
|
273 | nt.assert_in("NameError", captured.stdout) | |
|
274 | nt.assert_in("name_error", captured.stdout) | |
|
271 | 275 | |
|
272 |
def test_ |
|
|
276 | def test_error_pretty_method(): | |
|
273 | 277 | f = PlainTextFormatter() |
|
274 | 278 | class BadPretty(object): |
|
275 | 279 | def _repr_pretty_(self): |
@@ -278,9 +282,23 b' def test_warn_error_pretty_method():' | |||
|
278 | 282 | with capture_output() as captured: |
|
279 | 283 | result = f(bad) |
|
280 | 284 | nt.assert_is(result, None) |
|
281 |
nt.assert_in(" |
|
|
282 |
nt.assert_in(" |
|
|
283 |
nt.assert_in(" |
|
|
285 | nt.assert_in("Traceback", captured.stdout) | |
|
286 | nt.assert_in("_repr_pretty_", captured.stdout) | |
|
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 | 303 | class MakePDF(object): |
|
286 | 304 | def _repr_pdf_(self): |
General Comments 0
You need to be logged in to leave comments.
Login now