Skip to content

Commit

Permalink
bpo-38006: Avoid closure in weakref.WeakValueDictionary (pythonGH-15641)
Browse files Browse the repository at this point in the history
weakref.WeakValueDictionary defines a local remove() function used as
callback for weak references. This function was created with a
closure.  Modify the implementation to avoid the closure.
  • Loading branch information
vstinner authored and websurfer5 committed Jul 20, 2020
1 parent f0900f7 commit 81249d5
Show file tree
Hide file tree
Showing 3 changed files with 10 additions and 2 deletions.
5 changes: 5 additions & 0 deletions Lib/test/test_weakref.py
Original file line number Diff line number Diff line change
Expand Up @@ -1792,6 +1792,11 @@ def test_threaded_weak_value_dict_deepcopy(self):
# copying should not result in a crash.
self.check_threaded_weak_dict_copy(weakref.WeakValueDictionary, True)

@support.cpython_only
def test_remove_closure(self):
d = weakref.WeakValueDictionary()
self.assertIsNone(d._remove.__closure__)


from test import mapping_tests

Expand Down
4 changes: 2 additions & 2 deletions Lib/weakref.py
Original file line number Diff line number Diff line change
Expand Up @@ -108,12 +108,12 @@ def remove(wr, selfref=ref(self), _atomic_removal=_remove_dead_weakref):
else:
# Atomic removal is necessary since this function
# can be called asynchronously by the GC
_atomic_removal(d, wr.key)
_atomic_removal(self.data, wr.key)
self._remove = remove
# A list of keys to be removed
self._pending_removals = []
self._iterating = set()
self.data = d = {}
self.data = {}
self.update(other, **kw)

def _commit_removals(self):
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
weakref.WeakValueDictionary defines a local remove() function used as
callback for weak references. This function was created with a closure.
Modify the implementation to avoid the closure.

0 comments on commit 81249d5

Please sign in to comment.