summaryrefslogtreecommitdiff
path: root/coverage/parser.py
diff options
context:
space:
mode:
Diffstat (limited to 'coverage/parser.py')
-rw-r--r--coverage/parser.py15
1 files changed, 15 insertions, 0 deletions
diff --git a/coverage/parser.py b/coverage/parser.py
index 3dbfbf30..8b2a9ac5 100644
--- a/coverage/parser.py
+++ b/coverage/parser.py
@@ -67,6 +67,9 @@ class PythonParser:
# The raw line numbers of excluded lines of code, as marked by pragmas.
self.raw_excluded = set()
+ # The line numbers of class definitions.
+ self.raw_classdefs = set()
+
# The line numbers of docstring lines.
self.raw_docstrings = set()
@@ -130,6 +133,12 @@ class PythonParser:
indent += 1
elif toktype == token.DEDENT:
indent -= 1
+ elif toktype == token.NAME:
+ if ttext == 'class':
+ # Class definitions look like branches in the bytecode, so
+ # we need to exclude them. The simplest way is to note the
+ # lines with the 'class' keyword.
+ self.raw_classdefs.add(slineno)
elif toktype == token.OP:
if ttext == ':' and nesting == 0:
should_exclude = (elineno in self.raw_excluded) or excluding_decorators
@@ -292,6 +301,12 @@ class PythonParser:
continue
exit_counts[l1] += 1
+ # Class definitions have one extra exit, so remove one for each:
+ for l in self.raw_classdefs:
+ # Ensure key is there: class definitions can include excluded lines.
+ if l in exit_counts:
+ exit_counts[l] -= 1
+
return exit_counts
def missing_arc_description(self, start, end, executed_arcs=None):