summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSerhiy Storchaka <storchaka@gmail.com>2015-12-28 21:59:09 (GMT)
committerSerhiy Storchaka <storchaka@gmail.com>2015-12-28 21:59:09 (GMT)
commite3a7d26aa68b3068bea6c417f6f61530b6f0794e (patch)
tree7896905c75de979bf486f5d5018a8e7405634cc3
parent1e3c3e906c9f1fcc463cfb3641d078eec773666f (diff)
parente4d65e3aab980cd8c2347d71bc6e26c19227953b (diff)
downloadcpython-e3a7d26aa68b3068bea6c417f6f61530b6f0794e.zip
cpython-e3a7d26aa68b3068bea6c417f6f61530b6f0794e.tar.gz
cpython-e3a7d26aa68b3068bea6c417f6f61530b6f0794e.tar.bz2
Issue #25447: Copying the lru_cache() wrapper object now always works,
independedly from the type of the wrapped object (by returning the original object unchanged).
-rw-r--r--Lib/test/test_functools.py14
-rw-r--r--Misc/NEWS4
-rw-r--r--Modules/_functoolsmodule.c16
3 files changed, 32 insertions, 2 deletions
diff --git a/Lib/test/test_functools.py b/Lib/test/test_functools.py
index d822b2d..cf0b95d 100644
--- a/Lib/test/test_functools.py
+++ b/Lib/test/test_functools.py
@@ -1262,14 +1262,24 @@ class TestLRU:
def test_copy(self):
cls = self.__class__
- for f in cls.cached_func[0], cls.cached_meth, cls.cached_staticmeth:
+ def orig(x, y):
+ return 3 * x + y
+ part = self.module.partial(orig, 2)
+ funcs = (cls.cached_func[0], cls.cached_meth, cls.cached_staticmeth,
+ self.module.lru_cache(2)(part))
+ for f in funcs:
with self.subTest(func=f):
f_copy = copy.copy(f)
self.assertIs(f_copy, f)
def test_deepcopy(self):
cls = self.__class__
- for f in cls.cached_func[0], cls.cached_meth, cls.cached_staticmeth:
+ def orig(x, y):
+ return 3 * x + y
+ part = self.module.partial(orig, 2)
+ funcs = (cls.cached_func[0], cls.cached_meth, cls.cached_staticmeth,
+ self.module.lru_cache(2)(part))
+ for f in funcs:
with self.subTest(func=f):
f_copy = copy.deepcopy(f)
self.assertIs(f_copy, f)
diff --git a/Misc/NEWS b/Misc/NEWS
index e795234..4a5a71e 100644
--- a/Misc/NEWS
+++ b/Misc/NEWS
@@ -123,6 +123,10 @@ Core and Builtins
Library
-------
+- Issue #25447: Copying the lru_cache() wrapper object now always works,
+ independedly from the type of the wrapped object (by returning the original
+ object unchanged).
+
- Issue #25768: Have the functions in compileall return booleans instead of
ints and add proper documentation and tests for the return values.
diff --git a/Modules/_functoolsmodule.c b/Modules/_functoolsmodule.c
index fadc0a9..035d3d9 100644
--- a/Modules/_functoolsmodule.c
+++ b/Modules/_functoolsmodule.c
@@ -1053,6 +1053,20 @@ lru_cache_reduce(PyObject *self, PyObject *unused)
return PyObject_GetAttrString(self, "__qualname__");
}
+static PyObject *
+lru_cache_copy(PyObject *self, PyObject *unused)
+{
+ Py_INCREF(self);
+ return self;
+}
+
+static PyObject *
+lru_cache_deepcopy(PyObject *self, PyObject *unused)
+{
+ Py_INCREF(self);
+ return self;
+}
+
static int
lru_cache_tp_traverse(lru_cache_object *self, visitproc visit, void *arg)
{
@@ -1104,6 +1118,8 @@ static PyMethodDef lru_cache_methods[] = {
{"cache_info", (PyCFunction)lru_cache_cache_info, METH_NOARGS},
{"cache_clear", (PyCFunction)lru_cache_cache_clear, METH_NOARGS},
{"__reduce__", (PyCFunction)lru_cache_reduce, METH_NOARGS},
+ {"__copy__", (PyCFunction)lru_cache_copy, METH_VARARGS},
+ {"__deepcopy__", (PyCFunction)lru_cache_deepcopy, METH_VARARGS},
{NULL}
};