[pypy-commit] pypy default: Oops, bug: if a throw() propagates the error sent in, then the 'return'
arigo
pypy.commits at gmail.com
Fri Sep 16 10:49:42 EDT 2016
Author: Armin Rigo <arigo at tunes.org>
Branch:
Changeset: r87141:47fa78e23bfb
Date: 2016-09-16 16:49 +0200
http://bitbucket.org/pypy/pypy/changeset/47fa78e23bfb/
Log: Oops, bug: if a throw() propagates the error sent in, then the
'return' trace was not called. This can confuse debuggers/profilers.
diff --git a/pypy/interpreter/pyframe.py b/pypy/interpreter/pyframe.py
--- a/pypy/interpreter/pyframe.py
+++ b/pypy/interpreter/pyframe.py
@@ -276,18 +276,17 @@
if next_instr != 0:
self.pushvalue(w_inputvalue)
#
- try:
- w_exitvalue = self.dispatch(self.pycode, next_instr,
- executioncontext)
- except Exception:
- executioncontext.return_trace(self, self.space.w_None)
- raise
+ w_exitvalue = self.dispatch(self.pycode, next_instr,
+ executioncontext)
executioncontext.return_trace(self, w_exitvalue)
# it used to say self.last_exception = None
# this is now done by the code in pypyjit module
# since we don't want to invalidate the virtualizable
# for no good reason
got_exception = False
+ except Exception:
+ executioncontext.return_trace(self, self.space.w_None)
+ raise
finally:
executioncontext.leave(self, w_exitvalue, got_exception)
return w_exitvalue
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
@@ -562,3 +562,21 @@
res = f(10).g()
sys.settrace(None)
assert res == 10
+
+ def test_throw_trace_bug(self):
+ import sys
+ def f():
+ yield 5
+ gen = f()
+ assert next(gen) == 5
+ seen = []
+ def trace_func(frame, event, *args):
+ seen.append(event)
+ return trace_func
+ sys.settrace(trace_func)
+ try:
+ gen.throw(ValueError)
+ except ValueError:
+ pass
+ sys.settrace(None)
+ assert seen == ['call', 'exception', 'return']
More information about the pypy-commit
mailing list