diff --git a/IPython/core/formatters.py b/IPython/core/formatters.py index b4ccf03..9a2644c 100644 --- a/IPython/core/formatters.py +++ b/IPython/core/formatters.py @@ -183,22 +183,31 @@ class DisplayFormatter(Configurable): # Formatters for specific format types (text, html, svg, etc.) #----------------------------------------------------------------------------- +class FormatterWarning(UserWarning): + """Warning class for errors in formatters""" + @decorator def warn_format_error(method, self, *args, **kwargs): """decorator for warning on failed format call""" try: r = method(self, *args, **kwargs) + except NotImplementedError as e: + # don't warn on NotImplementedErrors + return None except Exception as e: - warn("Exception in %s formatter: %s" % (self.format_type, e)) + warnings.warn("Exception in %s formatter: %s" % (self.format_type, e), + FormatterWarning, + ) return None if r is None or isinstance(r, self._return_type) or \ (isinstance(r, tuple) and r and isinstance(r[0], self._return_type)): return r else: - warn("%s formatter returned invalid type %s (expected %s) for object: %s" % ( - self.format_type, type(r), self._return_type, pretty._safe_repr(args[0]) - )) - + warnings.warn( + "%s formatter returned invalid type %s (expected %s) for object: %s" % \ + (self.format_type, type(r), self._return_type, pretty._safe_repr(args[0])), + FormatterWarning + ) class FormatterABC(with_metaclass(abc.ABCMeta, object)): diff --git a/IPython/core/tests/test_formatters.py b/IPython/core/tests/test_formatters.py index a2972cc..184d5d5 100644 --- a/IPython/core/tests/test_formatters.py +++ b/IPython/core/tests/test_formatters.py @@ -240,17 +240,29 @@ def test_warn_error_method(): with capture_output() as captured: result = f(bad) nt.assert_is(result, None) - nt.assert_in("WARNING", captured.stderr) + nt.assert_in("FormatterWarning", captured.stderr) nt.assert_in("text/html", captured.stderr) nt.assert_in("zero", captured.stderr) +def test_nowarn_notimplemented(): + f = HTMLFormatter() + class HTMLNotImplemented(object): + def _repr_html_(self): + raise NotImplementedError + return 1/0 + h = HTMLNotImplemented() + with capture_output() as captured: + result = f(h) + nt.assert_is(result, None) + nt.assert_not_in("FormatterWarning", captured.stderr) + def test_warn_error_for_type(): f = HTMLFormatter() f.for_type(int, lambda i: name_error) with capture_output() as captured: result = f(5) nt.assert_is(result, None) - nt.assert_in("WARNING", captured.stderr) + nt.assert_in("FormatterWarning", captured.stderr) nt.assert_in("text/html", captured.stderr) nt.assert_in("name_error", captured.stderr) @@ -263,7 +275,7 @@ def test_warn_error_pretty_method(): with capture_output() as captured: result = f(bad) nt.assert_is(result, None) - nt.assert_in("WARNING", captured.stderr) + nt.assert_in("FormatterWarning", captured.stderr) nt.assert_in("text/plain", captured.stderr) nt.assert_in("argument", captured.stderr)