Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 7b7099c

Browse files
committed
merge 3.2 (#12475)
2 parents 92843e3 + d2ed630 commit 7b7099c

3 files changed

Lines changed: 23 additions & 4 deletions

File tree

Lib/test/test_exceptions.py

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff 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():

Misc/NEWS

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,9 @@ What's New in Python 3.3 Alpha 1?
1010
Core 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

Python/ceval.c

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff 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

30073003
fast_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) {

0 commit comments

Comments
 (0)