@@ -3068,6 +3068,74 @@ def test_frozen_pickle(self):
3068
3068
self .assertIsNot (obj , p )
3069
3069
self .assertEqual (obj , p )
3070
3070
3071
+ @dataclass (frozen = True , slots = True )
3072
+ class FrozenSlotsGetStateClass :
3073
+ foo : str
3074
+ bar : int
3075
+
3076
+ getstate_called : bool = field (default = False , compare = False )
3077
+
3078
+ def __getstate__ (self ):
3079
+ object .__setattr__ (self , 'getstate_called' , True )
3080
+ return [self .foo , self .bar ]
3081
+
3082
+ @dataclass (frozen = True , slots = True )
3083
+ class FrozenSlotsSetStateClass :
3084
+ foo : str
3085
+ bar : int
3086
+
3087
+ setstate_called : bool = field (default = False , compare = False )
3088
+
3089
+ def __setstate__ (self , state ):
3090
+ object .__setattr__ (self , 'setstate_called' , True )
3091
+ object .__setattr__ (self , 'foo' , state [0 ])
3092
+ object .__setattr__ (self , 'bar' , state [1 ])
3093
+
3094
+ @dataclass (frozen = True , slots = True )
3095
+ class FrozenSlotsAllStateClass :
3096
+ foo : str
3097
+ bar : int
3098
+
3099
+ getstate_called : bool = field (default = False , compare = False )
3100
+ setstate_called : bool = field (default = False , compare = False )
3101
+
3102
+ def __getstate__ (self ):
3103
+ object .__setattr__ (self , 'getstate_called' , True )
3104
+ return [self .foo , self .bar ]
3105
+
3106
+ def __setstate__ (self , state ):
3107
+ object .__setattr__ (self , 'setstate_called' , True )
3108
+ object .__setattr__ (self , 'foo' , state [0 ])
3109
+ object .__setattr__ (self , 'bar' , state [1 ])
3110
+
3111
+ def test_frozen_slots_pickle_custom_state (self ):
3112
+ for proto in range (pickle .HIGHEST_PROTOCOL + 1 ):
3113
+ with self .subTest (proto = proto ):
3114
+ obj = self .FrozenSlotsGetStateClass ('a' , 1 )
3115
+ dumped = pickle .dumps (obj , protocol = proto )
3116
+
3117
+ self .assertTrue (obj .getstate_called )
3118
+ self .assertEqual (obj , pickle .loads (dumped ))
3119
+
3120
+ for proto in range (pickle .HIGHEST_PROTOCOL + 1 ):
3121
+ with self .subTest (proto = proto ):
3122
+ obj = self .FrozenSlotsSetStateClass ('a' , 1 )
3123
+ obj2 = pickle .loads (pickle .dumps (obj , protocol = proto ))
3124
+
3125
+ self .assertTrue (obj2 .setstate_called )
3126
+ self .assertEqual (obj , obj2 )
3127
+
3128
+ for proto in range (pickle .HIGHEST_PROTOCOL + 1 ):
3129
+ with self .subTest (proto = proto ):
3130
+ obj = self .FrozenSlotsAllStateClass ('a' , 1 )
3131
+ dumped = pickle .dumps (obj , protocol = proto )
3132
+
3133
+ self .assertTrue (obj .getstate_called )
3134
+
3135
+ obj2 = pickle .loads (dumped )
3136
+ self .assertTrue (obj2 .setstate_called )
3137
+ self .assertEqual (obj , obj2 )
3138
+
3071
3139
def test_slots_with_default_no_init (self ):
3072
3140
# Originally reported in bpo-44649.
3073
3141
@dataclass (slots = True )
0 commit comments