issue 2045: Infinite recursion when printing a subclass of defaultdict,
if default_factory is set to a bound method. Backport of r60663.
This commit is contained in:
parent
ec4301e60f
commit
3e5f8a6975
|
@ -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.5.2c1?
|
|||
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.
|
||||
|
||||
- Issue #1920: "while 0" statements were completely removed by the compiler,
|
||||
even in the presence of an "else" clause, which is supposed to be run when
|
||||
the condition is false. Now the compiler correctly emits bytecode for the
|
||||
|
|
|
@ -1217,7 +1217,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;
|
||||
|
|
Loading…
Reference in New Issue