summaryrefslogtreecommitdiff
path: root/coverage/tracer.c
diff options
context:
space:
mode:
authorNed Batchelder <ned@nedbatchelder.com>2011-04-25 21:29:20 -0400
committerNed Batchelder <ned@nedbatchelder.com>2011-04-25 21:29:20 -0400
commit689679aa144314c9ac0dc4a48d336889992de1a5 (patch)
tree2b2ab0c39b99eac5d9546be5abf67bc175d17ec1 /coverage/tracer.c
parent4adf9b46ce958c33aaede3bb1b9521cea6b1eb53 (diff)
downloadpython-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.c31
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 */
+