gh-151728: Clear the typing caches at interpreter shutdown (GH-154858)
encukou <[email protected]> Thu, 30 Jul 2026 08:00:30 -0400 (EDT)
| Newsgroups | gmane.comp.python.cvs |
|---|---|
| Message-ID | <[email protected]> |
https://github.com/python/cpython/commit/22a6c51c94a4fde986b8964f1d36d5ec3ac20dcc commit: 22a6c51c94a4fde986b8964f1d36d5ec3ac20dcc branch: main author: Wenzel Jakob <[email protected]> committer: encukou <[email protected]> date: 2026-07-30T14:00:08+02:00 summary: gh-151728: Clear the typing caches at interpreter shutdown (GH-154858) The typing module caches every subscripted type. When an extension module leaks a reference to typing, these caches also keep types owned by other (correct) extension modules alive past interpreter shutdown, where nothing can free them anymore. The cache_clear callables are already collected in typing._cleanups, so registering them with atexit is enough to avoid this. files: A Misc/NEWS.d/next/Library/2026-07-29-11-05-00.gh-issue-151728.Kq3vTn.rst M Lib/test/libregrtest/utils.py M Lib/typing.py diff --git a/Lib/test/libregrtest/utils.py b/Lib/test/libregrtest/utils.py index 32f02429ff33076..892d204700179f6 100644 --- a/Lib/test/libregrtest/utils.py +++ b/Lib/test/libregrtest/utils.py @@ -272,8 +272,7 @@ def clear_caches(): except KeyError: pass else: - for f in typing._cleanups: - f() + typing._clear_caches() import inspect abs_classes = filter(inspect.isabstract, typing.__dict__.values()) diff --git a/Lib/typing.py b/Lib/typing.py index 054420865d7fb50..809c0ff88607a59 100644 --- a/Lib/typing.py +++ b/Lib/typing.py @@ -19,6 +19,7 @@ """ from abc import abstractmethod, ABCMeta +import atexit import collections from collections import defaultdict import collections.abc @@ -392,6 +393,16 @@ def _flatten_literal_params(parameters): _caches = {} +def _clear_caches(): + for cleanup in _cleanups: + cleanup() + + +# Release the LRU caches at shutdown, they otherwise redistribute reference +# leaks of one extension to types of unrelated ones. See GH-151728. +atexit.register(_clear_caches) + + def _tp_cache(func=None, /, *, typed=False): """Internal wrapper caching __getitem__ of generic types. diff --git a/Misc/NEWS.d/next/Library/2026-07-29-11-05-00.gh-issue-151728.Kq3vTn.rst b/Misc/NEWS.d/next/Library/2026-07-29-11-05-00.gh-issue-151728.Kq3vTn.rst new file mode 100644 index 000000000000000..39c63a1aea3193a --- /dev/null +++ b/Misc/NEWS.d/next/Library/2026-07-29-11-05-00.gh-issue-151728.Kq3vTn.rst @@ -0,0 +1,4 @@ +Clear the internal :mod:`typing` caches from an exit handler. Previously, an +extension module that leaked a reference to :mod:`typing` would also keep every +subscripted type alive past interpreter shutdown, including types owned by +unrelated extension modules. _______________________________________________ Python-checkins mailing list -- [email protected] To unsubscribe send an email to [email protected] https://mail.python.org/mailman3//lists/python-checkins.python.org Member address: [email protected]