summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorWenzel Jakob <wenzel.jakob@epfl.ch>2022-11-30 08:33:32 (GMT)
committerGitHub <noreply@github.com>2022-11-30 08:33:32 (GMT)
commitc314198fadd3dc79ee15f375a409163d8fb33586 (patch)
tree3638e07e4a904b8b9cd53c47cbe71b096247c4f1
parent8bb2303fd75c299d8fc85229889ac75e867c135c (diff)
downloadcpython-c314198fadd3dc79ee15f375a409163d8fb33586.zip
cpython-c314198fadd3dc79ee15f375a409163d8fb33586.tar.gz
cpython-c314198fadd3dc79ee15f375a409163d8fb33586.tar.bz2
gh-98253: Break potential reference cycles in external code worsened by typing.py lru_cache (#98591)
-rw-r--r--Lib/typing.py14
-rw-r--r--Misc/NEWS.d/next/Library/2022-10-24-11-01-05.gh-issue-98253.HVd5v4.rst10
2 files changed, 21 insertions, 3 deletions
diff --git a/Lib/typing.py b/Lib/typing.py
index 127e3c9..38e227e3c 100644
--- a/Lib/typing.py
+++ b/Lib/typing.py
@@ -325,6 +325,7 @@ def _flatten_literal_params(parameters):
_cleanups = []
+_caches = {}
def _tp_cache(func=None, /, *, typed=False):
@@ -332,13 +333,20 @@ def _tp_cache(func=None, /, *, typed=False):
original function for non-hashable arguments.
"""
def decorator(func):
- cached = functools.lru_cache(typed=typed)(func)
- _cleanups.append(cached.cache_clear)
+ # The callback 'inner' references the newly created lru_cache
+ # indirectly by performing a lookup in the global '_caches' dictionary.
+ # This breaks a reference that can be problematic when combined with
+ # C API extensions that leak references to types. See GH-98253.
+
+ cache = functools.lru_cache(typed=typed)(func)
+ _caches[func] = cache
+ _cleanups.append(cache.cache_clear)
+ del cache
@functools.wraps(func)
def inner(*args, **kwds):
try:
- return cached(*args, **kwds)
+ return _caches[func](*args, **kwds)
except TypeError:
pass # All real errors (not unhashable args) are raised below.
return func(*args, **kwds)
diff --git a/Misc/NEWS.d/next/Library/2022-10-24-11-01-05.gh-issue-98253.HVd5v4.rst b/Misc/NEWS.d/next/Library/2022-10-24-11-01-05.gh-issue-98253.HVd5v4.rst
new file mode 100644
index 0000000..00df007
--- /dev/null
+++ b/Misc/NEWS.d/next/Library/2022-10-24-11-01-05.gh-issue-98253.HVd5v4.rst
@@ -0,0 +1,10 @@
+The implementation of the typing module is now more resilient to reference
+leaks in binary extension modules.
+
+Previously, a reference leak in a typed C API-based extension module could leak
+internals of the typing module, which could in turn introduce leaks in
+essentially any other package with typed function signatures. Although the
+typing package is not the original source of the problem, such non-local
+dependences exacerbate debugging of large-scale projects, and the
+implementation was therefore changed to reduce harm by providing better
+isolation.