Commit b01aa430 authored by Amaury Forgeot d'Arc's avatar Amaury Forgeot d'Arc

issue 2045: Infinite recursion when printing a subclass of defaultdict,

if default_factory is set to a bound method.

Will backport.
parent 48397d6c
......@@ -141,6 +141,29 @@ class TestDefaultDict(unittest.TestCase):
else:
self.fail("expected KeyError")
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()
self.assert_(repr(d).startswith(
"defaultdict(<bound method sub._factory of 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.
tfn = tempfile.mktemp()
try:
f = open(tfn, "w+")
try:
print >>f, d
finally:
f.close()
finally:
os.remove(tfn)
def test_main():
test_support.run_unittest(TestDefaultDict)
......
......@@ -12,6 +12,9 @@ What's New in Python 2.6 alpha 1?
Core and builtins
-----------------
- Issue #2045: Fix an infinite recursion triggered when printing a subclass of
collections.defaultdict, if its default_factory is set to a bound method.
- Fixed a minor memory leak in dictobject.c. The content of the free
list was not freed on interpreter shutdown.
......
......@@ -1300,7 +1300,17 @@ defdict_repr(defdictobject *dd)
if (dd->default_factory == NULL)
defrepr = PyString_FromString("None");
else
defrepr = PyObject_Repr(dd->default_factory);
{
int status = Py_ReprEnter(dd->default_factory);
if (status != 0) {
if (status < 0)
return NULL;
defrepr = PyString_FromString("...");
}
else
defrepr = PyObject_Repr(dd->default_factory);
Py_ReprLeave(dd->default_factory);
}
if (defrepr == NULL) {
Py_DECREF(baserepr);
return NULL;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment