Commit 45120f27 authored by Serhiy Storchaka's avatar Serhiy Storchaka

Issue #25447: The lru_cache() wrapper objects now can be copied and pickled

(by returning the original object unchanged).
parent a7b83b43
import abc
import collections
import copy
from itertools import permutations
import pickle
from random import choice
......@@ -1251,11 +1252,64 @@ class TestLRU:
self.assertEqual(b.f.cache_info(), X.f.cache_info())
self.assertEqual(c.f.cache_info(), X.f.cache_info())
class TestLRUC(TestLRU, unittest.TestCase):
module = c_functools
def test_pickle(self):
cls = self.__class__
for f in cls.cached_func[0], cls.cached_meth, cls.cached_staticmeth:
for proto in range(pickle.HIGHEST_PROTOCOL + 1):
with self.subTest(proto=proto, func=f):
f_copy = pickle.loads(pickle.dumps(f, proto))
self.assertIs(f_copy, f)
def test_copy(self):
cls = self.__class__
for f in cls.cached_func[0], cls.cached_meth, cls.cached_staticmeth:
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:
with self.subTest(func=f):
f_copy = copy.deepcopy(f)
self.assertIs(f_copy, f)
@py_functools.lru_cache()
def py_cached_func(x, y):
return 3 * x + y
@c_functools.lru_cache()
def c_cached_func(x, y):
return 3 * x + y
class TestLRUPy(TestLRU, unittest.TestCase):
module = py_functools
cached_func = py_cached_func,
@module.lru_cache()
def cached_meth(self, x, y):
return 3 * x + y
@staticmethod
@module.lru_cache()
def cached_staticmeth(x, y):
return 3 * x + y
class TestLRUC(TestLRU, unittest.TestCase):
module = c_functools
cached_func = c_cached_func,
@module.lru_cache()
def cached_meth(self, x, y):
return 3 * x + y
@staticmethod
@module.lru_cache()
def cached_staticmeth(x, y):
return 3 * x + y
class TestSingleDispatch(unittest.TestCase):
......
......@@ -45,6 +45,9 @@ Core and Builtins
Library
-------
- Issue #25447: The lru_cache() wrapper objects now can be copied and pickled
(by returning the original object unchanged).
- Issue #25390: typing: Don't crash on Union[str, Pattern].
- Issue #25441: asyncio: Raise error from drain() when socket is closed.
......
......@@ -1047,6 +1047,12 @@ lru_cache_cache_clear(lru_cache_object *self, PyObject *unused)
Py_RETURN_NONE;
}
static PyObject *
lru_cache_reduce(PyObject *self, PyObject *unused)
{
return PyObject_GetAttrString(self, "__qualname__");
}
static int
lru_cache_tp_traverse(lru_cache_object *self, visitproc visit, void *arg)
{
......@@ -1097,6 +1103,7 @@ cache_info_type: namedtuple class with the fields:\n\
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},
{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