[pypy-commit] pypy py3.7-bpo-27541: Implement bpo-27541: Reprs of subclasses of some classes now contain actual type name
Yannick_Jadoul
pypy.commits at gmail.com
Mon Dec 30 17:29:23 EST 2019
Author: Yannick Jadoul <yannick.jadoul at belgacom.net>
Branch: py3.7-bpo-27541
Changeset: r98418:fc33829c0465
Date: 2019-12-30 23:28 +0100
http://bitbucket.org/pypy/pypy/changeset/fc33829c0465/
Log: Implement bpo-27541: Reprs of subclasses of some classes now contain
actual type name
diff --git a/lib_pypy/_collections.py b/lib_pypy/_collections.py
--- a/lib_pypy/_collections.py
+++ b/lib_pypy/_collections.py
@@ -211,14 +211,14 @@
def __repr__(self):
threadlocalattr = '__repr' + str(_thread_ident())
if threadlocalattr in self.__dict__:
- return 'deque([...])'
+ return '%s([...])' % (self.__class__.__name__,)
else:
self.__dict__[threadlocalattr] = True
try:
if self.maxlen is not None:
- return 'deque(%r, maxlen=%s)' % (list(self), self.maxlen)
+ return '%s(%r, maxlen=%s)' % (self.__class__.__name__, list(self), self.maxlen)
else:
- return 'deque(%r)' % (list(self),)
+ return '%s(%r)' % (self.__class__.__name__, list(self))
finally:
del self.__dict__[threadlocalattr]
@@ -411,10 +411,10 @@
def __repr__(self, recurse=set()):
if id(self) in recurse:
- return "defaultdict(...)"
+ return "%s(...)" % (self.__class__.__name__,)
try:
recurse.add(id(self))
- return "defaultdict(%s, %s)" % (repr(self.default_factory), super(defaultdict, self).__repr__())
+ return "%s(%s, %s)" % (self.__class__.__name__, repr(self.default_factory), super(defaultdict, self).__repr__())
finally:
recurse.remove(id(self))
diff --git a/pypy/module/_collections/app_defaultdict.py b/pypy/module/_collections/app_defaultdict.py
--- a/pypy/module/_collections/app_defaultdict.py
+++ b/pypy/module/_collections/app_defaultdict.py
@@ -40,7 +40,7 @@
factoryrepr = repr(self.default_factory)
finally:
recurse.remove(id(self))
- return "defaultdict(%s, %s)" % (factoryrepr, dictrepr)
+ return "%s(%s, %s)" % (self.__class__.__name__, factoryrepr, dictrepr)
def copy(self):
return type(self)(self.default_factory, self)
diff --git a/pypy/module/_collections/interp_deque.py b/pypy/module/_collections/interp_deque.py
--- a/pypy/module/_collections/interp_deque.py
+++ b/pypy/module/_collections/interp_deque.py
@@ -536,7 +536,7 @@
maxlenrepr = ''
else:
maxlenrepr = ', maxlen=%d' % (d.maxlen,)
- return 'deque(%s%s)' % (listrepr, maxlenrepr)
+ return '%s(%s%s)' % (d.__class__.__name__, listrepr, maxlenrepr)
""", filename=__file__)
dequerepr = app.interphook("dequerepr")
diff --git a/pypy/module/_collections/test/test_defaultdict.py b/pypy/module/_collections/test/test_defaultdict.py
--- a/pypy/module/_collections/test/test_defaultdict.py
+++ b/pypy/module/_collections/test/test_defaultdict.py
@@ -98,4 +98,10 @@
pass
d = X.__new__(X)
d.__init__(d.mydefault)
- assert repr(d).endswith('defaultdict(..., {})>, {})')
+ assert repr(d).endswith('X(..., {})>, {})')
+
+ def test_subclass_repr(self):
+ import _collections
+ class subclass(_collections.defaultdict):
+ pass
+ assert repr(subclass()) == 'subclass(None, {})'
diff --git a/pypy/module/_collections/test/test_deque.py b/pypy/module/_collections/test/test_deque.py
--- a/pypy/module/_collections/test/test_deque.py
+++ b/pypy/module/_collections/test/test_deque.py
@@ -448,3 +448,9 @@
elements = 'ABCDEFGHI'
d = deque([-2, -1, 0, 0, 1, 2])
assert d.index(0, -4*sys.maxsize, 4*sys.maxsize) == 2
+
+ def test_subclass_repr(self):
+ from _collections import deque
+ class subclass(deque):
+ pass
+ assert repr(subclass()) == 'subclass([])'
diff --git a/pypy/module/array/interp_array.py b/pypy/module/array/interp_array.py
--- a/pypy/module/array/interp_array.py
+++ b/pypy/module/array/interp_array.py
@@ -766,8 +766,9 @@
# Misc methods
def descr_repr(self, space):
+ cls_name = space.type(self).getname(space)
if self.len == 0:
- return space.newtext("array('%s')" % self.typecode)
+ return space.newtext("%s('%s')" % (cls_name, self.typecode))
elif self.typecode == "u":
try:
w_unicode = self.descr_tounicode(space)
@@ -778,11 +779,11 @@
r = "<%s>" % (space.text_w(w_exc_value),)
else:
r = space.text_w(space.repr(w_unicode))
- s = "array('%s', %s)" % (self.typecode, r)
+ s = "%s('%s', %s)" % (cls_name, self.typecode, r)
return space.newtext(s)
else:
r = space.repr(self.descr_tolist(space))
- s = "array('%s', %s)" % (self.typecode, space.text_w(r))
+ s = "%s('%s', %s)" % (cls_name, self.typecode, space.text_w(r))
return space.newtext(s)
def check_valid_unicode(self, space, s):
diff --git a/pypy/module/array/test/test_array.py b/pypy/module/array/test/test_array.py
--- a/pypy/module/array/test/test_array.py
+++ b/pypy/module/array/test/test_array.py
@@ -864,25 +864,25 @@
def extend(self, lst):
self.append(10)
- assert repr(mya('u', 'hi')) == "array('u', 'hi')"
- assert repr(mya('i', [1, 2, 3])) == "array('i', [1, 2, 3])"
- assert repr(mya('i', (1, 2, 3))) == "array('i', [1, 2, 3])"
+ assert repr(mya('u', 'hi')) == "mya('u', 'hi')"
+ assert repr(mya('i', [1, 2, 3])) == "mya('i', [1, 2, 3])"
+ assert repr(mya('i', (1, 2, 3))) == "mya('i', [1, 2, 3])"
a = mya('i')
a.fromlist([1, 2, 3])
- assert repr(a) == "array('i', [7])"
+ assert repr(a) == "mya('i', [7])"
a = mya('b')
a.fromstring(b'hi')
- assert repr(a) == "array('b', [8])"
+ assert repr(a) == "mya('b', [8])"
a = mya('u')
a.fromunicode('hi')
- assert repr(a) == "array('u', '9')"
+ assert repr(a) == "mya('u', '9')"
a = mya('i')
a.extend([1, 2, 3])
- assert repr(a) == "array('i', [10])"
+ assert repr(a) == "mya('i', [10])"
def test_override_to(self):
class mya(self.array):
@@ -899,9 +899,9 @@
assert mya('u', 'hi').tobytes() == 'str'
assert mya('u', 'hi').tounicode() == 'unicode'
- assert repr(mya('u', 'hi')) == "array('u', 'hi')"
- assert repr(mya('i', [1, 2, 3])) == "array('i', [1, 2, 3])"
- assert repr(mya('i', (1, 2, 3))) == "array('i', [1, 2, 3])"
+ assert repr(mya('u', 'hi')) == "mya('u', 'hi')"
+ assert repr(mya('i', [1, 2, 3])) == "mya('i', [1, 2, 3])"
+ assert repr(mya('i', (1, 2, 3))) == "mya('i', [1, 2, 3])"
def test_unicode_outofrange(self):
input_unicode = u'\x01\u263a\x00\ufeff'
@@ -1111,6 +1111,12 @@
struct.pack_into('>H', view, 1, 0x1234)
assert a.tobytes() == b'ab\x12\x34ef'
+ def test_subclass_repr(self):
+ import array
+ class subclass(self.array):
+ pass
+ assert repr(subclass('i')) == "subclass('i')"
+
class AppTestArrayReconstructor:
spaceconfig = dict(usemodules=('array', 'struct'))
diff --git a/pypy/module/itertools/interp_itertools.py b/pypy/module/itertools/interp_itertools.py
--- a/pypy/module/itertools/interp_itertools.py
+++ b/pypy/module/itertools/interp_itertools.py
@@ -27,12 +27,13 @@
def repr_w(self):
space = self.space
+ cls_name = space.type(self).getname(space)
c = space.text_w(space.repr(self.w_c))
if self.single_argument():
- s = 'count(%s)' % (c,)
+ s = '%s(%s)' % (cls_name, c)
else:
step = space.text_w(space.repr(self.w_step))
- s = 'count(%s, %s)' % (c, step)
+ s = '%s(%s, %s)' % (cls_name, c, step)
return self.space.newtext(s)
def reduce_w(self):
@@ -107,11 +108,13 @@
return self.space.newint(self.count)
def repr_w(self):
- objrepr = self.space.text_w(self.space.repr(self.w_obj))
+ space = self.space
+ cls_name = space.type(self).getname(space)
+ objrepr = self.space.text_w(space.repr(self.w_obj))
if self.counting:
- s = 'repeat(%s, %d)' % (objrepr, self.count)
+ s = '%s(%s, %d)' % (cls_name, objrepr, self.count)
else:
- s = 'repeat(%s)' % (objrepr,)
+ s = '%s(%s)' % (cls_name, objrepr)
return self.space.newtext(s)
def descr_reduce(self):
diff --git a/pypy/module/itertools/test/test_itertools.py b/pypy/module/itertools/test/test_itertools.py
--- a/pypy/module/itertools/test/test_itertools.py
+++ b/pypy/module/itertools/test/test_itertools.py
@@ -36,6 +36,12 @@
raises(TypeError, itertools.count, 'a')
raises(TypeError, itertools.count, [])
+ def test_count_subclass_repr(self):
+ import itertools
+ class subclass(itertools.count):
+ pass
+ assert repr(subclass(123)) == 'subclass(123)'
+
def test_repeat(self):
import itertools
@@ -99,6 +105,12 @@
r = itertools.repeat('a', -3)
assert operator.length_hint(r, 3) == 0
+ def test_repeat_subclass_repr(self):
+ import itertools
+ class subclass(itertools.repeat):
+ pass
+ assert repr(subclass('foobar')) == "subclass('foobar')"
+
def test_takewhile(self):
import itertools
diff --git a/pypy/objspace/std/bytearrayobject.py b/pypy/objspace/std/bytearrayobject.py
--- a/pypy/objspace/std/bytearrayobject.py
+++ b/pypy/objspace/std/bytearrayobject.py
@@ -222,11 +222,13 @@
def descr_repr(self, space):
s, start, end, _ = self._convert_idx_params(space, None, None)
+ cls_name = space.type(self).getname(space)
# Good default if there are no replacements.
- buf = StringBuilder(len("bytearray(b'')") + (end - start))
+ buf = StringBuilder(len(cls_name) + len("(b'')") + (end - start))
- buf.append("bytearray(b")
+ buf.append(cls_name)
+ buf.append("(b")
quote = "'"
for i in range(start, end):
c = s[i]
diff --git a/pypy/objspace/std/test/test_bytearrayobject.py b/pypy/objspace/std/test/test_bytearrayobject.py
--- a/pypy/objspace/std/test/test_bytearrayobject.py
+++ b/pypy/objspace/std/test/test_bytearrayobject.py
@@ -764,3 +764,8 @@
assert x.find(b'fe') == -1
assert x.index(b'f', 2, 11) == 5
assert x.__alloc__() == 14
+
+ def test_subclass_repr(self):
+ class subclass(bytearray):
+ pass
+ assert repr(subclass(b'test')) == "subclass(b'test')"
More information about the pypy-commit
mailing list