Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 819efc4

Browse files
authored
Merge pull request #10959 from takluyver/i10950
Defining __repr__ should override pretty printer for parent class
2 parents 6a0ae6b + 98c4cb9 commit 819efc4

3 files changed

Lines changed: 35 additions & 26 deletions

File tree

IPython/core/tests/test_formatters.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,7 @@ def test_pretty():
4949
f = PlainTextFormatter()
5050
f.for_type(A, foo_printer)
5151
nt.assert_equal(f(A()), 'foo')
52-
nt.assert_equal(f(B()), 'foo')
52+
nt.assert_equal(f(B()), 'B()')
5353
nt.assert_equal(f(GoodPretty()), 'foo')
5454
# Just don't raise an exception for the following:
5555
f(BadPretty())

IPython/lib/pretty.py

Lines changed: 13 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -395,6 +395,10 @@ def pretty(self, obj):
395395
meth = cls._repr_pretty_
396396
if callable(meth):
397397
return meth(obj, self, cycle)
398+
if cls is not object \
399+
and callable(cls.__dict__.get('__repr__')):
400+
return _repr_pprint(obj, self, cycle)
401+
398402
return _default_pprint(obj, self, cycle)
399403
finally:
400404
self.end_group()
@@ -540,17 +544,12 @@ def _default_pprint(obj, p, cycle):
540544
p.end_group(1, '>')
541545

542546

543-
def _seq_pprinter_factory(start, end, basetype):
547+
def _seq_pprinter_factory(start, end):
544548
"""
545549
Factory that returns a pprint function useful for sequences. Used by
546550
the default pprint for tuples, dicts, and lists.
547551
"""
548552
def inner(obj, p, cycle):
549-
typ = type(obj)
550-
if basetype is not None and typ is not basetype and typ.__repr__ != basetype.__repr__:
551-
# If the subclass provides its own repr, use it instead.
552-
return p.text(typ.__repr__(obj))
553-
554553
if cycle:
555554
return p.text(start + '...' + end)
556555
step = len(start)
@@ -567,21 +566,16 @@ def inner(obj, p, cycle):
567566
return inner
568567

569568

570-
def _set_pprinter_factory(start, end, basetype):
569+
def _set_pprinter_factory(start, end):
571570
"""
572571
Factory that returns a pprint function useful for sets and frozensets.
573572
"""
574573
def inner(obj, p, cycle):
575-
typ = type(obj)
576-
if basetype is not None and typ is not basetype and typ.__repr__ != basetype.__repr__:
577-
# If the subclass provides its own repr, use it instead.
578-
return p.text(typ.__repr__(obj))
579-
580574
if cycle:
581575
return p.text(start + '...' + end)
582576
if len(obj) == 0:
583577
# Special case.
584-
p.text(basetype.__name__ + '()')
578+
p.text(type(obj).__name__ + '()')
585579
else:
586580
step = len(start)
587581
p.begin_group(step, start)
@@ -599,17 +593,12 @@ def inner(obj, p, cycle):
599593
return inner
600594

601595

602-
def _dict_pprinter_factory(start, end, basetype=None):
596+
def _dict_pprinter_factory(start, end):
603597
"""
604598
Factory that returns a pprint function used by the default pprint of
605599
dicts and dict proxies.
606600
"""
607601
def inner(obj, p, cycle):
608-
typ = type(obj)
609-
if basetype is not None and typ is not basetype and typ.__repr__ != basetype.__repr__:
610-
# If the subclass provides its own repr, use it instead.
611-
return p.text(typ.__repr__(obj))
612-
613602
if cycle:
614603
return p.text('{...}')
615604
step = len(start)
@@ -750,12 +739,12 @@ def _exception_pprint(obj, p, cycle):
750739
int: _repr_pprint,
751740
float: _repr_pprint,
752741
str: _repr_pprint,
753-
tuple: _seq_pprinter_factory('(', ')', tuple),
754-
list: _seq_pprinter_factory('[', ']', list),
755-
dict: _dict_pprinter_factory('{', '}', dict),
742+
tuple: _seq_pprinter_factory('(', ')'),
743+
list: _seq_pprinter_factory('[', ']'),
744+
dict: _dict_pprinter_factory('{', '}'),
756745

757-
set: _set_pprinter_factory('{', '}', set),
758-
frozenset: _set_pprinter_factory('frozenset({', '})', frozenset),
746+
set: _set_pprinter_factory('{', '}'),
747+
frozenset: _set_pprinter_factory('frozenset({', '})'),
759748
super: _super_pprint,
760749
_re_pattern_type: _re_pattern_pprint,
761750
type: _type_pprint,

IPython/lib/tests/test_pretty.py

Lines changed: 21 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -420,4 +420,24 @@ def meaning_of_life(question=None):
420420
return "Don't panic"
421421

422422
nt.assert_in('meaning_of_life(question=None)', pretty.pretty(meaning_of_life))
423-
423+
424+
425+
class OrderedCounter(Counter, OrderedDict):
426+
'Counter that remembers the order elements are first encountered'
427+
428+
def __repr__(self):
429+
return '%s(%r)' % (self.__class__.__name__, OrderedDict(self))
430+
431+
def __reduce__(self):
432+
return self.__class__, (OrderedDict(self),)
433+
434+
class MySet(set): # Override repr of a basic type
435+
def __repr__(self):
436+
return 'mine'
437+
438+
def test_custom_repr():
439+
"""A custom repr should override a pretty printer for a parent type"""
440+
oc = OrderedCounter("abracadabra")
441+
nt.assert_in("OrderedCounter(OrderedDict", pretty.pretty(oc))
442+
443+
nt.assert_equal(pretty.pretty(MySet()), 'mine')

0 commit comments

Comments
 (0)