[pypy-commit] pypy default: Avoid RuntimeError in repr() of recursive dictviews (bpo-18533)

rlamy pypy.commits at gmail.com
Tue Aug 20 15:43:04 EDT 2019


Author: Ronan Lamy <ronan.lamy at gmail.com>
Branch: 
Changeset: r97227:3ea4a70584df
Date: 2019-08-20 20:42 +0100
http://bitbucket.org/pypy/pypy/changeset/3ea4a70584df/

Log:	Avoid RuntimeError in repr() of recursive dictviews (bpo-18533)

diff --git a/pypy/objspace/std/dictmultiobject.py b/pypy/objspace/std/dictmultiobject.py
--- a/pypy/objspace/std/dictmultiobject.py
+++ b/pypy/objspace/std/dictmultiobject.py
@@ -446,9 +446,23 @@
                 del currently_in_repr[d]
             except:
                 pass
+
+    def viewrepr(currently_in_repr, view):
+        if view in currently_in_repr:
+            return '...'
+        currently_in_repr[view] = 1
+        try:
+            return (type(view).__name__ + "([" +
+               ", ".join([repr(x) for x in view]) + '])')
+        finally:
+            try:
+                del currently_in_repr[view]
+            except:
+                pass
 ''', filename=__file__)
 
 dictrepr = app.interphook("dictrepr")
+viewrepr = app.interphook("viewrepr")
 
 
 W_DictMultiObject.typedef = TypeDef("dict",
@@ -1515,7 +1529,9 @@
         self.w_dict = w_dict
 
     def descr_repr(self, space):
+        return viewrepr(space, space.get_objects_in_repr(), self)
         w_seq = space.call_function(space.w_list, self)
+
         w_repr = space.repr(w_seq)
         return space.newtext("%s(%s)" % (space.type(self).getname(space),
                                          space.text_w(w_repr)))
diff --git a/pypy/objspace/std/test/test_dictmultiobject.py b/pypy/objspace/std/test/test_dictmultiobject.py
--- a/pypy/objspace/std/test/test_dictmultiobject.py
+++ b/pypy/objspace/std/test/test_dictmultiobject.py
@@ -917,6 +917,12 @@
         assert (r == "dict_values(['ABC', 10])" or
                 r == "dict_values([10, 'ABC'])")
 
+    def test_recursive_repr(self):
+        d = {1: 2}
+        d[2] = d.viewvalues()
+        print repr(d)
+        assert repr(d) == '{1: 2, 2: dict_values([2, ...])}'
+
     def test_keys_set_operations(self):
         d1 = {'a': 1, 'b': 2}
         d2 = {'b': 3, 'c': 2}


More information about the pypy-commit mailing list