summaryrefslogtreecommitdiff
path: root/coverage/parser.py
diff options
context:
space:
mode:
authorNed Batchelder <ned@nedbatchelder.com>2016-03-27 13:44:49 -0400
committerNed Batchelder <ned@nedbatchelder.com>2016-03-27 13:44:49 -0400
commit3e03a20a7a95aa9b5bd9d11b643489e22682832f (patch)
treed5e1be7e12977174fdfed3e5ed78b87b81eee406 /coverage/parser.py
parent531323862667b0764b09d33efbd803cffc4e238c (diff)
downloadpython-coveragepy-git-3e03a20a7a95aa9b5bd9d11b643489e22682832f.tar.gz
Better descriptions of missing one-line executables. Part of #475
Diffstat (limited to 'coverage/parser.py')
-rw-r--r--coverage/parser.py28
1 files changed, 22 insertions, 6 deletions
diff --git a/coverage/parser.py b/coverage/parser.py
index f4dd02d4..8fb5d89b 100644
--- a/coverage/parser.py
+++ b/coverage/parser.py
@@ -21,8 +21,12 @@ from coverage.phystokens import compile_unicode, generate_tokens, neuter_encodin
class PythonParser(object):
- """Parse code to find executable lines, excluded lines, etc."""
+ """Parse code to find executable lines, excluded lines, etc.
+ This information is all based on static analysis: no code execution is
+ involved.
+
+ """
@contract(text='unicode|None')
def __init__(self, text=None, filename=None, exclude=None):
"""
@@ -304,11 +308,23 @@ class PythonParser(object):
return exit_counts
- def missing_arc_description(self, start, end):
+ def missing_arc_description(self, start, end, executed_arcs=None):
"""Provide an English sentence describing a missing arc."""
if self._missing_arc_fragments is None:
self._analyze_ast()
+ actual_start = start
+
+ if (
+ executed_arcs and
+ end < 0 and end == -start and
+ (end, start) not in executed_arcs and
+ (end, start) in self._missing_arc_fragments
+ ):
+ # It's a one-line callable, and we never even started it,
+ # and we have a message about not starting it.
+ start, end = end, start
+
fragment_pairs = self._missing_arc_fragments.get((start, end), [(None, None)])
msgs = []
@@ -325,9 +341,9 @@ class PythonParser(object):
emsg = "didn't jump to line {lineno}"
emsg = emsg.format(lineno=end)
- msg = "line {start} {emsg}".format(start=start, emsg=emsg)
+ msg = "line {start} {emsg}".format(start=actual_start, emsg=emsg)
if smsg is not None:
- msg += ", because {smsg}".format(smsg=smsg.format(lineno=start))
+ msg += ", because {smsg}".format(smsg=smsg.format(lineno=actual_start))
msgs.append(msg)
@@ -939,10 +955,10 @@ class AstArcAnalyzer(object):
"""A function to make methods for online callable _code_object__ methods."""
def _code_object__oneline_callable(self, node):
start = self.line_for_node(node)
- self.add_arc(-start, start)
+ self.add_arc(-start, start, None, "didn't run the {0} on line {1}".format(noun, start))
self.add_arc(
start, -start, None,
- "didn't run the {0} on line {1}".format(noun, start),
+ "didn't finish the {0} on line {1}".format(noun, start),
)
return _code_object__oneline_callable