bpo-38006: Avoid closure in weakref.WeakValueDictionary (GH-15641) · python/cpython@a2af05a

3 files changed

lines changed

Original file line numberDiff line numberDiff line change

@@ -1792,6 +1792,11 @@ def test_threaded_weak_value_dict_deepcopy(self):

17921792

# copying should not result in a crash.

17931793

self.check_threaded_weak_dict_copy(weakref.WeakValueDictionary, True)

17941794
1795+

@support.cpython_only

1796+

def test_remove_closure(self):

1797+

d = weakref.WeakValueDictionary()

1798+

self.assertIsNone(d._remove.__closure__)

1799+
17951800
17961801

from test import mapping_tests

17971802
Original file line numberDiff line numberDiff line change

@@ -108,12 +108,12 @@ def remove(wr, selfref=ref(self), _atomic_removal=_remove_dead_weakref):

108108

else:

109109

# Atomic removal is necessary since this function

110110

# can be called asynchronously by the GC

111-

_atomic_removal(d, wr.key)

111+

_atomic_removal(self.data, wr.key)

112112

self._remove = remove

113113

# A list of keys to be removed

114114

self._pending_removals = []

115115

self._iterating = set()

116-

self.data = d = {}

116+

self.data = {}

117117

self.update(other, **kw)

118118
119119

def _commit_removals(self):

Original file line numberDiff line numberDiff line change

@@ -0,0 +1,3 @@

1+

weakref.WeakValueDictionary defines a local remove() function used as

2+

callback for weak references. This function was created with a closure.

3+

Modify the implementation to avoid the closure.