File tree Expand file tree Collapse file tree
Expand file tree Collapse file tree Original file line number Diff line number Diff line change @@ -567,6 +567,21 @@ def yield_raise():
567567 del g
568568 self .assertEqual (sys .exc_info ()[0 ], TypeError )
569569
570+ def test_generator_leaking2 (self ):
571+ # See issue 12475.
572+ def g ():
573+ yield
574+ try :
575+ raise RuntimeError
576+ except RuntimeError :
577+ it = g ()
578+ next (it )
579+ try :
580+ next (it )
581+ except StopIteration :
582+ pass
583+ self .assertEqual (sys .exc_info (), (None , None , None ))
584+
570585 def test_generator_finalizing_and_exc_info (self ):
571586 # See #7173
572587 def simple_gen ():
Original file line number Diff line number Diff line change @@ -10,6 +10,9 @@ What's New in Python 3.3 Alpha 1?
1010Core and Builtins
1111-----------------
1212
13+ - Issue #12475: Prevent generators from leaking their exception state into the
14+ callers frame as they return for the last time.
15+
1316- Issue #12291: You can now load multiple marshalled objects from a stream,
1417 with other data interleaved between marshalled objects.
1518
Original file line number Diff line number Diff line change @@ -1865,10 +1865,6 @@ PyEval_EvalFrameEx(PyFrameObject *f, int throwflag)
18651865 retval = POP ();
18661866 f -> f_stacktop = stack_pointer ;
18671867 why = WHY_YIELD ;
1868- /* Put aside the current exception state and restore
1869- that of the calling frame. This only serves when
1870- "yield" is used inside an except handler. */
1871- SWAP_EXC_STATE ();
18721868 goto fast_yield ;
18731869
18741870 TARGET (POP_EXCEPT )
@@ -3005,6 +3001,11 @@ PyEval_EvalFrameEx(PyFrameObject *f, int throwflag)
30053001 retval = NULL ;
30063002
30073003fast_yield :
3004+ if (co -> co_flags & CO_GENERATOR && (why == WHY_YIELD || why == WHY_RETURN ))
3005+ /* Put aside the current exception state and restore that of the
3006+ calling frame. */
3007+ SWAP_EXC_STATE ();
3008+
30083009 if (tstate -> use_tracing ) {
30093010 if (tstate -> c_tracefunc ) {
30103011 if (why == WHY_RETURN || why == WHY_YIELD ) {
You can’t perform that action at this time.
0 commit comments