diff options
author | Ned Batchelder <ned@nedbatchelder.com> | 2016-01-10 15:33:01 -0500 |
---|---|---|
committer | Ned Batchelder <ned@nedbatchelder.com> | 2016-01-10 15:33:01 -0500 |
commit | 4772c5b15d3586e21cbb3866183ba5fd07a01b3d (patch) | |
tree | 6fd36ab513a2ffac9fb4e1c1f8dfb154e6d9d2db | |
parent | 259985f289987ecdddd02f76736669e13ec1268a (diff) | |
download | python-coveragepy-git-4772c5b15d3586e21cbb3866183ba5fd07a01b3d.tar.gz |
Class docstrings are executable.
-rw-r--r-- | coverage/parser.py | 20 | ||||
-rw-r--r-- | tests/test_coverage.py | 4 | ||||
-rw-r--r-- | tests/test_parser.py | 6 |
3 files changed, 18 insertions, 12 deletions
diff --git a/coverage/parser.py b/coverage/parser.py index 501b76c4..307b83e6 100644 --- a/coverage/parser.py +++ b/coverage/parser.py @@ -125,6 +125,7 @@ class PythonParser(object): excluding = False excluding_decorators = False prev_toktype = token.INDENT + last_name = None first_line = None empty = True first_on_line = True @@ -146,6 +147,7 @@ class PythonParser(object): # we need to exclude them. The simplest way is to note the # lines with the 'class' keyword. self.raw_classdefs.add(slineno) + last_name = ttext elif toktype == token.OP: if ttext == ':': should_exclude = (elineno in self.raw_excluded) or excluding_decorators @@ -168,7 +170,8 @@ class PythonParser(object): # (a trick from trace.py in the stdlib.) This works for # 99.9999% of cases. For the rest (!) see: # http://stackoverflow.com/questions/1769332/x/1769794#1769794 - self.raw_docstrings.update(range(slineno, elineno+1)) + if last_name == 'def': + self.raw_docstrings.update(range(slineno, elineno+1)) elif toktype == token.NEWLINE: if first_line is not None and elineno != first_line: # We're at the end of a line, and we've ended on a @@ -334,6 +337,7 @@ class AstArcAnalyzer(object): if int(os.environ.get("COVERAGE_ASTDUMP", 0)): # pragma: debugging # Dump the AST so that failing tests have helpful output. print(self.statements) + print(self.multiline) ast_dump(self.root_node) self.arcs = None @@ -508,13 +512,13 @@ class AstArcAnalyzer(object): if dec_start != last: self.arcs.add((last, dec_start)) last = dec_start - # The definition line may have been missed, but we should have it in - # `self.statements`. - body_start = self.line_for_node(node.body[0]) - for lineno in range(last+1, body_start): - if lineno in self.statements: - self.arcs.add((last, lineno)) - last = lineno + # The definition line may have been missed, but we should have it in + # `self.statements`. + body_start = self.line_for_node(node.body[0]) + for lineno in range(last+1, body_start): + if lineno in self.statements: + self.arcs.add((last, lineno)) + last = lineno # the body is handled in add_arcs_for_code_objects. return set([last]) diff --git a/tests/test_coverage.py b/tests/test_coverage.py index 227360e3..1173e1e6 100644 --- a/tests/test_coverage.py +++ b/tests/test_coverage.py @@ -1140,7 +1140,9 @@ class CompoundStatementTest(CoverageTest): x = theClass().foo() assert x == 1 """, - [2,6,8,10,11,13,14], "") + [2, 3, 6, 8, 10, 11, 13, 14], "", + arcz=".2 2D DE E-2 23 36 6A A-2 .8 8-6 .B B-A", + ) class ExcludeTest(CoverageTest): diff --git a/tests/test_parser.py b/tests/test_parser.py index c32fdc4d..fe907117 100644 --- a/tests/test_parser.py +++ b/tests/test_parser.py @@ -145,8 +145,8 @@ class PythonParserTest(CoverageTest): def func(x, y=5): return 6 - class Foo: # the only statement... - '''9''' + class Foo: # only this.. + '''9''' # ..and this are statements. @foo # nocover def __init__(self): '''12''' @@ -169,7 +169,7 @@ class PythonParserTest(CoverageTest): parser.raw_statements, set([3, 4, 5, 6, 8, 9, 10, 13, 15, 16, 17, 20, 22, 23, 25, 26]) ) - self.assertEqual(parser.statements, set([8])) + self.assertEqual(parser.statements, set([8, 9])) def test_class_decorator_pragmas(self): parser = self.parse_source("""\ |