File tree Expand file tree Collapse file tree 2 files changed +19
-0
lines changed Expand file tree Collapse file tree 2 files changed +19
-0
lines changed Original file line number Diff line number Diff line change @@ -584,13 +584,21 @@ static void GREENLET_NOINLINE(g_initialstub)(void* mark)
584
584
{
585
585
int err ;
586
586
PyObject * o ;
587
+ PyObject * exc , * val , * tb ;
587
588
589
+ /* save exception in case getattr clears it */
590
+ PyErr_Fetch (& exc , & val , & tb );
588
591
/* ts_target.run is the object to call in the new greenlet */
589
592
PyObject * run = PyObject_GetAttrString ((PyObject * ) ts_target , "run" );
590
593
if (run == NULL ) {
591
594
g_passaround_clear ();
595
+ Py_XDECREF (exc );
596
+ Py_XDECREF (val );
597
+ Py_XDECREF (tb );
592
598
return ;
593
599
}
600
+ /* restore saved exception */
601
+ PyErr_Restore (exc , val , tb );
594
602
/* now use run_info to store the statedict */
595
603
o = ts_target -> run_info ;
596
604
ts_target -> run_info = green_statedict (ts_target -> parent );
Original file line number Diff line number Diff line change @@ -320,3 +320,14 @@ def test_parent_return_failure(self):
320
320
g2 = greenlet (lambda : None , parent = g1 )
321
321
# AttributeError should propagate to us, no fatal errors
322
322
self .assertRaises (AttributeError , g2 .switch )
323
+
324
+ def test_throw_exception_not_lost (self ):
325
+ class mygreenlet (greenlet ):
326
+ def __getattribute__ (self , name ):
327
+ try :
328
+ raise Exception ()
329
+ except :
330
+ pass
331
+ return greenlet .__getattribute__ (self , name )
332
+ g = mygreenlet (lambda : None )
333
+ self .assertRaises (SomeError , g .throw , SomeError ())
You can’t perform that action at this time.
0 commit comments