mirror of
https://github.com/python/cpython.git
synced 2025-09-26 10:19:53 +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 = []
|
_cleanups = []
|
||||||
|
_caches = {}
|
||||||
|
|
||||||
|
|
||||||
def _tp_cache(func=None, /, *, typed=False):
|
def _tp_cache(func=None, /, *, typed=False):
|
||||||
|
@ -332,13 +333,20 @@ def _tp_cache(func=None, /, *, typed=False):
|
||||||
original function for non-hashable arguments.
|
original function for non-hashable arguments.
|
||||||
"""
|
"""
|
||||||
def decorator(func):
|
def decorator(func):
|
||||||
cached = functools.lru_cache(typed=typed)(func)
|
# The callback 'inner' references the newly created lru_cache
|
||||||
_cleanups.append(cached.cache_clear)
|
# 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)
|
@functools.wraps(func)
|
||||||
def inner(*args, **kwds):
|
def inner(*args, **kwds):
|
||||||
try:
|
try:
|
||||||
return cached(*args, **kwds)
|
return _caches[func](*args, **kwds)
|
||||||
except TypeError:
|
except TypeError:
|
||||||
pass # All real errors (not unhashable args) are raised below.
|
pass # All real errors (not unhashable args) are raised below.
|
||||||
return func(*args, **kwds)
|
return func(*args, **kwds)
|
||||||
|
|
|
@ -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.
|
Loading…
Add table
Add a link
Reference in a new issue