[Python-checkins] cpython (merge 3.6 -> default): Merge 3.6 (issue #28653)

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


https://hg.python.org/cpython/rev/784fea019cab
changeset:   105032:784fea019cab
parent:      105029:437564294e6c
parent:      105031:5b253d641826
user:        Yury Selivanov <yury at magic.io>
date:        Wed Nov 09 18:57:00 2016 -0500
summary:
  Merge 3.6 (issue #28653)

files:
  Lib/test/test_functools.py |  19 +++++++++++++++++++
  Modules/_functoolsmodule.c |   8 ++++++--
  2 files changed, 25 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
@@ -1189,6 +1189,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/Modules/_functoolsmodule.c b/Modules/_functoolsmodule.c
--- a/Modules/_functoolsmodule.c
+++ b/Modules/_functoolsmodule.c
@@ -793,8 +793,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);
@@ -849,8 +851,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