PyCQA / pydocstyle

docstring style checker
http://pydocstyle.org
MIT License
1.11k stars 189 forks source link

IndentationError: unexpected indent when docstring is in nested function. #370

Closed pinkavaj closed 5 years ago

pinkavaj commented 5 years ago

Exception is raised for latest (6de6d93) pydocstyle when nested function contains docstring with arguments section.

How to reproduce:

Write python file sample.py:

def foo():
    def bar(a):
        """A docstring

        Args:
            a : An argument.
        """
        pass

Run: pydocstyle sample.py

Result:

Traceback (most recent call last):
  File "/home/pinky/.local/bin/pydocstyle", line 11, in <module>
    load_entry_point('pydocstyle', 'console_scripts', 'pydocstyle')()
  File "/home/pinky/work/pydocstyle/src/pydocstyle/cli.py", line 68, in main
    sys.exit(run_pydocstyle())
  File "/home/pinky/work/pydocstyle/src/pydocstyle/cli.py", line 45, in run_pydocstyle
    ignore_decorators=ignore_decorators))
  File "/home/pinky/work/pydocstyle/src/pydocstyle/checker.py", line 883, in check
    ignore_decorators):
  File "/home/pinky/work/pydocstyle/src/pydocstyle/checker.py", line 124, in check_source
    for error in errors:
  File "/home/pinky/work/pydocstyle/src/pydocstyle/checker.py", line 831, in check_docstring_sections
    yield from self._check_google_sections(lines, definition, docstring)
  File "/home/pinky/work/pydocstyle/src/pydocstyle/checker.py", line 819, in _check_google_sections
    yield from self._check_google_section(docstring, definition, ctx)
  File "/home/pinky/work/pydocstyle/src/pydocstyle/checker.py", line 714, in _check_google_section
    yield from cls._check_args_section(docstring, definition, context)
  File "/home/pinky/work/pydocstyle/src/pydocstyle/checker.py", line 681, in _check_args_section
    function_pos_args = get_function_args(definition.source)
  File "/home/pinky/work/pydocstyle/src/pydocstyle/checker.py", line 916, in get_function_args
    function_arg_node = ast.parse(function_string).body[0].args
  File "/usr/lib/python3.7/ast.py", line 35, in parse
    return compile(source, filename, mode, PyCF_ONLY_AST)
  File "<unknown>", line 1
    def bar(a):
    ^
IndentationError: unexpected indent
Hanaasagi commented 5 years ago

NestedFunction keep the source origin indention, so ast could not parse. One quick way to fix is just removing any common leading whitespace from every line in source.

diff --git a/src/pydocstyle/checker.py b/src/pydocstyle/checker.py
index 29ff08f..03ab4d6 100644
--- a/src/pydocstyle/checker.py
+++ b/src/pydocstyle/checker.py
@@ -3,6 +3,7 @@
 import ast
 import string
 import sys
+import textwrap
 import tokenize as tk
 from itertools import takewhile, chain
 from re import compile as re
@@ -678,7 +679,7 @@ class ConventionChecker:

         """
         if definition.kind == 'function':
-            function_pos_args = get_function_args(definition.source)
+            function_pos_args = get_function_args(textwrap.dedent(definition.source))
             docstring_args = set()
             for line in context.following_lines:
                 match = ConventionChecker.GOOGLE_ARGS_REGEX.match(line)

If it seems good, I will pull request to resolve it.

pinkavaj commented 5 years ago

Cannot this produce confusing outputs for users?

pmantica1 commented 5 years ago

What is the progress with this issue?

ljades commented 5 years ago

Can a package/project owner approve and publish one of the PR's open for fixing the IndentationError? Until it's fixed my project can't feasibly upgrade to pydocstyle 4.0

sambhav commented 5 years ago

This should be closed now - given that the issue is fixed in 4.0.1