mirror of
https://github.com/python/cpython.git
synced 2025-10-25 02:43:41 +00:00
GH-91636: Clear weakrefs created by finalizers. (GH-136401)
Weakrefs to unreachable garbage that are created during running of finalizers need to be cleared. This avoids exposing objects that have `tp_clear` called on them to Python-level code.
This commit is contained in:
parent
bc9bc078df
commit
b6b99bf7f1
4 changed files with 54 additions and 14 deletions
|
|
@ -262,9 +262,11 @@ class Cyclic(tuple):
|
|||
# finalizer.
|
||||
def __del__(self):
|
||||
|
||||
# 5. Create a weakref to `func` now. If we had created
|
||||
# it earlier, it would have been cleared by the
|
||||
# garbage collector before calling the finalizers.
|
||||
# 5. Create a weakref to `func` now. In previous
|
||||
# versions of Python, this would avoid having it
|
||||
# cleared by the garbage collector before calling
|
||||
# the finalizers. Now, weakrefs get cleared after
|
||||
# calling finalizers.
|
||||
self[1].ref = weakref.ref(self[0])
|
||||
|
||||
# 6. Drop the global reference to `latefin`. The only
|
||||
|
|
@ -293,14 +295,18 @@ def func():
|
|||
# which will find `cyc` and `func` as garbage.
|
||||
gc.collect()
|
||||
|
||||
# 9. Previously, this would crash because `func_qualname`
|
||||
# had been NULL-ed out by func_clear().
|
||||
# 9. Previously, this would crash because the weakref
|
||||
# created in the finalizer revealed the function after
|
||||
# `tp_clear` was called and `func_qualname`
|
||||
# had been NULL-ed out by func_clear(). Now, we clear
|
||||
# weakrefs to unreachable objects before calling `tp_clear`
|
||||
# but after calling finalizers.
|
||||
print(f"{func=}")
|
||||
"""
|
||||
# We're mostly just checking that this doesn't crash.
|
||||
rc, stdout, stderr = assert_python_ok("-c", code)
|
||||
self.assertEqual(rc, 0)
|
||||
self.assertRegex(stdout, rb"""\A\s*func=<function at \S+>\s*\z""")
|
||||
# The `func` global is None because the weakref was cleared.
|
||||
self.assertRegex(stdout, rb"""\A\s*func=None""")
|
||||
self.assertFalse(stderr)
|
||||
|
||||
@refcount_test
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue