diff --git a/IPython/core/formatters.py b/IPython/core/formatters.py index ef010c3..8e17bc9 100644 --- a/IPython/core/formatters.py +++ b/IPython/core/formatters.py @@ -39,38 +39,21 @@ else: #----------------------------------------------------------------------------- -def _valid_formatter(f): - """Return whether an object is a valid formatter - - Cases checked: +def _safe_get_formatter_method(obj, name): + """Safely get a formatter method - - bound methods OK - - unbound methods NO - - callable with zero args OK + - Classes cannot have formatter methods, only instance + - protect against proxy objects that claim to have everything """ - if f is None: - return False - elif isinstance(f, types.BuiltinFunctionType): - # bound methods on compiled classes have type builtin_function - return True - elif callable(f): - # anything that works with zero args should be okay - try: - inspect.getcallargs(f) - except Exception: - return False - else: - return True - return False - -def _safe_get_formatter_method(obj, name): - """Safely get a formatter method""" if inspect.isclass(obj): # repr methods only make sense on instances, not classes return None method = pretty._safe_getattr(obj, name, None) - # formatter methods must be bound - if _valid_formatter(method): + if callable(method): + # obj claims to have repr method... + if callable(pretty._safe_getattr(obj, '_ipython_canary_method_should_not_exist_', None)): + # ...but don't trust proxy objects that claim to have everything + return None return method diff --git a/IPython/core/tests/test_formatters.py b/IPython/core/tests/test_formatters.py index 6061ed4..5322bb3 100644 --- a/IPython/core/tests/test_formatters.py +++ b/IPython/core/tests/test_formatters.py @@ -348,8 +348,7 @@ def test_print_method_weird(): with capture_output() as captured: result = f(call_hat) - nt.assert_equal(result, '_repr_html_') - nt.assert_not_in("FormatterWarning", captured.stderr) + nt.assert_equal(result, None) class BadReprArgs(object): def _repr_html_(self, extra, args):