Author: Armin Rigo <ar...@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'] _______________________________________________ pypy-commit mailing list pypy-commit@python.org https://mail.python.org/mailman/listinfo/pypy-commit