diff options
author | Ned Batchelder <ned@nedbatchelder.com> | 2011-04-25 21:29:20 -0400 |
---|---|---|
committer | Ned Batchelder <ned@nedbatchelder.com> | 2011-04-25 21:29:20 -0400 |
commit | 689679aa144314c9ac0dc4a48d336889992de1a5 (patch) | |
tree | 2b2ab0c39b99eac5d9546be5abf67bc175d17ec1 /coverage/tracer.c | |
parent | 4adf9b46ce958c33aaede3bb1b9521cea6b1eb53 (diff) | |
download | python-coveragepy-git-689679aa144314c9ac0dc4a48d336889992de1a5.tar.gz |
A fix for bug #123, but it doesn't restore tracing properly yet, still want to get to the bottom of that.
--HG--
branch : bug_123
Diffstat (limited to 'coverage/tracer.c')
-rw-r--r-- | coverage/tracer.c | 31 |
1 files changed, 27 insertions, 4 deletions
diff --git a/coverage/tracer.c b/coverage/tracer.c index e046596a..2faabb62 100644 --- a/coverage/tracer.c +++ b/coverage/tracer.c @@ -462,7 +462,7 @@ Tracer_pytrace(Tracer *self, PyObject *args) { PyFrameObject *frame; PyObject *what_str; - PyObject *arg_unused; + PyObject *arg; int what; static char *what_names[] = { "call", "exception", "line", "return", @@ -470,8 +470,12 @@ Tracer_pytrace(Tracer *self, PyObject *args) NULL }; + #if WHAT_LOG + printf("pytrace\n"); + #endif + if (!PyArg_ParseTuple(args, "O!O!O:Tracer_pytrace", - &PyFrame_Type, &frame, &MyText_Type, &what_str, &arg_unused)) { + &PyFrame_Type, &frame, &MyText_Type, &what_str, &arg)) { goto done; } @@ -484,7 +488,7 @@ Tracer_pytrace(Tracer *self, PyObject *args) } /* Invoke the C function, and return ourselves. */ - if (Tracer_trace(self, frame, what, arg_unused) == RET_OK) { + if (Tracer_trace(self, frame, what, arg) == RET_OK) { return PyObject_GetAttrString((PyObject*)self, "pytrace"); } @@ -492,6 +496,24 @@ done: return NULL; } +/* + * Python has two ways to set the trace function: sys.settrace(fn), which + * takes a Python callable, and PyEval_SetTrace(func, obj), which takes + * a C function and a Python object. The way these work together is that + * sys.settrace(pyfn) calls PyEval_SetTrace(builtin_func, pyfn), using the + * Python callable as the object in PyEval_SetTrace. So sys.gettrace() + * simply returns the Python object used as the second argument to + * PyEval_SetTrace. So sys.gettrace() will return our self parameter, which + * means it must be callable to be used in sys.settrace(). + * + * So we make our self callable, equivalent to invoking our trace function. + */ +static PyObject * +Tracer_call(Tracer *self, PyObject *args, PyObject *kwds_unused) +{ + return Tracer_pytrace(self, args); +} + static PyObject * Tracer_start(Tracer *self, PyObject *args_unused) { @@ -590,7 +612,7 @@ TracerType = { 0, /*tp_as_sequence*/ 0, /*tp_as_mapping*/ 0, /*tp_hash */ - 0, /*tp_call*/ + (ternaryfunc)Tracer_call, /*tp_call*/ 0, /*tp_str*/ 0, /*tp_getattro*/ 0, /*tp_setattro*/ @@ -678,3 +700,4 @@ inittracer(void) } #endif /* Py3k */ + |