GH-91636: Clear weakrefs created by finalizers. (GH-136401)
Some checks are pending
Tests / (push) Blocked by required conditions
Tests / Windows MSI (push) Blocked by required conditions
Tests / Change detection (push) Waiting to run
Tests / Docs (push) Blocked by required conditions
Tests / Check if Autoconf files are up to date (push) Blocked by required conditions
Tests / Check if generated files are up to date (push) Blocked by required conditions
Tests / Ubuntu SSL tests with OpenSSL (push) Blocked by required conditions
Tests / WASI (push) Blocked by required conditions
Tests / Hypothesis tests on Ubuntu (push) Blocked by required conditions
Tests / Address sanitizer (push) Blocked by required conditions
Tests / Undefined behavior sanitizer (push) Blocked by required conditions
Tests / Cross build Linux (push) Blocked by required conditions
Tests / CIFuzz (push) Blocked by required conditions
Tests / All required checks pass (push) Blocked by required conditions
Lint / lint (push) Waiting to run
mypy / Run mypy on Lib/_pyrepl (push) Waiting to run
mypy / Run mypy on Lib/test/libregrtest (push) Waiting to run
mypy / Run mypy on Lib/tomllib (push) Waiting to run
mypy / Run mypy on Tools/build (push) Waiting to run
mypy / Run mypy on Tools/cases_generator (push) Waiting to run
mypy / Run mypy on Tools/clinic (push) Waiting to run
mypy / Run mypy on Tools/jit (push) Waiting to run
mypy / Run mypy on Tools/peg_generator (push) Waiting to run

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:
Neil Schemenauer 2025-07-08 12:19:57 -07:00 committed by GitHub
parent bc9bc078df
commit b6b99bf7f1
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
4 changed files with 54 additions and 14 deletions

View file

@ -262,9 +262,11 @@ class GCTests(unittest.TestCase):
# 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 @@ class GCTests(unittest.TestCase):
# 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