File tree Expand file tree Collapse file tree 3 files changed +21
-2
lines changed
Expand file tree Collapse file tree 3 files changed +21
-2
lines changed Original file line number Diff line number Diff line change @@ -204,5 +204,20 @@ def default_factory():
204204 self .assertEqual (test_dict [key ], 2 )
205205 self .assertEqual (count , 2 )
206206
207+ def test_repr_recursive_factory (self ):
208+ # gh-145492: defaultdict.__repr__ should not cause infinite recursion
209+ # when the factory's __repr__ calls repr() on the defaultdict.
210+ class ProblematicFactory :
211+ def __call__ (self ):
212+ return {}
213+ def __repr__ (self ):
214+ repr (dd )
215+ return "ProblematicFactory()"
216+
217+ dd = defaultdict (ProblematicFactory ())
218+ # Should not raise RecursionError
219+ r = repr (dd )
220+ self .assertIn ('ProblematicFactory()' , r )
221+
207222if __name__ == "__main__" :
208223 unittest .main ()
Original file line number Diff line number Diff line change 1+ Fix infinite recursion in :class: `collections.defaultdict ` ``__repr__ ``
2+ when a ``defaultdict `` contains itself. Based on analysis by KowalskiThomas
3+ in :gh: `145492 `.
Original file line number Diff line number Diff line change @@ -2385,9 +2385,10 @@ defdict_repr(PyObject *op)
23852385 }
23862386 defrepr = PyUnicode_FromString ("..." );
23872387 }
2388- else
2388+ else {
23892389 defrepr = PyObject_Repr (dd -> default_factory );
2390- Py_ReprLeave (dd -> default_factory );
2390+ Py_ReprLeave (dd -> default_factory );
2391+ }
23912392 }
23922393 if (defrepr == NULL ) {
23932394 Py_DECREF (baserepr );
You can’t perform that action at this time.
0 commit comments