From bba62f9097ac116edb30a10ca15ee25bc7da62d9 Mon Sep 17 00:00:00 2001 From: Ned Batchelder Date: Sat, 10 Oct 2009 15:36:31 -0400 Subject: Properly separate the line data and the arc data. --- coverage/collector.py | 33 +++++++++++++++++++-------------- coverage/control.py | 2 +- coverage/tracer.c | 16 +++++++++++----- 3 files changed, 31 insertions(+), 20 deletions(-) diff --git a/coverage/collector.py b/coverage/collector.py index 87441ff..7c6c27c 100644 --- a/coverage/collector.py +++ b/coverage/collector.py @@ -29,7 +29,7 @@ class PyTracer: # used to force the use of this tracer. def __init__(self): - self.data = None + self.line_data = None self.should_trace = None self.should_trace_cache = None self.cur_filename = None @@ -59,7 +59,7 @@ class PyTracer: elif event == 'line': # Record an executed line. if self.cur_filename: - self.data[(self.cur_filename, frame.f_lineno)] = True + self.line_data[(self.cur_filename, frame.f_lineno)] = True elif event == 'return': # Leaving this function, pop the filename stack. self.cur_filename = self.filename_stack.pop() @@ -97,7 +97,8 @@ class PyBranchTracer: # used to force the use of this tracer. def __init__(self): - self.data = None + self.line_data = None + self.arc_data = None self.should_trace = None self.should_trace_cache = None self.cur_filename = None @@ -116,7 +117,7 @@ class PyBranchTracer: if frame == self.last_exc_back: # Someone forgot a return event. if self.cur_filename: - self.data['arcs'][(self.cur_filename, self.last_line, 0)] = True + self.arc_data[(self.cur_filename, self.last_line, 0)] = True self.cur_filename, self.last_line = self.filename_stack.pop() self.last_exc_back = None @@ -131,12 +132,12 @@ class PyBranchTracer: elif event == 'line': # Record an executed line. if self.cur_filename: - self.data[(self.cur_filename, frame.f_lineno)] = True - self.data['arcs'][(self.cur_filename, self.last_line, frame.f_lineno)] = True + self.line_data[(self.cur_filename, frame.f_lineno)] = True + self.arc_data[(self.cur_filename, self.last_line, frame.f_lineno)] = True self.last_line = frame.f_lineno elif event == 'return': if self.cur_filename: - self.data['arcs'][(self.cur_filename, self.last_line, 0)] = True + self.arc_data[(self.cur_filename, self.last_line, 0)] = True # Leaving this function, pop the filename stack. self.cur_filename, self.last_line = self.filename_stack.pop() elif event == 'exception': @@ -146,7 +147,6 @@ class PyBranchTracer: def start(self): """Start this Tracer.""" assert self.branch - self.data['arcs'] = {} sys.settrace(self._trace) def stop(self): @@ -210,7 +210,10 @@ class Collector: """Clear collected data, and prepare to collect more.""" # A dictionary with an entry for (Python source file name, line number # in that file) if that line has been executed. - self.data = {} + self.line_data = {} + + # TODO + self.arc_data = {} # A cache of the results from should_trace, the decision about whether # to trace execution in a file. A dict of filename to (filename or @@ -223,7 +226,8 @@ class Collector: def _start_tracer(self): """Start a new Tracer object, and store it in self.tracers.""" tracer = self._trace_class() - tracer.data = self.data + tracer.line_data = self.line_data + tracer.arc_data = self.arc_data tracer.should_trace = self.should_trace tracer.should_trace_cache = self.should_trace_cache tracer.branch = self.branch @@ -282,9 +286,10 @@ class Collector: tracer.start() threading.settrace(self._installation_trace) - def data_points(self): + def get_data(self, kind): """Return the (filename, lineno) pairs collected.""" - if 'arcs' in self.data: + if self.arc_data: import pprint - pprint.pprint(self.data['arcs']) - return self.data.keys() + pprint.pprint(self.arc_data) + if kind == 'line': + return self.line_data.keys() diff --git a/coverage/control.py b/coverage/control.py index 8f54a64..aa1727f 100644 --- a/coverage/control.py +++ b/coverage/control.py @@ -215,7 +215,7 @@ class coverage: def _harvest_data(self): """Get the collected data by filename and reset the collector.""" - self.data.add_line_data(self.collector.data_points()) + self.data.add_line_data(self.collector.get_data('line')) self.collector.reset() # Backward compatibility with version 1. diff --git a/coverage/tracer.c b/coverage/tracer.c index c318e9e..98f10d1 100644 --- a/coverage/tracer.c +++ b/coverage/tracer.c @@ -39,7 +39,8 @@ typedef struct { PyObject_HEAD PyObject * should_trace; - PyObject * data; + PyObject * line_data; + PyObject * arc_data; PyObject * should_trace_cache; PyObject * branch; int started; @@ -59,7 +60,8 @@ static int Tracer_init(Tracer *self, PyObject *args, PyObject *kwds) { self->should_trace = NULL; - self->data = NULL; + self->line_data = NULL; + self->arc_data = NULL; self->should_trace_cache = NULL; self->started = 0; self->depth = -1; @@ -80,7 +82,8 @@ Tracer_dealloc(Tracer *self) } Py_XDECREF(self->should_trace); - Py_XDECREF(self->data); + Py_XDECREF(self->line_data); + Py_XDECREF(self->arc_data); Py_XDECREF(self->should_trace_cache); while (self->depth >= 0) { @@ -245,7 +248,7 @@ Tracer_trace(Tracer *self, PyFrameObject *frame, int what, PyObject *arg) Py_INCREF(tracename); PyTuple_SET_ITEM(t, 0, tracename); PyTuple_SET_ITEM(t, 1, MyInt_FromLong(frame->f_lineno)); - PyDict_SetItem(self->data, t, Py_None); + PyDict_SetItem(self->line_data, t, Py_None); Py_DECREF(t); } } @@ -296,7 +299,10 @@ Tracer_members[] = { { "should_trace", T_OBJECT, offsetof(Tracer, should_trace), 0, PyDoc_STR("Function indicating whether to trace a file.") }, - { "data", T_OBJECT, offsetof(Tracer, data), 0, + { "line_data", T_OBJECT, offsetof(Tracer, line_data), 0, + PyDoc_STR("The raw dictionary of trace data.") }, + + { "arc_data", T_OBJECT, offsetof(Tracer, arc_data), 0, PyDoc_STR("The raw dictionary of trace data.") }, { "should_trace_cache", T_OBJECT, offsetof(Tracer, should_trace_cache), 0, -- cgit v1.2.1