@@ -160,3 +160,72 @@ def func(my_arg='2'):
160
160
161
161
exc = pickle .loads (pickle .dumps (exc , protocol = protocol ))
162
162
assert exc .__traceback__ .tb_next .tb_frame .f_locals == {'my_variable' : 1 }
163
+
164
+
165
+ class CustomReduceException (Exception ):
166
+ def __init__ (self , message , arg1 , arg2 , arg3 ):
167
+ super ().__init__ (message )
168
+ self .values12 = (arg1 , arg2 )
169
+ self .value3 = arg3
170
+
171
+ def __reduce__ (self ):
172
+ return self .__class__ , self .args + self .values12 + (self .value3 ,)
173
+
174
+
175
+ def test_custom_reduce ():
176
+ try :
177
+ raise CustomReduceException ('foo' , 1 , 2 , 3 )
178
+ except Exception as e :
179
+ exc = e
180
+
181
+ tblib .pickling_support .install (exc )
182
+ exc = pickle .loads (pickle .dumps (exc ))
183
+
184
+ assert isinstance (exc , CustomReduceException )
185
+ assert exc .args == ('foo' ,)
186
+ assert exc .values12 == (1 , 2 )
187
+ assert exc .value3 == 3
188
+ assert exc .__traceback__ is not None
189
+
190
+
191
+ class CustomReduceExException (Exception ):
192
+ def __init__ (self , message , arg1 , arg2 , protocol ):
193
+ super ().__init__ (message )
194
+ self .values12 = (arg1 , arg2 )
195
+ self .value3 = protocol
196
+
197
+ def __reduce_ex__ (self , protocol ):
198
+ return self .__class__ , self .args + self .values12 + (self .value3 ,)
199
+
200
+
201
+ @pytest .mark .parametrize ('protocol' , [None , * list (range (1 , pickle .HIGHEST_PROTOCOL + 1 ))])
202
+ def test_custom_reduce_ex (protocol ):
203
+ try :
204
+ raise CustomReduceExException ('foo' , 1 , 2 , 3 )
205
+ except Exception as e :
206
+ exc = e
207
+
208
+ tblib .pickling_support .install (exc )
209
+ exc = pickle .loads (pickle .dumps (exc , protocol = protocol ))
210
+
211
+ assert isinstance (exc , CustomReduceExException )
212
+ assert exc .args == ('foo' ,)
213
+ assert exc .values12 == (1 , 2 )
214
+ assert exc .value3 == 3
215
+ assert exc .__traceback__ is not None
216
+
217
+
218
+ def test_oserror ():
219
+ try :
220
+ raise OSError (13 , 'Access denied' )
221
+ except Exception as e :
222
+ exc = e
223
+
224
+ tblib .pickling_support .install (exc )
225
+ exc = pickle .loads (pickle .dumps (exc ))
226
+
227
+ assert isinstance (exc , OSError )
228
+ assert exc .args == (13 , 'Access denied' )
229
+ assert exc .errno == 13
230
+ assert exc .strerror == 'Access denied'
231
+ assert exc .__traceback__ is not None
0 commit comments