From 63f389bc8a61c8e1fefb4aa1388ecd18b3c2b361 2012-03-30 11:08:52 From: Walter Doerwald Date: 2012-03-30 11:08:52 Subject: [PATCH] Fix dispatching in the pretty printing module. Search for the best method to use for pretty printing an object now no longer prefers any registered printer in type_printers for the class or any of the base classes over a _repr_pretty_ method defined in the class or any of its base classes. Instead the mro is walked, looking for both registered printers and _repr_pretty_ methods, so that the inheritance hierarchy will be taken into account. --- diff --git a/IPython/lib/pretty.py b/IPython/lib/pretty.py index d8ce094..b74037e 100644 --- a/IPython/lib/pretty.py +++ b/IPython/lib/pretty.py @@ -336,21 +336,25 @@ class RepresentationPrinter(PrettyPrinter): pass else: return printer(obj, self, cycle) - # Next look for type_printers. + # Next walk the mro and check for either: + # 1) a registered printer + # 2) a _repr_pretty_ method for cls in _get_mro(obj_class): if cls in self.type_pprinters: + # printer registered in self.type_pprinters return self.type_pprinters[cls](obj, self, cycle) else: + # deferred printer printer = self._in_deferred_types(cls) if printer is not None: return printer(obj, self, cycle) - # Finally look for special method names. - if hasattr(obj_class, '_repr_pretty_'): - # Some objects automatically create any requested - # attribute. Try to ignore most of them by checking for - # callability. - if callable(obj_class._repr_pretty_): - return obj_class._repr_pretty_(obj, self, cycle) + else: + # Finally look for special method names. + # Some objects automatically create any requested + # attribute. Try to ignore most of them by checking for + # callability. + if callable(getattr(obj_class, '_repr_pretty_')): + return obj_class._repr_pretty_(obj, self, cycle) return _default_pprint(obj, self, cycle) finally: self.end_group() diff --git a/IPython/lib/tests/test_pretty.py b/IPython/lib/tests/test_pretty.py index ccf215a..9b65bbf 100644 --- a/IPython/lib/tests/test_pretty.py +++ b/IPython/lib/tests/test_pretty.py @@ -40,6 +40,11 @@ class MyList(object): p.pretty(child) +class MyDict(dict): + def _repr_pretty_(self, p, cycle): + p.text("MyDict(...)") + + def test_indentation(): """Test correct indentation in groups""" count = 40 @@ -47,3 +52,14 @@ def test_indentation(): expectedoutput = "MyList(\n" + ",\n".join(" %d" % i for i in range(count)) + ")" nt.assert_equals(gotoutput, expectedoutput) + + +def test_dispatch(): + """ + Test correct dispatching: The _repr_pretty_ method for MyDict + must be found before the registered printer for dict. + """ + gotoutput = pretty.pretty(MyDict()) + expectedoutput = "MyDict(...)" + + nt.assert_equals(gotoutput, expectedoutput)