diff options
Diffstat (limited to 'coverage/tracer.c')
-rw-r--r-- | coverage/tracer.c | 59 |
1 files changed, 56 insertions, 3 deletions
diff --git a/coverage/tracer.c b/coverage/tracer.c index 3131d7df..cb242219 100644 --- a/coverage/tracer.c +++ b/coverage/tracer.c @@ -83,6 +83,7 @@ typedef struct { PyObject * warn; PyObject * coroutine_id_func; PyObject * data; + PyObject * plugin_data; PyObject * should_trace_cache; PyObject * arcs; @@ -192,6 +193,7 @@ CTracer_init(CTracer *self, PyObject *args_unused, PyObject *kwds_unused) self->warn = NULL; self->coroutine_id_func = NULL; self->data = NULL; + self->plugin_data = NULL; self->should_trace_cache = NULL; self->arcs = NULL; @@ -232,6 +234,7 @@ CTracer_dealloc(CTracer *self) Py_XDECREF(self->warn); Py_XDECREF(self->coroutine_id_func); Py_XDECREF(self->data); + Py_XDECREF(self->plugin_data); Py_XDECREF(self->should_trace_cache); DataStack_dealloc(self, &self->data_stack); @@ -385,6 +388,7 @@ CTracer_trace(CTracer *self, PyFrameObject *frame, int what, PyObject *arg_unuse PyObject * filename = NULL; PyObject * tracename = NULL; PyObject * disposition = NULL; + PyObject * disp_trace = NULL; #if WHAT_LOG || TRACE_LOG PyObject * ascii = NULL; #endif @@ -475,15 +479,33 @@ CTracer_trace(CTracer *self, PyFrameObject *frame, int what, PyObject *arg_unuse Py_INCREF(disposition); } - /* If tracename is a string, then we're supposed to trace. */ - tracename = PyObject_GetAttrString(disposition, "filename"); - if (tracename == NULL) { + disp_trace = PyObject_GetAttrString(disposition, "trace"); + if (disp_trace == NULL) { STATS( self->stats.errors++; ) Py_DECREF(disposition); return RET_ERROR; } + + tracename = Py_None; + Py_INCREF(tracename); + + if (disp_trace == Py_True) { + /* If tracename is a string, then we're supposed to trace. */ + tracename = PyObject_GetAttrString(disposition, "source_filename"); + if (tracename == NULL) { + STATS( self->stats.errors++; ) + Py_DECREF(disposition); + Py_DECREF(disp_trace); + return RET_ERROR; + } + } + Py_DECREF(disp_trace); + if (MyText_Check(tracename)) { PyObject * file_data = PyDict_GetItem(self->data, tracename); + PyObject * disp_plugin = NULL; + PyObject * disp_plugin_name = NULL; + if (file_data == NULL) { file_data = PyDict_New(); if (file_data == NULL) { @@ -500,6 +522,34 @@ CTracer_trace(CTracer *self, PyFrameObject *frame, int what, PyObject *arg_unuse Py_DECREF(disposition); return RET_ERROR; } + + if (self->plugin_data != NULL) { + /* If the disposition mentions a plugin, record that. */ + disp_plugin = PyObject_GetAttrString(disposition, "plugin"); + if (disp_plugin == NULL) { + STATS( self->stats.errors++; ) + Py_DECREF(tracename); + Py_DECREF(disposition); + return RET_ERROR; + } + if (disp_plugin != Py_None) { + disp_plugin_name = PyObject_GetAttrString(disp_plugin, "__name__"); + Py_DECREF(disp_plugin); + if (disp_plugin_name == NULL) { + STATS( self->stats.errors++; ) + Py_DECREF(tracename); + Py_DECREF(disposition); + return RET_ERROR; + } + ret = PyDict_SetItem(self->plugin_data, tracename, disp_plugin_name); + Py_DECREF(disp_plugin_name); + if (ret < 0) { + Py_DECREF(tracename); + Py_DECREF(disposition); + return RET_ERROR; + } + } + } } self->cur_entry.file_data = file_data; /* Make the frame right in case settrace(gettrace()) happens. */ @@ -735,6 +785,9 @@ CTracer_members[] = { { "data", T_OBJECT, offsetof(CTracer, data), 0, PyDoc_STR("The raw dictionary of trace data.") }, + { "plugin_data", T_OBJECT, offsetof(CTracer, plugin_data), 0, + PyDoc_STR("Mapping from filename to plugin name.") }, + { "should_trace_cache", T_OBJECT, offsetof(CTracer, should_trace_cache), 0, PyDoc_STR("Dictionary caching should_trace results.") }, |