summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNed Batchelder <ned@nedbatchelder.com>2018-02-09 16:26:39 -0500
committerNed Batchelder <ned@nedbatchelder.com>2018-02-09 16:26:39 -0500
commitcbfefaeed86e276677d4c0aa56c5897eb67dcf10 (patch)
treea0eef2b2ccb62433606209e32d2185b858deb315
parent18f721da6bbc651ddd698b6986f7eb439245d62e (diff)
downloadpython-coveragepy-cbfefaeed86e276677d4c0aa56c5897eb67dcf10.tar.gz
Properly handle empty decorated functions in 3.7. #640
-rw-r--r--CHANGES.rst6
-rw-r--r--coverage/parser.py13
-rw-r--r--tests/test_parser.py17
3 files changed, 29 insertions, 7 deletions
diff --git a/CHANGES.rst b/CHANGES.rst
index 5aa8874..3779a00 100644
--- a/CHANGES.rst
+++ b/CHANGES.rst
@@ -19,7 +19,11 @@ Change history for Coverage.py
Unreleased
----------
-(none yet)
+- On Python 3.7, reporting about a decorated function with no body other than a
+ docstring would crash coverage.py with an IndexError (`issue 640`_). This is
+ now fixed.
+
+.. _issue 640: https://bitbucket.org/ned/coveragepy/issues/640/indexerror-reporting-on-an-empty-decorated
.. _changes_45:
diff --git a/coverage/parser.py b/coverage/parser.py
index 590eace..6e6cccd 100644
--- a/coverage/parser.py
+++ b/coverage/parser.py
@@ -831,12 +831,13 @@ class AstArcAnalyzer(object):
# in `self.statements`. For some constructs, `line_for_node` is
# not what we'd think of as the first line in the statement, so map
# it to the first one.
- body_start = self.line_for_node(node.body[0])
- body_start = self.multiline.get(body_start, body_start)
- for lineno in range(last+1, body_start):
- if lineno in self.statements:
- self.add_arc(last, lineno)
- last = lineno
+ if node.body:
+ body_start = self.line_for_node(node.body[0])
+ body_start = self.multiline.get(body_start, body_start)
+ for lineno in range(last+1, body_start):
+ if lineno in self.statements:
+ self.add_arc(last, lineno)
+ last = lineno
# The body is handled in collect_arcs.
return set([ArcStart(last)])
diff --git a/tests/test_parser.py b/tests/test_parser.py
index e9628ac..afb8771 100644
--- a/tests/test_parser.py
+++ b/tests/test_parser.py
@@ -187,6 +187,23 @@ class PythonParserTest(CoverageTest):
self.assertEqual(parser.raw_statements, set([1, 2, 3, 5, 6, 7, 8]))
self.assertEqual(parser.statements, set([1, 2, 3]))
+ def test_empty_decorated_function(self):
+ parser = self.parse_source("""\
+ def decorator(func):
+ return func
+
+ @decorator
+ def foo(self):
+ '''Docstring'''
+
+ @decorator
+ def bar(self):
+ pass
+ """)
+ self.assertEqual(parser.statements, set([1, 2, 4, 8, 10]))
+ self.assertEqual(parser.arcs(), set(self.arcz_to_arcs(".1 14 48 8. .2 2. -8A A-8")))
+ self.assertEqual(parser.exit_counts(), {1: 1, 2: 1, 4: 1, 8: 1, 10: 1})
+
class ParserMissingArcDescriptionTest(CoverageTest):
"""Tests for PythonParser.missing_arc_description."""