diff --git a/src/core/IronPython.Modules/_collections.cs b/src/core/IronPython.Modules/_collections.cs index d58d66f1d..8b5c447b8 100644 --- a/src/core/IronPython.Modules/_collections.cs +++ b/src/core/IronPython.Modules/_collections.cs @@ -920,7 +920,8 @@ private bool WalkDeque(DequeWalker walker) { infinite.Add(this); try { StringBuilder sb = new StringBuilder(); - sb.Append("deque(["); + sb.Append(PythonOps.GetPythonTypeName(this)); + sb.Append("(["); string comma = ""; lock (_lockObj) { @@ -1188,7 +1189,7 @@ public override PythonDictionary copy(CodeContext/*!*/ context) { } public override string __repr__(CodeContext context) { - return string.Format("defaultdict({0}, {1})", ReprFactory(context, default_factory), base.__repr__(context)); + return string.Format("{0}({1}, {2})", PythonOps.GetPythonTypeName(this), ReprFactory(context, default_factory), base.__repr__(context)); static string ReprFactory(CodeContext context, object factory) { var infinite = PythonOps.GetAndCheckInfinite(factory); diff --git a/src/core/IronPython.Modules/array.cs b/src/core/IronPython.Modules/array.cs index ed2919433..216d89829 100644 --- a/src/core/IronPython.Modules/array.cs +++ b/src/core/IronPython.Modules/array.cs @@ -856,7 +856,7 @@ bool IStructuralEquatable.Equals(object? other, IEqualityComparer comparer) { #region ICodeFormattable Members public virtual string/*!*/ __repr__(CodeContext/*!*/ context) { - string res = "array('" + typecode.ToString() + "'"; + string res = PythonOps.GetPythonTypeName(this) + "('" + typecode.ToString() + "'"; if (_data.Count == 0) { return res + ")"; } diff --git a/src/core/IronPython.StdLib/lib/test/test_defaultdict.py b/src/core/IronPython.StdLib/lib/test/test_defaultdict.py index 532d53598..d9b2297d7 100644 --- a/src/core/IronPython.StdLib/lib/test/test_defaultdict.py +++ b/src/core/IronPython.StdLib/lib/test/test_defaultdict.py @@ -157,8 +157,14 @@ def __init__(self): def _factory(self): return [] d = sub() - self.assertTrue(repr(d).startswith( - "defaultdict(, \{\}\)") # NOTE: printing a subclass of a builtin type does not call its # tp_print slot. So this part is essentially the same test as above. diff --git a/src/core/IronPython/Runtime/ByteArray.cs b/src/core/IronPython/Runtime/ByteArray.cs index d96d5fa13..ec83218b2 100644 --- a/src/core/IronPython/Runtime/ByteArray.cs +++ b/src/core/IronPython/Runtime/ByteArray.cs @@ -1079,7 +1079,7 @@ public PythonTuple __reduce__(CodeContext context) { private string Repr() { lock (this) { - return "bytearray(" + _bytes.BytesRepr() + ")"; + return PythonOps.GetPythonTypeName(this) + "(" + _bytes.BytesRepr() + ")"; } } diff --git a/tests/suite/test_isinstance.py b/tests/suite/test_isinstance.py index afa9cfc00..e1796f51f 100644 --- a/tests/suite/test_isinstance.py +++ b/tests/suite/test_isinstance.py @@ -974,4 +974,26 @@ def test_tuple_new(self): self.assertRaises(TypeError, tuple.__new__, str) self.assertRaises(TypeError, tuple.__new__, str, 'abc') + + def test_container_repr(self): + import array, collections + class MyArray(array.array): pass + class MyBytearray(bytearray): pass + class MyDeque(collections.deque): pass + class MyDefaultDict(collections.defaultdict): pass + class MySet(set): pass + + if is_cli or sys.version_info >= (3, 7): + self.assertEqual(repr(MyArray('b')), "MyArray('b')") + self.assertEqual(repr(MyBytearray(b'x')), "MyBytearray(b'x')") + self.assertEqual(repr(MyDeque(['c'])), "MyDeque(['c'])") + self.assertTrue("MyDefaultDict" in repr(MyDefaultDict(list))) + else: + self.assertEqual(repr(MyArray('b')), "array('b')") + self.assertEqual(repr(MyBytearray(b'x')), "bytearray(b'x')") + self.assertEqual(repr(MyDeque(['c'])), "deque(['c'])") + self.assertTrue("defaultdict" in repr(MyDefaultDict(list))) + self.assertEqual(repr(MySet()), "MySet()") + + run_test(__name__)