Skip to content

Commit

Permalink
refactor: no need for specialized pyexpat code anymore
Browse files Browse the repository at this point in the history
The pyexpat bug that plagued us was fixed in Python 3.4:
https://bugs.python.org/issue22462

We no longer need the code that adapted to it.  The test will remain, couldn't
hurt.
  • Loading branch information
nedbat committed Oct 18, 2021
1 parent 50a0e37 commit 8021196
Show file tree
Hide file tree
Showing 5 changed files with 0 additions and 106 deletions.
2 changes: 0 additions & 2 deletions coverage/ctracer/stats.h
Original file line number Diff line number Diff line change
Expand Up @@ -17,10 +17,8 @@ typedef struct Stats {
#if COLLECT_STATS
unsigned int lines;
unsigned int returns;
unsigned int exceptions;
unsigned int others;
unsigned int files;
unsigned int missed_returns;
unsigned int stack_reallocs;
unsigned int errors;
unsigned int pycalls;
Expand Down
79 changes: 0 additions & 79 deletions coverage/ctracer/tracer.c
Original file line number Diff line number Diff line change
Expand Up @@ -295,48 +295,6 @@ CTracer_set_pdata_stack(CTracer *self)
* Parts of the trace function.
*/

static int
CTracer_check_missing_return(CTracer *self, PyFrameObject *frame)
{
int ret = RET_ERROR;

if (self->last_exc_back) {
if (frame == self->last_exc_back) {
/* Looks like someone forgot to send a return event. We'll clear
the exception state and do the RETURN code here. Notice that the
frame we have in hand here is not the correct frame for the RETURN,
that frame is gone. Our handling for RETURN doesn't need the
actual frame, but we do log it, so that will look a little off if
you're looking at the detailed log.
If someday we need to examine the frame when doing RETURN, then
we'll need to keep more of the missed frame's state.
*/
STATS( self->stats.missed_returns++; )
if (CTracer_set_pdata_stack(self) < 0) {
goto error;
}
if (self->pdata_stack->depth >= 0) {
if (self->tracing_arcs && self->pcur_entry->file_data) {
if (CTracer_record_pair(self, self->pcur_entry->last_line, -self->last_exc_firstlineno) < 0) {
goto error;
}
}
SHOWLOG(PyFrame_GetLineNumber(frame), MyFrame_GetCode(frame)->co_filename, "missedreturn");
self->pdata_stack->depth--;
self->pcur_entry = &self->pdata_stack->stack[self->pdata_stack->depth];
}
}
self->last_exc_back = NULL;
}

ret = RET_OK;

error:

return ret;
}

static int
CTracer_handle_call(CTracer *self, PyFrameObject *frame)
{
Expand Down Expand Up @@ -773,30 +731,6 @@ CTracer_handle_return(CTracer *self, PyFrameObject *frame)
return ret;
}

static int
CTracer_handle_exception(CTracer *self, PyFrameObject *frame)
{
/* Some code (Python 2.3, and pyexpat anywhere) fires an exception event
without a return event. To detect that, we'll keep a copy of the
parent frame for an exception event. If the next event is in that
frame, then we must have returned without a return event. We can
synthesize the missing event then.
Python itself fixed this problem in 2.4. Pyexpat still has the bug.
I've reported the problem with pyexpat as http://bugs.python.org/issue6359 .
If it gets fixed, this code should still work properly. Maybe some day
the bug will be fixed everywhere coverage.py is supported, and we can
remove this missing-return detection.
More about this fix: https://nedbatchelder.com/blog/200907/a_nasty_little_bug.html
*/
STATS( self->stats.exceptions++; )
self->last_exc_back = frame->f_back;
self->last_exc_firstlineno = MyFrame_GetCode(frame)->co_firstlineno;

return RET_OK;
}

/*
* The Trace Function
*/
Expand Down Expand Up @@ -837,11 +771,6 @@ CTracer_trace(CTracer *self, PyFrameObject *frame, int what, PyObject *arg_unuse
Py_DECREF(ascii);
#endif

/* See below for details on missing-return detection. */
if (CTracer_check_missing_return(self, frame) < 0) {
goto error;
}

self->activity = TRUE;

switch (what) {
Expand All @@ -863,12 +792,6 @@ CTracer_trace(CTracer *self, PyFrameObject *frame, int what, PyObject *arg_unuse
}
break;

case PyTrace_EXCEPTION:
if (CTracer_handle_exception(self, frame) < 0) {
goto error;
}
break;

default:
STATS( self->stats.others++; )
break;
Expand Down Expand Up @@ -1050,10 +973,8 @@ CTracer_get_stats(CTracer *self, PyObject *args_unused)
"calls", self->stats.calls,
"lines", self->stats.lines,
"returns", self->stats.returns,
"exceptions", self->stats.exceptions,
"others", self->stats.others,
"files", self->stats.files,
"missed_returns", self->stats.missed_returns,
"stack_reallocs", self->stats.stack_reallocs,
"stack_alloc", self->pdata_stack->alloc,
"errors", self->stats.errors,
Expand Down
4 changes: 0 additions & 4 deletions coverage/ctracer/tracer.h
Original file line number Diff line number Diff line change
Expand Up @@ -60,10 +60,6 @@ typedef struct CTracer {
/* The current file's data stack entry. */
DataStackEntry * pcur_entry;

/* The parent frame for the last exception event, to fix missing returns. */
PyFrameObject * last_exc_back;
int last_exc_firstlineno;

Stats stats;
} CTracer;

Expand Down
5 changes: 0 additions & 5 deletions coverage/inorout.py
Original file line number Diff line number Diff line change
Expand Up @@ -349,11 +349,6 @@ def nope(disp, reason):
# can't do anything with the data later anyway.
return nope(disp, "not a real file name")

# pyexpat does a dumb thing, calling the trace function explicitly from
# C code with a C file name.
if re.search(r"[/\\]Modules[/\\]pyexpat.c", filename):
return nope(disp, "pyexpat lies about itself")

# Jython reports the .class file to the tracer, use the source file.
if filename.endswith("$py.class"):
filename = filename[:-9] + ".py"
Expand Down
16 changes: 0 additions & 16 deletions coverage/pytracer.py
Original file line number Diff line number Diff line change
Expand Up @@ -55,8 +55,6 @@ def __init__(self):
self.started_context = False

self.data_stack = []
self.last_exc_back = None
self.last_exc_firstlineno = 0
self.thread = None
self.stopped = False
self._activity = False
Expand Down Expand Up @@ -118,17 +116,6 @@ def _trace(self, frame, event, arg_unused):
)
return None

if self.last_exc_back:
if frame == self.last_exc_back:
# Someone forgot a return event.
if self.trace_arcs and self.cur_file_data:
pair = (self.last_line, -self.last_exc_firstlineno)
self.cur_file_data.add(pair)
self.cur_file_data, self.cur_file_name, self.last_line, self.started_context = (
self.data_stack.pop()
)
self.last_exc_back = None

# if event != 'call' and frame.f_code.co_filename != self.cur_file_name:
# self.log("---\n*", frame.f_code.co_filename, self.cur_file_name, frame.f_lineno)

Expand Down Expand Up @@ -204,9 +191,6 @@ def _trace(self, frame, event, arg_unused):
if self.started_context:
self.context = None
self.switch_context(None)
elif event == 'exception':
self.last_exc_back = frame.f_back
self.last_exc_firstlineno = frame.f_code.co_firstlineno
return self._trace

def start(self):
Expand Down

0 comments on commit 8021196

Please sign in to comment.