From abe2e5a2afb7c32065276833ca84210e47499280 Mon Sep 17 00:00:00 2001 From: Serhiy Storchaka Date: Mon, 29 Aug 2022 13:07:44 +0300 Subject: [PATCH] gh-95196: Disable incorrect pickling of the C implemented classmethod descriptors --- Lib/test/pickletester.py | 21 ++++++++++++++++++- ...2-08-29-13-06-58.gh-issue-95196.eGRR4b.rst | 1 + Objects/descrobject.c | 2 +- 3 files changed, 22 insertions(+), 2 deletions(-) create mode 100644 Misc/NEWS.d/next/Core and Builtins/2022-08-29-13-06-58.gh-issue-95196.eGRR4b.rst diff --git a/Lib/test/pickletester.py b/Lib/test/pickletester.py index 21419e11c87497..c0267c2663f7c7 100644 --- a/Lib/test/pickletester.py +++ b/Lib/test/pickletester.py @@ -2776,6 +2776,15 @@ def pie(self): unpickled = self.loads(self.dumps(method, proto)) self.assertEqual(method(obj), unpickled(obj)) + descriptors = ( + PyMethodsTest.__dict__['cheese'], + PyMethodsTest.__dict__['wine'], + ) + for proto in range(pickle.HIGHEST_PROTOCOL + 1): + for descr in descriptors: + with self.subTest(proto=proto, descr=descr): + self.assertRaises(TypeError, self.dumps, descr, proto) + def test_c_methods(self): global Subclass class Subclass(tuple): @@ -2805,12 +2814,22 @@ class Nested(str): (Subclass.Nested("sweet").count, ("e",)), (Subclass.Nested.count, (Subclass.Nested("sweet"), "e")), ) - for proto in range(pickle.HIGHEST_PROTOCOL + 1): + #for proto in range(pickle.HIGHEST_PROTOCOL + 1): + for proto in [5]: for method, args in c_methods: with self.subTest(proto=proto, method=method): unpickled = self.loads(self.dumps(method, proto)) self.assertEqual(method(*args), unpickled(*args)) + descriptors = ( + bytearray.__dict__['maketrans'], + dict.__dict__['fromkeys'], + ) + for proto in range(pickle.HIGHEST_PROTOCOL + 1): + for descr in descriptors: + with self.subTest(proto=proto, descr=descr): + self.assertRaises(TypeError, self.dumps, descr, proto) + def test_compat_pickle(self): tests = [ (range(1, 7), '__builtin__', 'xrange'), diff --git a/Misc/NEWS.d/next/Core and Builtins/2022-08-29-13-06-58.gh-issue-95196.eGRR4b.rst b/Misc/NEWS.d/next/Core and Builtins/2022-08-29-13-06-58.gh-issue-95196.eGRR4b.rst new file mode 100644 index 00000000000000..37534fa1752550 --- /dev/null +++ b/Misc/NEWS.d/next/Core and Builtins/2022-08-29-13-06-58.gh-issue-95196.eGRR4b.rst @@ -0,0 +1 @@ +Disable incorrect pickling of the C implemented classmethod descriptors. diff --git a/Objects/descrobject.c b/Objects/descrobject.c index 82570e085143ed..a2974f91aaaec3 100644 --- a/Objects/descrobject.c +++ b/Objects/descrobject.c @@ -776,7 +776,7 @@ PyTypeObject PyClassMethodDescr_Type = { 0, /* tp_weaklistoffset */ 0, /* tp_iter */ 0, /* tp_iternext */ - descr_methods, /* tp_methods */ + 0, /* tp_methods */ descr_members, /* tp_members */ method_getset, /* tp_getset */ 0, /* tp_base */