IndexError reporting on an empty decorated function under Python 3.7

Issue #640 resolved
Ned Batchelder
repo owner created an issue
$ python -V
Python 3.7.0b1

$ cat foob.py
def decorator(func):
    return func

class Class:
    @decorator
    def foo(self):
        """Docstring"""

$ coverage run --branch foob.py && coverage xml
Traceback (most recent call last):
  File "/usr/local/virtualenvs/tmp-e47d674e964684d7/bin/coverage", line 11, in <module>
    sys.exit(main())
  File "/usr/local/virtualenvs/tmp-e47d674e964684d7/lib/python3.7/site-packages/coverage/cmdline.py", line 753, in main
    status = CoverageScript().command_line(argv)
  File "/usr/local/virtualenvs/tmp-e47d674e964684d7/lib/python3.7/site-packages/coverage/cmdline.py", line 522, in command_line
    total = self.coverage.xml_report(outfile=outfile, **report_args)
  File "/usr/local/virtualenvs/tmp-e47d674e964684d7/lib/python3.7/site-packages/coverage/control.py", line 1140, in xml_report
    return reporter.report(morfs, outfile=outfile)
  File "/usr/local/virtualenvs/tmp-e47d674e964684d7/lib/python3.7/site-packages/coverage/xmlreport.py", line 72, in report
    self.report_files(self.xml_file, morfs)
  File "/usr/local/virtualenvs/tmp-e47d674e964684d7/lib/python3.7/site-packages/coverage/report.py", line 91, in report_files
    report_fn(fr, self.coverage._analyze(fr))
  File "/usr/local/virtualenvs/tmp-e47d674e964684d7/lib/python3.7/site-packages/coverage/control.py", line 970, in _analyze
    return Analysis(self.data, it)
  File "/usr/local/virtualenvs/tmp-e47d674e964684d7/lib/python3.7/site-packages/coverage/results.py", line 28, in __init__
    self._arc_possibilities = sorted(self.file_reporter.arcs())
  File "/usr/local/virtualenvs/tmp-e47d674e964684d7/lib/python3.7/site-packages/coverage/python.py", line 208, in arcs
    return self.parser.arcs()
  File "/usr/local/virtualenvs/tmp-e47d674e964684d7/lib/python3.7/site-packages/coverage/parser.py", line 263, in arcs
    self._analyze_ast()
  File "/usr/local/virtualenvs/tmp-e47d674e964684d7/lib/python3.7/site-packages/coverage/parser.py", line 273, in _analyze_ast
    aaa.analyze()
  File "/usr/local/virtualenvs/tmp-e47d674e964684d7/lib/python3.7/site-packages/coverage/parser.py", line 545, in analyze
    code_object_handler(node)
  File "/usr/local/virtualenvs/tmp-e47d674e964684d7/lib/python3.7/site-packages/coverage/parser.py", line 1089, in _code_object__ClassDef
    exits = self.add_body_arcs(node.body, from_start=ArcStart(start))
  File "/usr/local/virtualenvs/tmp-e47d674e964684d7/lib/python3.7/site-packages/coverage/parser.py", line 666, in add_body_arcs
    prev_starts = self.add_arcs(body_node)
  File "/usr/local/virtualenvs/tmp-e47d674e964684d7/lib/python3.7/site-packages/coverage/parser.py", line 629, in add_arcs
    return handler(node)
  File "/usr/local/virtualenvs/tmp-e47d674e964684d7/lib/python3.7/site-packages/coverage/parser.py", line 834, in _handle_decorated
    body_start = self.line_for_node(node.body[0])
IndexError: list index out of range

Comments (4)

  1. Naoki INADA

    We're thinking change again in 3.7b3. In this time, docstring will be moved from attribute to special AST node named DocString. See this example:

    source = """\
    def foo():
        "docstring"
    """
    
    import ast
    t = ast.parse(source)
    print(ast.dump(t))
    

    3.6: ... FunctionDef(name='foo', args=arguments(...), body=[Expr(value=Str(s='docstring'))], decorator_list=[], returns=None) ...

    3.7b2: ... FunctionDef(name='foo', args=arguments(...), body=[], decorator_list=[], returns=None, docstring='docstring') ...

    3.7b3?: ... FunctionDef(name='foo', args=arguments(args=[], vararg=None, kwonlyargs=[], kw_defaults=[], kwarg=None, defaults=[]), body=[DocString(s='docstring')], decorator_list=[], returns=None) ...

    Of course, ast.getdocstring() works in all versions. With this change, you can get lineno of docstring from the DocString node (while there is bug for now).

    We want feedback from AST users. Please post your comment on this issue or Python-Dev mailing list.

  2. Log in to comment