Let trackref release classes defined at run time (#7922)

This commit is contained in:
Adrian 2026-08-10 10:09:57 +02:00 committed by GitHub
parent c285f4cb18
commit afbd2c9320
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 17 additions and 4 deletions

View File

@ -14,7 +14,6 @@ This library has a minimal performance impact.
from __future__ import annotations
from collections import defaultdict
from operator import itemgetter
from time import monotonic_ns
from types import NoneType
@ -28,8 +27,8 @@ if TYPE_CHECKING:
from typing_extensions import Self
live_refs: defaultdict[type, WeakKeyDictionary[object, float]] = defaultdict(
WeakKeyDictionary
live_refs: WeakKeyDictionary[type, WeakKeyDictionary[object, float]] = (
WeakKeyDictionary()
)
@ -41,7 +40,11 @@ class object_ref:
def __new__(cls, *args: Any, **kwargs: Any) -> Self:
obj = object.__new__(cls)
live_refs[cls][obj] = monotonic_ns()
try:
refs = live_refs[cls]
except KeyError:
refs = live_refs[cls] = WeakKeyDictionary()
refs[obj] = monotonic_ns()
return obj

View File

@ -124,3 +124,13 @@ def test_iter_all():
o2 = Bar() # noqa: F841
o3 = Foo()
assert set(trackref.iter_all("Foo")) == {o1, o3}
def test_run_time_classes() -> None:
for _ in range(10):
base = type("Baz", (trackref.object_ref,), {})
base()
del base
garbage_collect()
assert not list(trackref.iter_all("Baz"))
assert sum(1 for cls in trackref.live_refs if cls.__name__ == "Baz") == 0