Files
RustPython/Lib/collections
Changjoon 330b18f2fe Preserve recursively-set value in defaultdict.__missing__ (#7718)
CPython's defaultdict.__missing__ (Modules/_collectionsmodule.c::defdict_missing)
calls default_factory() first; if the factory's recursion already populated
self[key] while running, the existing value is preserved instead of being
overwritten.

RustPython ships a Python fallback at Lib/collections/_defaultdict.py
(the C _collections.defaultdict is not available). That fallback
unconditionally executed self[key] = val after the factory returned,
overwriting any value the recursive call had already stored.

Add a 'if key in self: return self[key]' guard before the assignment.
dict.__contains__ does not invoke __missing__, so there's no recursion
risk; in the common non-reentrant case the check is False and behavior
is unchanged.

Unmasks test_defaultdict.TestDefaultDict.test_factory_conflict_with_set_value.
2026-04-29 18:14:32 +09:00
..