Author: Antonio Cuni <[email protected]>
Branch: py3k
Changeset: r57349:50440c0c0292
Date: 2012-09-14 16:35 +0200
http://bitbucket.org/pypy/pypy/changeset/50440c0c0292/
Log: don't clear the exception state between yields inside generators
diff --git a/pypy/interpreter/pyframe.py b/pypy/interpreter/pyframe.py
--- a/pypy/interpreter/pyframe.py
+++ b/pypy/interpreter/pyframe.py
@@ -132,9 +132,12 @@
assert self.w_globals is not None
self.w_locals = self.w_globals
+ def is_generator(self):
+ return self.getcode().co_flags & pycode.CO_GENERATOR
+
def run(self):
"""Start this frame's execution."""
- if self.getcode().co_flags & pycode.CO_GENERATOR:
+ if self.is_generator():
from pypy.interpreter.generator import GeneratorIterator
return self.space.wrap(GeneratorIterator(self))
else:
@@ -179,7 +182,9 @@
executioncontext.return_trace(self, w_exitvalue)
# clean up the exception, might be useful for not
# allocating exception objects in some cases
- self.last_exception = None
+ # if it's a generator, we have to preserve the exception state
+ if not self.is_generator():
+ self.last_exception = None
got_exception = False
finally:
executioncontext.leave(self, w_exitvalue, got_exception)
diff --git a/pypy/interpreter/test/test_pyframe.py
b/pypy/interpreter/test/test_pyframe.py
--- a/pypy/interpreter/test/test_pyframe.py
+++ b/pypy/interpreter/test/test_pyframe.py
@@ -461,3 +461,16 @@
assert seen == [(1, f, firstline + 6, 'line', None),
(1, f, firstline + 7, 'line', None),
(1, f, firstline + 8, 'line', None)]
+
+ def test_preserve_exc_state_in_generators(self):
+ import sys
+ def yield_raise():
+ try:
+ raise KeyError("caught")
+ except KeyError:
+ yield sys.exc_info()[0]
+ yield sys.exc_info()[0]
+
+ it = yield_raise()
+ assert next(it) is KeyError
+ assert next(it) is KeyError
_______________________________________________
pypy-commit mailing list
[email protected]
http://mail.python.org/mailman/listinfo/pypy-commit