@@ -868,21 +868,16 @@ def test_builtin_classicmethod(self):
868868 assert depickled_unbound_meth is unbound_classicmethod
869869 assert depickled_clsdict_meth is clsdict_classicmethod
870870
871-
872871 def test_builtin_classmethod (self ):
873872 obj = 1.5 # float object
874873
875874 bound_clsmethod = obj .fromhex # builtin_function_or_method
876875 unbound_clsmethod = type (obj ).fromhex # builtin_function_or_method
877- clsdict_clsmethod = type (
878- obj ).__dict__ ['fromhex' ] # classmethod_descriptor
879876
880877 depickled_bound_meth = pickle_depickle (
881878 bound_clsmethod , protocol = self .protocol )
882879 depickled_unbound_meth = pickle_depickle (
883880 unbound_clsmethod , protocol = self .protocol )
884- depickled_clsdict_meth = pickle_depickle (
885- clsdict_clsmethod , protocol = self .protocol )
886881
887882 # float.fromhex takes a string as input.
888883 arg = "0x1"
@@ -893,6 +888,40 @@ def test_builtin_classmethod(self):
893888 assert depickled_bound_meth (arg ) == bound_clsmethod (arg )
894889 assert depickled_unbound_meth (arg ) == unbound_clsmethod (arg )
895890
891+ @pytest .mark .skipif (
892+ (
893+ sys .version_info >= (3 , 10 , 8 ) and
894+ platform .python_implementation () == 'CPython'
895+ ),
896+
897+ reason = (
898+ "CPython dropped support for pickling classmethod_descriptor,"
899+ "https://github.com/python/cpython/issues/95196"
900+ )
901+
902+ )
903+ def test_builtin_classmethod_descriptor (self ):
904+ # `classmethod_descriptor` is the analogue `classmethod` (used for
905+ # pure Python classes) for builtin types. Until CPython 3.10.8,
906+ # `classmethod_descriptor` implemented an (incorrect) reducer. After
907+ # https://github.com/python/cpython/issues/95196 revealed its
908+ # incorrectness, this reducer was dropped (and not fixed), on the
909+ # ground that pickling its Pythonic equivalent, `classmethod`,
910+ # was never supported in the first place.
911+ # Note that cloudpickle supports pickling `classmethod` objects,
912+ # but never patched pickle's incorrect `classmethod_descriptor`
913+ # reducer: pickling `classmethod_descriptor` objects using cloudpickle
914+ # has always been broken.
915+ obj = 1.5 # float object
916+
917+ clsdict_clsmethod = type (
918+ obj ).__dict__ ['fromhex' ] # classmethod_descriptor
919+
920+ depickled_clsdict_meth = pickle_depickle (
921+ clsdict_clsmethod , protocol = self .protocol )
922+
923+ # float.fromhex takes a string as input.
924+ arg = "0x1"
896925 if platform .python_implementation () == 'CPython' :
897926 # Roundtripping a classmethod_descriptor results in a
898927 # builtin_function_or_method (CPython upstream issue).
0 commit comments