Skip to content

Commit 8021196

Browse files
committed
refactor: no need for specialized pyexpat code anymore
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.
1 parent 50a0e37 commit 8021196

File tree

5 files changed

+0
-106
lines changed

5 files changed

+0
-106
lines changed

coverage/ctracer/stats.h

-2
Original file line numberDiff line numberDiff line change
@@ -17,10 +17,8 @@ typedef struct Stats {
1717
#if COLLECT_STATS
1818
unsigned int lines;
1919
unsigned int returns;
20-
unsigned int exceptions;
2120
unsigned int others;
2221
unsigned int files;
23-
unsigned int missed_returns;
2422
unsigned int stack_reallocs;
2523
unsigned int errors;
2624
unsigned int pycalls;

coverage/ctracer/tracer.c

-79
Original file line numberDiff line numberDiff line change
@@ -295,48 +295,6 @@ CTracer_set_pdata_stack(CTracer *self)
295295
* Parts of the trace function.
296296
*/
297297

298-
static int
299-
CTracer_check_missing_return(CTracer *self, PyFrameObject *frame)
300-
{
301-
int ret = RET_ERROR;
302-
303-
if (self->last_exc_back) {
304-
if (frame == self->last_exc_back) {
305-
/* Looks like someone forgot to send a return event. We'll clear
306-
the exception state and do the RETURN code here. Notice that the
307-
frame we have in hand here is not the correct frame for the RETURN,
308-
that frame is gone. Our handling for RETURN doesn't need the
309-
actual frame, but we do log it, so that will look a little off if
310-
you're looking at the detailed log.
311-
312-
If someday we need to examine the frame when doing RETURN, then
313-
we'll need to keep more of the missed frame's state.
314-
*/
315-
STATS( self->stats.missed_returns++; )
316-
if (CTracer_set_pdata_stack(self) < 0) {
317-
goto error;
318-
}
319-
if (self->pdata_stack->depth >= 0) {
320-
if (self->tracing_arcs && self->pcur_entry->file_data) {
321-
if (CTracer_record_pair(self, self->pcur_entry->last_line, -self->last_exc_firstlineno) < 0) {
322-
goto error;
323-
}
324-
}
325-
SHOWLOG(PyFrame_GetLineNumber(frame), MyFrame_GetCode(frame)->co_filename, "missedreturn");
326-
self->pdata_stack->depth--;
327-
self->pcur_entry = &self->pdata_stack->stack[self->pdata_stack->depth];
328-
}
329-
}
330-
self->last_exc_back = NULL;
331-
}
332-
333-
ret = RET_OK;
334-
335-
error:
336-
337-
return ret;
338-
}
339-
340298
static int
341299
CTracer_handle_call(CTracer *self, PyFrameObject *frame)
342300
{
@@ -773,30 +731,6 @@ CTracer_handle_return(CTracer *self, PyFrameObject *frame)
773731
return ret;
774732
}
775733

776-
static int
777-
CTracer_handle_exception(CTracer *self, PyFrameObject *frame)
778-
{
779-
/* Some code (Python 2.3, and pyexpat anywhere) fires an exception event
780-
without a return event. To detect that, we'll keep a copy of the
781-
parent frame for an exception event. If the next event is in that
782-
frame, then we must have returned without a return event. We can
783-
synthesize the missing event then.
784-
785-
Python itself fixed this problem in 2.4. Pyexpat still has the bug.
786-
I've reported the problem with pyexpat as http://bugs.python.org/issue6359 .
787-
If it gets fixed, this code should still work properly. Maybe some day
788-
the bug will be fixed everywhere coverage.py is supported, and we can
789-
remove this missing-return detection.
790-
791-
More about this fix: https://nedbatchelder.com/blog/200907/a_nasty_little_bug.html
792-
*/
793-
STATS( self->stats.exceptions++; )
794-
self->last_exc_back = frame->f_back;
795-
self->last_exc_firstlineno = MyFrame_GetCode(frame)->co_firstlineno;
796-
797-
return RET_OK;
798-
}
799-
800734
/*
801735
* The Trace Function
802736
*/
@@ -837,11 +771,6 @@ CTracer_trace(CTracer *self, PyFrameObject *frame, int what, PyObject *arg_unuse
837771
Py_DECREF(ascii);
838772
#endif
839773

840-
/* See below for details on missing-return detection. */
841-
if (CTracer_check_missing_return(self, frame) < 0) {
842-
goto error;
843-
}
844-
845774
self->activity = TRUE;
846775

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

866-
case PyTrace_EXCEPTION:
867-
if (CTracer_handle_exception(self, frame) < 0) {
868-
goto error;
869-
}
870-
break;
871-
872795
default:
873796
STATS( self->stats.others++; )
874797
break;
@@ -1050,10 +973,8 @@ CTracer_get_stats(CTracer *self, PyObject *args_unused)
1050973
"calls", self->stats.calls,
1051974
"lines", self->stats.lines,
1052975
"returns", self->stats.returns,
1053-
"exceptions", self->stats.exceptions,
1054976
"others", self->stats.others,
1055977
"files", self->stats.files,
1056-
"missed_returns", self->stats.missed_returns,
1057978
"stack_reallocs", self->stats.stack_reallocs,
1058979
"stack_alloc", self->pdata_stack->alloc,
1059980
"errors", self->stats.errors,

coverage/ctracer/tracer.h

-4
Original file line numberDiff line numberDiff line change
@@ -60,10 +60,6 @@ typedef struct CTracer {
6060
/* The current file's data stack entry. */
6161
DataStackEntry * pcur_entry;
6262

63-
/* The parent frame for the last exception event, to fix missing returns. */
64-
PyFrameObject * last_exc_back;
65-
int last_exc_firstlineno;
66-
6763
Stats stats;
6864
} CTracer;
6965

coverage/inorout.py

-5
Original file line numberDiff line numberDiff line change
@@ -349,11 +349,6 @@ def nope(disp, reason):
349349
# can't do anything with the data later anyway.
350350
return nope(disp, "not a real file name")
351351

352-
# pyexpat does a dumb thing, calling the trace function explicitly from
353-
# C code with a C file name.
354-
if re.search(r"[/\\]Modules[/\\]pyexpat.c", filename):
355-
return nope(disp, "pyexpat lies about itself")
356-
357352
# Jython reports the .class file to the tracer, use the source file.
358353
if filename.endswith("$py.class"):
359354
filename = filename[:-9] + ".py"

coverage/pytracer.py

-16
Original file line numberDiff line numberDiff line change
@@ -55,8 +55,6 @@ def __init__(self):
5555
self.started_context = False
5656

5757
self.data_stack = []
58-
self.last_exc_back = None
59-
self.last_exc_firstlineno = 0
6058
self.thread = None
6159
self.stopped = False
6260
self._activity = False
@@ -118,17 +116,6 @@ def _trace(self, frame, event, arg_unused):
118116
)
119117
return None
120118

121-
if self.last_exc_back:
122-
if frame == self.last_exc_back:
123-
# Someone forgot a return event.
124-
if self.trace_arcs and self.cur_file_data:
125-
pair = (self.last_line, -self.last_exc_firstlineno)
126-
self.cur_file_data.add(pair)
127-
self.cur_file_data, self.cur_file_name, self.last_line, self.started_context = (
128-
self.data_stack.pop()
129-
)
130-
self.last_exc_back = None
131-
132119
# if event != 'call' and frame.f_code.co_filename != self.cur_file_name:
133120
# self.log("---\n*", frame.f_code.co_filename, self.cur_file_name, frame.f_lineno)
134121

@@ -204,9 +191,6 @@ def _trace(self, frame, event, arg_unused):
204191
if self.started_context:
205192
self.context = None
206193
self.switch_context(None)
207-
elif event == 'exception':
208-
self.last_exc_back = frame.f_back
209-
self.last_exc_firstlineno = frame.f_code.co_firstlineno
210194
return self._trace
211195

212196
def start(self):

0 commit comments

Comments
 (0)