Commit e4d65e3a authored by Serhiy Storchaka's avatar Serhiy Storchaka

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).
parent 762d5ea8
...@@ -1262,14 +1262,24 @@ class TestLRU: ...@@ -1262,14 +1262,24 @@ class TestLRU:
def test_copy(self): def test_copy(self):
cls = self.__class__ 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): with self.subTest(func=f):
f_copy = copy.copy(f) f_copy = copy.copy(f)
self.assertIs(f_copy, f) self.assertIs(f_copy, f)
def test_deepcopy(self): def test_deepcopy(self):
cls = self.__class__ 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): with self.subTest(func=f):
f_copy = copy.deepcopy(f) f_copy = copy.deepcopy(f)
self.assertIs(f_copy, f) self.assertIs(f_copy, f)
......
...@@ -36,6 +36,10 @@ Core and Builtins ...@@ -36,6 +36,10 @@ Core and Builtins
Library 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 #24103: Fixed possible use after free in ElementTree.XMLPullParser. - Issue #24103: Fixed possible use after free in ElementTree.XMLPullParser.
- Issue #25860: os.fwalk() no longer skips remaining directories when error - Issue #25860: os.fwalk() no longer skips remaining directories when error
......
...@@ -1053,6 +1053,20 @@ lru_cache_reduce(PyObject *self, PyObject *unused) ...@@ -1053,6 +1053,20 @@ lru_cache_reduce(PyObject *self, PyObject *unused)
return PyObject_GetAttrString(self, "__qualname__"); 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 static int
lru_cache_tp_traverse(lru_cache_object *self, visitproc visit, void *arg) lru_cache_tp_traverse(lru_cache_object *self, visitproc visit, void *arg)
{ {
...@@ -1104,6 +1118,8 @@ static PyMethodDef lru_cache_methods[] = { ...@@ -1104,6 +1118,8 @@ static PyMethodDef lru_cache_methods[] = {
{"cache_info", (PyCFunction)lru_cache_cache_info, METH_NOARGS}, {"cache_info", (PyCFunction)lru_cache_cache_info, METH_NOARGS},
{"cache_clear", (PyCFunction)lru_cache_cache_clear, METH_NOARGS}, {"cache_clear", (PyCFunction)lru_cache_cache_clear, METH_NOARGS},
{"__reduce__", (PyCFunction)lru_cache_reduce, METH_NOARGS}, {"__reduce__", (PyCFunction)lru_cache_reduce, METH_NOARGS},
{"__copy__", (PyCFunction)lru_cache_copy, METH_VARARGS},
{"__deepcopy__", (PyCFunction)lru_cache_deepcopy, METH_VARARGS},
{NULL} {NULL}
}; };
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment