[Python-checkins] cpython (merge 3.2 -> default): merge 3.2 (#12475)
benjamin.peterson
python-checkins at python.org
Sun Jul 3 20:44:36 CEST 2011
http://hg.python.org/cpython/rev/33dca840938d
changeset: 71154:33dca840938d
parent: 71153:65e57bead934
parent: 71152:36bc49565281
user: Benjamin Peterson <benjamin at python.org>
date: Sun Jul 03 13:48:36 2011 -0500
summary:
merge 3.2 (#12475)
files:
Lib/test/test_exceptions.py | 15 +++++++++++++++
Misc/NEWS | 3 +++
Python/ceval.c | 9 +++++----
3 files changed, 23 insertions(+), 4 deletions(-)
diff --git a/Lib/test/test_exceptions.py b/Lib/test/test_exceptions.py
--- a/Lib/test/test_exceptions.py
+++ b/Lib/test/test_exceptions.py
@@ -567,6 +567,21 @@
del g
self.assertEqual(sys.exc_info()[0], TypeError)
+ def test_generator_leaking2(self):
+ # See issue 12475.
+ def g():
+ yield
+ try:
+ raise RuntimeError
+ except RuntimeError:
+ it = g()
+ next(it)
+ try:
+ next(it)
+ except StopIteration:
+ pass
+ self.assertEqual(sys.exc_info(), (None, None, None))
+
def test_generator_finalizing_and_exc_info(self):
# See #7173
def simple_gen():
diff --git a/Misc/NEWS b/Misc/NEWS
--- a/Misc/NEWS
+++ b/Misc/NEWS
@@ -10,6 +10,9 @@
Core and Builtins
-----------------
+- Issue #12475: Prevent generators from leaking their exception state into the
+ callers frame as they return for the last time.
+
- Issue #12291: You can now load multiple marshalled objects from a stream,
with other data interleaved between marshalled objects.
diff --git a/Python/ceval.c b/Python/ceval.c
--- a/Python/ceval.c
+++ b/Python/ceval.c
@@ -1865,10 +1865,6 @@
retval = POP();
f->f_stacktop = stack_pointer;
why = WHY_YIELD;
- /* Put aside the current exception state and restore
- that of the calling frame. This only serves when
- "yield" is used inside an except handler. */
- SWAP_EXC_STATE();
goto fast_yield;
TARGET(POP_EXCEPT)
@@ -3005,6 +3001,11 @@
retval = NULL;
fast_yield:
+ if (co->co_flags & CO_GENERATOR && (why == WHY_YIELD || why == WHY_RETURN))
+ /* Put aside the current exception state and restore that of the
+ calling frame. */
+ SWAP_EXC_STATE();
+
if (tstate->use_tracing) {
if (tstate->c_tracefunc) {
if (why == WHY_RETURN || why == WHY_YIELD) {
--
Repository URL: http://hg.python.org/cpython
More information about the Python-checkins
mailing list