File tree Expand file tree Collapse file tree 3 files changed +32
-0
lines changed
Expand file tree Collapse file tree 3 files changed +32
-0
lines changed Original file line number Diff line number Diff line change 11In development
22==============
33
4+ 3.1.2
5+ =====
6+
7+ - Fix pickling of classes containing type annotations for Python 3.14
8+ ([ PR #578 ] ( https://github.com/cloudpipe/cloudpickle/pull/578 ) )
9+
4103.1.1
511=====
612
Original file line number Diff line number Diff line change @@ -783,6 +783,12 @@ def _class_getstate(obj):
783783
784784 clsdict .pop ("__dict__" , None ) # unpicklable property object
785785
786+ if sys .version_info >= (3 , 14 ):
787+ # PEP-649/749: __annotate_func__ contains a closure that references the class
788+ # dict. We need to exclude it from pickling. Python will recreate it when
789+ # __annotations__ is accessed at unpickling time.
790+ clsdict .pop ("__annotate_func__" , None )
791+
786792 return (clsdict , {})
787793
788794
@@ -1190,6 +1196,10 @@ def _class_setstate(obj, state):
11901196 for subclass in registry :
11911197 obj .register (subclass )
11921198
1199+ # PEP-649/749: During pickling, we excluded the __annotate_func__ attribute but it
1200+ # will be created by Python. Subsequently, annotations will be recreated when
1201+ # __annotations__ is accessed.
1202+
11931203 return obj
11941204
11951205
Original file line number Diff line number Diff line change @@ -2672,6 +2672,22 @@ class C:
26722672 C1 = pickle_depickle (C , protocol = self .protocol )
26732673 assert C1 .__annotations__ == C .__annotations__
26742674
2675+ def test_class_annotations_abstractclass (self ):
2676+ # see https://github.com/cloudpipe/cloudpickle/issues/572
2677+
2678+ class C (abc .ABC ):
2679+ a : int
2680+
2681+ C1 = pickle_depickle (C , protocol = self .protocol )
2682+ assert C1 .__annotations__ == C .__annotations__
2683+ C2 = pickle_depickle (C1 , protocol = self .protocol )
2684+ if sys .version_info >= (3 , 14 ):
2685+ # check that __annotate_func__ is created by Python
2686+ assert hasattr (C2 , "__annotate_func__" )
2687+ assert C2 .__annotations__ == C1 .__annotations__
2688+ c2 = C2 ()
2689+ assert isinstance (c2 , C2 )
2690+
26752691 def test_function_annotations (self ):
26762692 def f (a : int ) -> str :
26772693 pass
You can’t perform that action at this time.
0 commit comments