Commit 17e63f6a authored by Dmitry Trofimov's avatar Dmitry Trofimov

Fix tests after handling the case when tracing function returns None

parent dfc47cd4
......@@ -198,7 +198,8 @@
PyThreadState *tstate; \
PyGILState_STATE state = PyGILState_Ensure(); \
tstate = PyThreadState_GET(); \
if (unlikely(tstate->use_tracing && __pyx_frame->f_trace != Py_None)) { \
if (unlikely(tstate->use_tracing && tstate->c_tracefunc \
&& __pyx_frame->f_trace != Py_None)) { \
ret = __Pyx_call_line_trace_func(tstate, $frame_cname, lineno); \
} \
PyGILState_Release(state); \
......@@ -206,7 +207,8 @@
} \
} else { \
PyThreadState* tstate = PyThreadState_GET(); \
if (unlikely(tstate->use_tracing && __pyx_frame->f_trace != Py_None)) { \
if (unlikely(tstate->use_tracing && tstate->c_tracefunc \
&& __pyx_frame->f_trace != Py_None)) { \
int ret = __Pyx_call_line_trace_func(tstate, $frame_cname, lineno); \
if (unlikely(ret)) goto_error; \
} \
......@@ -216,7 +218,8 @@
#define __Pyx_TraceLine(lineno, nogil, goto_error) \
if (likely(!__Pyx_use_tracing)); else { \
PyThreadState* tstate = PyThreadState_GET(); \
if (unlikely(tstate->use_tracing && __pyx_frame->f_trace != Py_None)) { \
if (unlikely(tstate->use_tracing && tstate->c_tracefunc \
&& __pyx_frame->f_trace != Py_None)) { \
int ret = __Pyx_call_line_trace_func(tstate, $frame_cname, lineno); \
if (unlikely(ret)) goto_error; \
} \
......
......@@ -30,25 +30,62 @@ map_trace_types = {
}.get
cdef int _trace_func(PyObject* _traceobj, PyFrameObject* _frame, int what, PyObject* arg) except -1:
frame, traceobj = <object>_frame, <object>_traceobj
traceobj.append((map_trace_types(what), frame.f_lineno - frame.f_code.co_firstlineno))
return 0
cdef int trace_trampoline(PyObject* _traceobj, PyFrameObject* _frame, int what, PyObject* _arg) except -1:
frame = <object>_frame
traceobj = <object>_traceobj if _traceobj else None
arg = <object>_arg if _arg else None
cdef int _failing_call_trace_func(PyObject* _traceobj, PyFrameObject* _frame, int what, PyObject* arg) except -1:
if what == PyTrace_CALL:
raise ValueError("failing call trace!")
return _trace_func(_traceobj, _frame, what, arg)
callback = traceobj
else:
callback = frame.f_trace
if callback is None:
return 0
result = callback(frame, what, arg)
frame.f_trace = result
if result is None:
PyEval_SetTrace(NULL, None)
return -1
else:
return 0
def _create_trace_func(trace):
def _trace_func(frame, event, arg):
trace.append((map_trace_types(event), frame.f_lineno -
frame.f_code.co_firstlineno))
return _trace_func
return _trace_func
def _create_failing_call_trace_func(trace):
func = _create_trace_func(trace)
def _trace_func(frame, event, arg):
if event == PyTrace_CALL:
raise ValueError("failing call trace!")
func(frame, event, arg)
return _trace_func
return _trace_func
def _create__failing_line_trace_func(trace):
func = _create_trace_func(trace)
def _trace_func(frame, event, arg):
if event == PyTrace_LINE and trace:
if trace and trace[0] == frame.f_code.co_name:
# first line in the right function => fail!
raise ValueError("failing line trace!")
cdef int _failing_line_trace_func(PyObject* _traceobj, PyFrameObject* _frame, int what, PyObject* arg) except -1:
if what == PyTrace_LINE and _traceobj:
frame, traceobj = <object>_frame, <object>_traceobj
if traceobj and traceobj[0] == frame.f_code.co_name:
# first line in the right function => fail!
raise ValueError("failing line trace!")
return _trace_func(_traceobj, _frame, what, arg)
func(frame, event, arg)
return _trace_func
return _trace_func
def cy_add(a,b):
......@@ -87,7 +124,7 @@ def run_trace(func, *args):
[('line', 2), ('line', 5), ('return', 5)]
"""
trace = []
PyEval_SetTrace(<Py_tracefunc>_trace_func, trace)
PyEval_SetTrace(<Py_tracefunc>trace_trampoline, _create_trace_func(trace))
try:
func(*args)
finally:
......@@ -105,7 +142,7 @@ def fail_on_call_trace(func, *args):
ValueError: failing call trace!
"""
trace = []
PyEval_SetTrace(<Py_tracefunc>_failing_call_trace_func, trace)
PyEval_SetTrace(<Py_tracefunc>trace_trampoline, _create_failing_call_trace_func(trace))
try:
func(*args)
finally:
......@@ -142,7 +179,7 @@ def fail_on_line_trace(fail_func):
cdef int x = 1
trace = ['NO ERROR']
exception = None
PyEval_SetTrace(<Py_tracefunc>_failing_line_trace_func, trace)
PyEval_SetTrace(<Py_tracefunc>trace_trampoline, _create__failing_line_trace_func(trace))
try:
x += 1
cy_add(1, 2)
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment