pFad - Phone/Frame/Anonymizer/Declutterfier! Saves Data!


--- a PPN by Garber Painting Akron. With Image Size Reduction included!

URL: http://github.com/python/cpython/commit/59be951e150f696ff234f981f839d9ae56143e17

41e157469407.css" /> [3.14] gh-145492: Fix defaultdict __repr__ infinite recursion (GH-145… · python/cpython@59be951 · GitHub
Skip to content

Commit 59be951

Browse files
miss-islingtonKowalskiThomasmvanhorn
authored
[3.14] gh-145492: Fix defaultdict __repr__ infinite recursion (GH-145659) (GH-145747)
(cherry picked from commit 2d35f9b) Includes test fix-up from GH-145788 (cherry picked from commit aa4240e) Co-authored-by: Thomas Kowalski <thom.kowa@gmail.com> Co-authored-by: Matt Van Horn <mvanhorn@users.noreply.github.com>
1 parent a778fd6 commit 59be951

File tree

3 files changed

+21
-2
lines changed

3 files changed

+21
-2
lines changed

Lib/test/test_defaultdict.py

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff 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 f"ProblematicFactory for {dd}"
216+
217+
dd = defaultdict(ProblematicFactory())
218+
# Should not raise RecursionError
219+
r = repr(dd)
220+
self.assertIn("ProblematicFactory for", r)
221+
207222
if __name__ == "__main__":
208223
unittest.main()
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
Fix infinite recursion in :class:`collections.defaultdict` ``__repr__``
2+
when a ``defaultdict`` contains itself. Based on analysis by KowalskiThomas
3+
in :gh:`145492`.

Modules/_collectionsmodule.c

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2382,9 +2382,10 @@ defdict_repr(PyObject *op)
23822382
}
23832383
defrepr = PyUnicode_FromString("...");
23842384
}
2385-
else
2385+
else {
23862386
defrepr = PyObject_Repr(dd->default_factory);
2387-
Py_ReprLeave(dd->default_factory);
2387+
Py_ReprLeave(dd->default_factory);
2388+
}
23882389
}
23892390
if (defrepr == NULL) {
23902391
Py_DECREF(baserepr);

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad © 2024 Your Company Name. All rights reserved.





Check this box to remove all script contents from the fetched content.



Check this box to remove all images from the fetched content.


Check this box to remove all CSS styles from the fetched content.


Check this box to keep images inefficiently compressed and original size.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy