[pypy-svn] r58839 - in pypy/branch/2.5-merge/pypy/lib: . app_test

iko at codespeak.net iko at codespeak.net
Wed Oct 8 18:05:02 CEST 2008


Author: iko
Date: Wed Oct  8 18:05:02 2008
New Revision: 58839

Modified:
   pypy/branch/2.5-merge/pypy/lib/app_test/test_defaultdict.py
   pypy/branch/2.5-merge/pypy/lib/collections.py
Log:
fix defaultdict recursive repr()



Modified: pypy/branch/2.5-merge/pypy/lib/app_test/test_defaultdict.py
==============================================================================
--- pypy/branch/2.5-merge/pypy/lib/app_test/test_defaultdict.py	(original)
+++ pypy/branch/2.5-merge/pypy/lib/app_test/test_defaultdict.py	Wed Oct  8 18:05:02 2008
@@ -68,6 +68,17 @@
         d3[13]
         assert repr(d3), "defaultdict(%s, {13: 43})" % repr(foo)
 
+    def test_recursive_repr(self):
+        # Issue2045: stack overflow when default_factory is a bound method
+        class sub(defaultdict):
+            def __init__(self):
+                self.default_factory = self._factory
+            def _factory(self):
+                return []
+        d = sub()
+        assert repr(d).startswith(
+            "defaultdict(<bound method sub._factory of defaultdict(...")
+
     def test_copy(self):
         d1 = defaultdict()
         d2 = d1.copy()

Modified: pypy/branch/2.5-merge/pypy/lib/collections.py
==============================================================================
--- pypy/branch/2.5-merge/pypy/lib/collections.py	(original)
+++ pypy/branch/2.5-merge/pypy/lib/collections.py	Wed Oct  8 18:05:02 2008
@@ -337,8 +337,14 @@
         self[key] = value = self.default_factory()
         return value
 
-    def __repr__(self):
-        return "defaultdict(%s, %s)" % (repr(self.default_factory), super(defaultdict, self).__repr__())
+    def __repr__(self, recurse=[]):
+        if recurse:
+            return "defaultdict(...)"
+        try:
+            recurse.append(True)
+            return "defaultdict(%s, %s)" % (repr(self.default_factory), super(defaultdict, self).__repr__())
+        finally:
+            recurse.pop()
 
     def copy(self):
         return type(self)(self, default_factory=self.default_factory)



More information about the Pypy-commit mailing list