summaryrefslogtreecommitdiff
path: root/coverage/parser.py
diff options
context:
space:
mode:
authorNed Batchelder <ned@nedbatchelder.com>2022-09-26 19:21:41 -0400
committerNed Batchelder <ned@nedbatchelder.com>2022-09-26 20:27:16 -0400
commitfd36918609a18bd36a7e2c3b208220cf25c0957d (patch)
tree013019b92812c04882d85c83d334ecfae3dd6600 /coverage/parser.py
parent2c4bd7f1f9e8c3c429db2b9cfdc33ba0881f8fde (diff)
downloadpython-coveragepy-git-fd36918609a18bd36a7e2c3b208220cf25c0957d.tar.gz
fix: `class` statements shouldn't be branches. #1449
Revert "refactor: we no longer need to treat 'class' lines specially" This reverts commit 79f9f4575321fafc2ef770e3255f874db3d4b037.
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):