summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Lib/test/test_functools.py19
-rw-r--r--Misc/NEWS2
-rw-r--r--Modules/_functoolsmodule.c8
3 files changed, 27 insertions, 2 deletions
diff --git a/Lib/test/test_functools.py b/Lib/test/test_functools.py
index 9ea6747188..75427dfad3 100644
--- a/Lib/test/test_functools.py
+++ b/Lib/test/test_functools.py
@@ -1189,6 +1189,25 @@ class TestLRU:
self.assertEqual(misses, 4)
self.assertEqual(currsize, 2)
+ def test_lru_type_error(self):
+ # Regression test for issue #28653.
+ # lru_cache was leaking when one of the arguments
+ # wasn't cacheable.
+
+ @functools.lru_cache(maxsize=None)
+ def infinite_cache(o):
+ pass
+
+ @functools.lru_cache(maxsize=10)
+ def limited_cache(o):
+ pass
+
+ with self.assertRaises(TypeError):
+ infinite_cache([])
+
+ with self.assertRaises(TypeError):
+ limited_cache([])
+
def test_lru_with_maxsize_none(self):
@self.module.lru_cache(maxsize=None)
def fib(n):
diff --git a/Misc/NEWS b/Misc/NEWS
index ee3cb209ee..4e6ee55346 100644
--- a/Misc/NEWS
+++ b/Misc/NEWS
@@ -48,6 +48,8 @@ Library
- Issue #28652: Make loop methods reject socket kinds they do not support.
+- Issue #28653: Fix a refleak in functools.lru_cache.
+
Documentation
-------------
diff --git a/Modules/_functoolsmodule.c b/Modules/_functoolsmodule.c
index fa5fad3e75..2269d05da8 100644
--- a/Modules/_functoolsmodule.c
+++ b/Modules/_functoolsmodule.c
@@ -793,8 +793,10 @@ infinite_lru_cache_wrapper(lru_cache_object *self, PyObject *args, PyObject *kwd
if (!key)
return NULL;
hash = PyObject_Hash(key);
- if (hash == -1)
+ if (hash == -1) {
+ Py_DECREF(key);
return NULL;
+ }
result = _PyDict_GetItem_KnownHash(self->cache, key, hash);
if (result) {
Py_INCREF(result);
@@ -849,8 +851,10 @@ bounded_lru_cache_wrapper(lru_cache_object *self, PyObject *args, PyObject *kwds
if (!key)
return NULL;
hash = PyObject_Hash(key);
- if (hash == -1)
+ if (hash == -1) {
+ Py_DECREF(key);
return NULL;
+ }
link = (lru_list_elem *)_PyDict_GetItem_KnownHash(self->cache, key, hash);
if (link) {
lru_cache_extricate_link(link);