mirror of
https://github.com/python/cpython.git
synced 2026-04-14 15:50:50 +00:00
gh-145492: Fix defaultdict __repr__ infinite recursion (GH-145659)
Co-Authored-By: Thomas Kowalski <thom.kowa@gmail.com>
This commit is contained in:
parent
728e4a075e
commit
2d35f9bc1c
3 changed files with 21 additions and 2 deletions
|
|
@ -204,5 +204,20 @@ def default_factory():
|
|||
self.assertEqual(test_dict[key], 2)
|
||||
self.assertEqual(count, 2)
|
||||
|
||||
def test_repr_recursive_factory(self):
|
||||
# gh-145492: defaultdict.__repr__ should not cause infinite recursion
|
||||
# when the factory's __repr__ calls repr() on the defaultdict.
|
||||
class ProblematicFactory:
|
||||
def __call__(self):
|
||||
return {}
|
||||
def __repr__(self):
|
||||
repr(dd)
|
||||
return "ProblematicFactory()"
|
||||
|
||||
dd = defaultdict(ProblematicFactory())
|
||||
# Should not raise RecursionError
|
||||
r = repr(dd)
|
||||
self.assertIn('ProblematicFactory()', r)
|
||||
|
||||
if __name__ == "__main__":
|
||||
unittest.main()
|
||||
|
|
|
|||
|
|
@ -0,0 +1,3 @@
|
|||
Fix infinite recursion in :class:`collections.defaultdict` ``__repr__``
|
||||
when a ``defaultdict`` contains itself. Based on analysis by KowalskiThomas
|
||||
in :gh:`145492`.
|
||||
|
|
@ -2385,9 +2385,10 @@ defdict_repr(PyObject *op)
|
|||
}
|
||||
defrepr = PyUnicode_FromString("...");
|
||||
}
|
||||
else
|
||||
else {
|
||||
defrepr = PyObject_Repr(dd->default_factory);
|
||||
Py_ReprLeave(dd->default_factory);
|
||||
Py_ReprLeave(dd->default_factory);
|
||||
}
|
||||
}
|
||||
if (defrepr == NULL) {
|
||||
Py_DECREF(baserepr);
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue