This is Richie Hindle's patch:
[ 631276 ] Exceptions raised by line trace function It conflicted with the patches from Armin I just checked it, so I had to so some bits by hand.
This commit is contained in:
parent
019a78e76d
commit
006c75265f
|
@ -178,23 +178,48 @@ class TraceTestCase(unittest.TestCase):
|
||||||
self.run_test2(settrace_and_raise)
|
self.run_test2(settrace_and_raise)
|
||||||
|
|
||||||
class RaisingTraceFuncTestCase(unittest.TestCase):
|
class RaisingTraceFuncTestCase(unittest.TestCase):
|
||||||
def test_it(self):
|
def trace(self, frame, event, arg):
|
||||||
def tr(frame, event, arg):
|
"""A trace function that raises an exception in response to a
|
||||||
|
specific trace event."""
|
||||||
|
if event == self.raiseOnEvent:
|
||||||
raise ValueError # just something that isn't RuntimeError
|
raise ValueError # just something that isn't RuntimeError
|
||||||
def f():
|
else:
|
||||||
|
return self.trace
|
||||||
|
|
||||||
|
def f(self):
|
||||||
|
"""The function to trace; raises an exception if that's the case
|
||||||
|
we're testing, so that the 'exception' trace event fires."""
|
||||||
|
if self.raiseOnEvent == 'exception':
|
||||||
|
x = 0
|
||||||
|
y = 1/x
|
||||||
|
else:
|
||||||
return 1
|
return 1
|
||||||
|
|
||||||
|
def run_test_for_event(self, event):
|
||||||
|
"""Tests that an exception raised in response to the given event is
|
||||||
|
handled OK."""
|
||||||
|
self.raiseOnEvent = event
|
||||||
try:
|
try:
|
||||||
for i in xrange(sys.getrecursionlimit() + 1):
|
for i in xrange(sys.getrecursionlimit() + 1):
|
||||||
sys.settrace(tr)
|
sys.settrace(self.trace)
|
||||||
try:
|
try:
|
||||||
f()
|
self.f()
|
||||||
except ValueError:
|
except ValueError:
|
||||||
pass
|
pass
|
||||||
else:
|
else:
|
||||||
self.fail("exception not thrown!")
|
self.fail("exception not thrown!")
|
||||||
except RuntimeError:
|
except RuntimeError:
|
||||||
self.fail("recursion counter not reset")
|
self.fail("recursion counter not reset")
|
||||||
|
|
||||||
|
# Test the handling of exceptions raised by each kind of trace event.
|
||||||
|
def test_call(self):
|
||||||
|
self.run_test_for_event('call')
|
||||||
|
def test_line(self):
|
||||||
|
self.run_test_for_event('line')
|
||||||
|
def test_return(self):
|
||||||
|
self.run_test_for_event('return')
|
||||||
|
def test_exception(self):
|
||||||
|
self.run_test_for_event('exception')
|
||||||
|
|
||||||
def test_main():
|
def test_main():
|
||||||
test_support.run_unittest(TraceTestCase)
|
test_support.run_unittest(TraceTestCase)
|
||||||
|
|
|
@ -51,7 +51,7 @@ static int call_trace(Py_tracefunc, PyObject *, PyFrameObject *,
|
||||||
static void call_trace_protected(Py_tracefunc, PyObject *,
|
static void call_trace_protected(Py_tracefunc, PyObject *,
|
||||||
PyFrameObject *, int);
|
PyFrameObject *, int);
|
||||||
static void call_exc_trace(Py_tracefunc, PyObject *, PyFrameObject *);
|
static void call_exc_trace(Py_tracefunc, PyObject *, PyFrameObject *);
|
||||||
static void maybe_call_line_trace(Py_tracefunc, PyObject *,
|
static int maybe_call_line_trace(Py_tracefunc, PyObject *,
|
||||||
PyFrameObject *, int *, int *);
|
PyFrameObject *, int *, int *);
|
||||||
|
|
||||||
static PyObject *apply_slice(PyObject *, PyObject *, PyObject *);
|
static PyObject *apply_slice(PyObject *, PyObject *, PyObject *);
|
||||||
|
@ -726,9 +726,14 @@ eval_frame(PyFrameObject *f)
|
||||||
/* see maybe_call_line_trace
|
/* see maybe_call_line_trace
|
||||||
for expository comments */
|
for expository comments */
|
||||||
f->f_stacktop = stack_pointer;
|
f->f_stacktop = stack_pointer;
|
||||||
maybe_call_line_trace(tstate->c_tracefunc,
|
|
||||||
tstate->c_traceobj,
|
if (maybe_call_line_trace(tstate->c_tracefunc,
|
||||||
f, &instr_lb, &instr_ub);
|
tstate->c_traceobj,
|
||||||
|
f, &instr_lb, &instr_ub)) {
|
||||||
|
/* trace function raised an exception */
|
||||||
|
why = WHY_EXCEPTION;
|
||||||
|
goto on_error;
|
||||||
|
}
|
||||||
/* Reload possibly changed frame fields */
|
/* Reload possibly changed frame fields */
|
||||||
JUMPTO(f->f_lasti);
|
JUMPTO(f->f_lasti);
|
||||||
stack_pointer = f->f_stacktop;
|
stack_pointer = f->f_stacktop;
|
||||||
|
@ -2872,7 +2877,7 @@ call_trace(Py_tracefunc func, PyObject *obj, PyFrameObject *frame,
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static int
|
||||||
maybe_call_line_trace(Py_tracefunc func, PyObject *obj,
|
maybe_call_line_trace(Py_tracefunc func, PyObject *obj,
|
||||||
PyFrameObject *frame, int *instr_lb, int *instr_ub)
|
PyFrameObject *frame, int *instr_lb, int *instr_ub)
|
||||||
{
|
{
|
||||||
|
@ -2947,6 +2952,8 @@ maybe_call_line_trace(Py_tracefunc func, PyObject *obj,
|
||||||
suggested by f_lasti on this one occasion where it's desirable.
|
suggested by f_lasti on this one occasion where it's desirable.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
int result = 0;
|
||||||
|
|
||||||
if ((frame->f_lasti < *instr_lb || frame->f_lasti >= *instr_ub)) {
|
if ((frame->f_lasti < *instr_lb || frame->f_lasti >= *instr_ub)) {
|
||||||
PyCodeObject* co = frame->f_code;
|
PyCodeObject* co = frame->f_code;
|
||||||
int size, addr, line;
|
int size, addr, line;
|
||||||
|
@ -2980,8 +2987,8 @@ maybe_call_line_trace(Py_tracefunc func, PyObject *obj,
|
||||||
|
|
||||||
if (addr == frame->f_lasti) {
|
if (addr == frame->f_lasti) {
|
||||||
frame->f_lineno = line;
|
frame->f_lineno = line;
|
||||||
call_trace(func, obj, frame,
|
result = call_trace(func, obj, frame,
|
||||||
PyTrace_LINE, Py_None);
|
PyTrace_LINE, Py_None);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (size > 0) {
|
if (size > 0) {
|
||||||
|
@ -2996,6 +3003,8 @@ maybe_call_line_trace(Py_tracefunc func, PyObject *obj,
|
||||||
*instr_ub = INT_MAX;
|
*instr_ub = INT_MAX;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
|
Loading…
Reference in New Issue