Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 1 addition & 2 deletions Lib/test/libregrtest/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -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())
Expand Down
11 changes: 11 additions & 0 deletions Lib/typing.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
"""

from abc import abstractmethod, ABCMeta
import atexit
import collections
from collections import defaultdict
import collections.abc
Expand Down Expand Up @@ -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.

Expand Down
Original file line number Diff line number Diff line change
@@ -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.
Loading