From 2fed98553019df8d72355a90bb31c14c1309be79 Mon Sep 17 00:00:00 2001 From: Wenzel Jakob Date: Mon, 24 Oct 2022 10:51:51 +0200 Subject: [PATCH] break potential reference cycles in external code worsened by typing.py lru_cache (#98253) --- Lib/typing.py | 9 ++++++--- .../2022-10-24-11-01-05.gh-issue-98253.HVd5v4.rst | 10 ++++++++++ 2 files changed, 16 insertions(+), 3 deletions(-) create mode 100644 Misc/NEWS.d/next/Library/2022-10-24-11-01-05.gh-issue-98253.HVd5v4.rst diff --git a/Lib/typing.py b/Lib/typing.py index 95bd61c7f8c61f..be191555205aa1 100644 --- a/Lib/typing.py +++ b/Lib/typing.py @@ -344,6 +344,7 @@ def _flatten_literal_params(parameters): _cleanups = [] +_caches = { } def _tp_cache(func=None, /, *, typed=False): @@ -351,13 +352,15 @@ 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) + 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 00000000000000..00df0070f3b9c1 --- /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.