1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83
|
From 9b332800fa09bec1f03fd4dd10ca69d1655c809c Mon Sep 17 00:00:00 2001
From: Daniel Garcia Moreno <daniel.garcia@suse.com>
Date: Fri, 28 Oct 2022 13:55:45 +0200
Subject: [PATCH 1/4] Move builtin classmethod_descriptor to a different test
This patch mvoes the builtin classmethod descriptor test to a different
one and mark it to skip for python >= 3.10.8. The classmethod descriptor
serializarion was removed from python in these releases:
https://docs.python.org/3.10/whatsnew/changelog.html#id3
More information in the github issue:
https://github.com/python/cpython/issues/95196
Fix https://github.com/cloudpipe/cloudpickle/issues/485
---
tests/cloudpickle_test.py | 20 +++++++++++++++-----
1 file changed, 15 insertions(+), 5 deletions(-)
--- a/tests/cloudpickle_test.py
+++ b/tests/cloudpickle_test.py
@@ -868,21 +868,16 @@
assert depickled_unbound_meth is unbound_classicmethod
assert depickled_clsdict_meth is clsdict_classicmethod
-
def test_builtin_classmethod(self):
obj = 1.5 # float object
bound_clsmethod = obj.fromhex # builtin_function_or_method
unbound_clsmethod = type(obj).fromhex # builtin_function_or_method
- clsdict_clsmethod = type(
- obj).__dict__['fromhex'] # classmethod_descriptor
depickled_bound_meth = pickle_depickle(
bound_clsmethod, protocol=self.protocol)
depickled_unbound_meth = pickle_depickle(
unbound_clsmethod, protocol=self.protocol)
- depickled_clsdict_meth = pickle_depickle(
- clsdict_clsmethod, protocol=self.protocol)
# float.fromhex takes a string as input.
arg = "0x1"
@@ -893,6 +888,40 @@
assert depickled_bound_meth(arg) == bound_clsmethod(arg)
assert depickled_unbound_meth(arg) == unbound_clsmethod(arg)
+ @pytest.mark.skipif(
+ (
+ sys.version_info >= (3, 10, 8) and
+ platform.python_implementation() == 'CPython'
+ ),
+
+ reason=(
+ "CPython dropped support for pickling classmethod_descriptor,"
+ "https://github.com/python/cpython/issues/95196"
+ )
+
+ )
+ def test_builtin_classmethod_descriptor(self):
+ # `classmethod_descriptor` is the analogue `classmethod` (used for
+ # pure Python classes) for builtin types. Until CPython 3.10.8,
+ # `classmethod_descriptor` implemented an (incorrect) reducer. After
+ # https://github.com/python/cpython/issues/95196 revealed its
+ # incorrectness, this reducer was dropped (and not fixed), on the
+ # ground that pickling its Pythonic equivalent, `classmethod`,
+ # was never supported in the first place.
+ # Note that cloudpickle supports pickling `classmethod` objects,
+ # but never patched pickle's incorrect `classmethod_descriptor`
+ # reducer: pickling `classmethod_descriptor` objects using cloudpickle
+ # has always been broken.
+ obj = 1.5 # float object
+
+ clsdict_clsmethod = type(
+ obj).__dict__['fromhex'] # classmethod_descriptor
+
+ depickled_clsdict_meth = pickle_depickle(
+ clsdict_clsmethod, protocol=self.protocol)
+
+ # float.fromhex takes a string as input.
+ arg = "0x1"
if platform.python_implementation() == 'CPython':
# Roundtripping a classmethod_descriptor results in a
# builtin_function_or_method (CPython upstream issue).
|