@@ -164,3 +164,95 @@ def func(my_arg='2'):
164164
165165 exc = pickle .loads (pickle .dumps (exc , protocol = protocol )) # noqa: S301
166166 assert exc .__traceback__ .tb_next .tb_frame .f_locals == {'my_variable' : 1 }
167+
168+
169+ class CustomWithAttributesException (Exception ):
170+ def __init__ (self , message , arg1 , arg2 , arg3 ):
171+ super ().__init__ (message )
172+ self .values12 = (arg1 , arg2 )
173+ self .value3 = arg3
174+
175+
176+ def test_custom_with_attributes ():
177+ try :
178+ raise CustomWithAttributesException ('bar' , 1 , 2 , 3 )
179+ except Exception as e :
180+ exc = e
181+
182+ tblib .pickling_support .install (exc )
183+ exc = pickle .loads (pickle .dumps (exc ))
184+
185+ assert isinstance (exc , CustomWithAttributesException )
186+ assert exc .args == ('bar' ,)
187+ assert exc .values12 == (1 , 2 )
188+ assert exc .value3 == 3
189+ assert exc .__traceback__ is not None
190+
191+
192+ class CustomReduceException (Exception ):
193+ def __init__ (self , message , arg1 , arg2 , arg3 ):
194+ super ().__init__ (message )
195+ self .values12 = (arg1 , arg2 )
196+ self .value3 = arg3
197+
198+ def __reduce__ (self ):
199+ return self .__class__ , self .args + self .values12 + (self .value3 ,)
200+
201+
202+ def test_custom_reduce ():
203+ try :
204+ raise CustomReduceException ('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 ))
210+
211+ assert isinstance (exc , CustomReduceException )
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+ class CustomReduceExException (Exception ):
219+ def __init__ (self , message , arg1 , arg2 , protocol ):
220+ super ().__init__ (message )
221+ self .values12 = (arg1 , arg2 )
222+ self .value3 = protocol
223+
224+ def __reduce_ex__ (self , protocol ):
225+ return self .__class__ , self .args + self .values12 + (self .value3 ,)
226+
227+
228+ @pytest .mark .parametrize ('protocol' , [None , * list (range (1 , pickle .HIGHEST_PROTOCOL + 1 ))])
229+ def test_custom_reduce_ex (protocol ):
230+ try :
231+ raise CustomReduceExException ('foo' , 1 , 2 , 3 )
232+ except Exception as e :
233+ exc = e
234+
235+ tblib .pickling_support .install (exc )
236+ exc = pickle .loads (pickle .dumps (exc , protocol = protocol ))
237+
238+ assert isinstance (exc , CustomReduceExException )
239+ assert exc .args == ('foo' ,)
240+ assert exc .values12 == (1 , 2 )
241+ assert exc .value3 == 3
242+ assert exc .__traceback__ is not None
243+
244+
245+ def test_oserror ():
246+ try :
247+ raise OSError (13 , 'Permission denied' )
248+ except Exception as e :
249+ exc = e
250+
251+ tblib .pickling_support .install (exc )
252+ exc = pickle .loads (pickle .dumps (exc ))
253+
254+ assert isinstance (exc , OSError )
255+ assert exc .args == (13 , 'Permission denied' )
256+ assert exc .errno == 13
257+ assert exc .strerror == 'Permission denied'
258+ assert exc .__traceback__ is not None
0 commit comments