[Python-checkins] cpython (3.5): Issue #28653: Fix a refleak in functools.lru_cache.

yury.selivanov python-checkins at python.org
Wed Nov 9 18:57:15 EST 2016


https://hg.python.org/cpython/rev/ba59f3328032
changeset: 105030:ba59f3328032
branch: 3.5
parent: 105027:d926b484d33a
user: Yury Selivanov <yury at magic.io>
date: Wed Nov 09 18:55:45 2016 -0500
summary:
 Issue #28653: Fix a refleak in functools.lru_cache.
files:
 Lib/test/test_functools.py | 19 +++++++++++++++++++
 Misc/NEWS | 2 ++
 Modules/_functoolsmodule.c | 8 ++++++--
 3 files changed, 27 insertions(+), 2 deletions(-)
diff --git a/Lib/test/test_functools.py b/Lib/test/test_functools.py
--- a/Lib/test/test_functools.py
+++ b/Lib/test/test_functools.py
@@ -1162,6 +1162,25 @@
 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
--- a/Misc/NEWS
+++ b/Misc/NEWS
@@ -457,6 +457,8 @@
 
 - Issue #28652: Make loop methods reject socket kinds they do not support.
 
+- Issue #28653: Fix a refleak in functools.lru_cache.
+
 IDLE
 ----
 
diff --git a/Modules/_functoolsmodule.c b/Modules/_functoolsmodule.c
--- a/Modules/_functoolsmodule.c
+++ b/Modules/_functoolsmodule.c
@@ -781,8 +781,10 @@
 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);
@@ -837,8 +839,10 @@
 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);
-- 
Repository URL: https://hg.python.org/cpython


More information about the Python-checkins mailing list

AltStyle によって変換されたページ (->オリジナル) /