mirror of
https://github.com/python/cpython.git
synced 2025-10-10 00:43:41 +00:00
gh-98253: Break potential reference cycles in external code worsened by typing.py lru_cache (#98591)
This commit is contained in:
parent
8bb2303fd7
commit
c314198fad
2 changed files with 21 additions and 3 deletions
|
@ -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)
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue