Skip to content

Commit e4d65e3

Browse files
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).
1 parent 762d5ea commit e4d65e3

3 files changed

Lines changed: 32 additions & 2 deletions

File tree

Lib/test/test_functools.py

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1262,14 +1262,24 @@ def test_pickle(self):
12621262

12631263
def test_copy(self):
12641264
cls = self.__class__
1265-
for f in cls.cached_func[0], cls.cached_meth, cls.cached_staticmeth:
1265+
def orig(x, y):
1266+
return 3 * x + y
1267+
part = self.module.partial(orig, 2)
1268+
funcs = (cls.cached_func[0], cls.cached_meth, cls.cached_staticmeth,
1269+
self.module.lru_cache(2)(part))
1270+
for f in funcs:
12661271
with self.subTest(func=f):
12671272
f_copy = copy.copy(f)
12681273
self.assertIs(f_copy, f)
12691274

12701275
def test_deepcopy(self):
12711276
cls = self.__class__
1272-
for f in cls.cached_func[0], cls.cached_meth, cls.cached_staticmeth:
1277+
def orig(x, y):
1278+
return 3 * x + y
1279+
part = self.module.partial(orig, 2)
1280+
funcs = (cls.cached_func[0], cls.cached_meth, cls.cached_staticmeth,
1281+
self.module.lru_cache(2)(part))
1282+
for f in funcs:
12731283
with self.subTest(func=f):
12741284
f_copy = copy.deepcopy(f)
12751285
self.assertIs(f_copy, f)

Misc/NEWS

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,10 @@ Core and Builtins
3636
Library
3737
-------
3838

39+
- Issue #25447: Copying the lru_cache() wrapper object now always works,
40+
independedly from the type of the wrapped object (by returning the original
41+
object unchanged).
42+
3943
- Issue #24103: Fixed possible use after free in ElementTree.XMLPullParser.
4044

4145
- Issue #25860: os.fwalk() no longer skips remaining directories when error

Modules/_functoolsmodule.c

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1053,6 +1053,20 @@ lru_cache_reduce(PyObject *self, PyObject *unused)
10531053
return PyObject_GetAttrString(self, "__qualname__");
10541054
}
10551055

1056+
static PyObject *
1057+
lru_cache_copy(PyObject *self, PyObject *unused)
1058+
{
1059+
Py_INCREF(self);
1060+
return self;
1061+
}
1062+
1063+
static PyObject *
1064+
lru_cache_deepcopy(PyObject *self, PyObject *unused)
1065+
{
1066+
Py_INCREF(self);
1067+
return self;
1068+
}
1069+
10561070
static int
10571071
lru_cache_tp_traverse(lru_cache_object *self, visitproc visit, void *arg)
10581072
{
@@ -1104,6 +1118,8 @@ static PyMethodDef lru_cache_methods[] = {
11041118
{"cache_info", (PyCFunction)lru_cache_cache_info, METH_NOARGS},
11051119
{"cache_clear", (PyCFunction)lru_cache_cache_clear, METH_NOARGS},
11061120
{"__reduce__", (PyCFunction)lru_cache_reduce, METH_NOARGS},
1121+
{"__copy__", (PyCFunction)lru_cache_copy, METH_VARARGS},
1122+
{"__deepcopy__", (PyCFunction)lru_cache_deepcopy, METH_VARARGS},
11071123
{NULL}
11081124
};
11091125

0 commit comments

Comments
 (0)