diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml new file mode 100644 index 00000000..49b67a3c --- /dev/null +++ b/.github/workflows/test.yml @@ -0,0 +1,22 @@ +name: Run tests + +on: [push, pull_request] + +jobs: + test-latest: + runs-on: ${{ matrix.os }} + strategy: + matrix: + os: [macos-latest, ubuntu-latest, windows-latest] + python-version: [3.5, 3.6, 3.7, 3.8] + + steps: + - uses: actions/checkout@v2 + - name: Set up Python ${{ matrix.python-version }} + uses: actions/setup-python@v1 + with: + python-version: ${{ matrix.python-version }} + - name: Install tox + run: python -m pip install --upgrade pip tox + - name: Run Tests + run: tox -e py,install,docs diff --git a/docs/release_notes.rst b/docs/release_notes.rst index 9e9c4f3f..b5f532a3 100644 --- a/docs/release_notes.rst +++ b/docs/release_notes.rst @@ -20,8 +20,10 @@ Bug Fixes The bug caused some argument names to go unreported in D417 (#448). * Fixed an issue where skipping errors on module level docstring via #noqa failed when there where more prior comments (#446). +* Support backslash-continued descriptions in docstrings (#472). * Correctly detect publicity of modules inside directories (#470, #494). + 5.0.2 - January 8th, 2020 --------------------------- diff --git a/src/pydocstyle/checker.py b/src/pydocstyle/checker.py index 8e3be2c4..cd2846e5 100644 --- a/src/pydocstyle/checker.py +++ b/src/pydocstyle/checker.py @@ -278,7 +278,9 @@ def check_indent(self, definition, docstring): indent = self._get_docstring_indent(definition, docstring) lines = docstring.split('\n') if len(lines) > 1: - lines = lines[1:] # First line does not need indent. + # First line and line continuations need no indent. + lines = [line for i, line in enumerate(lines) + if i and not lines[i-1].endswith('\\')] indents = [leading_space(l) for l in lines if not is_blank(l)] if set(' \t') == set(''.join(indents) + indent): yield violations.D206() @@ -703,7 +705,9 @@ def _check_parameters_section(docstring, definition, context): """ docstring_args = set() section_level_indent = leading_space(context.line) - content = context.following_lines + # Join line continuations, then resplit by line. + content = ( + '\n'.join(context.following_lines).replace('\\\n', '').split('\n')) for current_line, next_line in zip(content, content[1:]): # All parameter definitions in the Numpy parameters # section must be at the same indent level as the section diff --git a/src/tests/test_cases/sections.py b/src/tests/test_cases/sections.py index 2200ddfe..d671102b 100644 --- a/src/tests/test_cases/sections.py +++ b/src/tests/test_cases/sections.py @@ -389,7 +389,6 @@ def test_missing_docstring_another(skip, verbose): # noqa: D213, D407 @expect("D417: Missing argument descriptions in the docstring " "(argument(s) y are missing descriptions in " "'test_missing_numpy_args' docstring)") -@expect("D207: Docstring is under-indented") def test_missing_numpy_args(_private_arg=0, x=1, y=2): # noqa: D406, D407 """Toggle the gizmo. @@ -405,13 +404,19 @@ def test_missing_numpy_args(_private_arg=0, x=1, y=2): # noqa: D406, D407 class TestNumpy: # noqa: D203 """Test class.""" - def test_method(self, test, another_test, _, x=1, y=2, _private_arg=1): # noqa: D213, D407 + def test_method(self, test, another_test, z, _, x=1, y=2, _private_arg=1): # noqa: D213, D407 """Test a valid args section. + Some long string with a \ +line continuation. + Parameters ---------- test, another_test Some parameters without type. + z : some parameter with a very long type description that requires a \ +line continuation. + But no further description. x, y : int Some integer parameters. diff --git a/tox.ini b/tox.ini index 3638f82c..91eacd46 100644 --- a/tox.ini +++ b/tox.ini @@ -4,7 +4,7 @@ # install tox" and then run "tox" from this directory. [tox] -envlist = {py35,py36,py37,py38}-{tests,install},py36-docs +envlist = {py35,py36,py37,py38}-{tests,install},docs,install,py36-docs [testenv] download = true @@ -20,34 +20,43 @@ deps = -rrequirements/runtime.txt -rrequirements/tests.txt -[testenv:py37-install] +[testenv:install] skip_install = True commands = python setup.py bdist_wheel pip install --no-index --find-links=dist pydocstyle pydocstyle --help +[testenv:docs] +changedir = docs +deps = + -rrequirements/runtime.txt + -rrequirements/docs.txt +commands = sphinx-build -b html . _build + +[testenv:py36-docs] +changedir = {[testenv:docs]changedir} +deps = {[testenv:docs]deps} +commands = {[testenv:docs]commands} + # There's no way to generate sub-sections in tox. # The following sections are all references to the `py37-install`. [testenv:py35-install] -skip_install = {[testenv:py37-install]skip_install} -commands = {[testenv:py37-install]commands} +skip_install = {[testenv:install]skip_install} +commands = {[testenv:install]commands} [testenv:py36-install] -skip_install = {[testenv:py37-install]skip_install} -commands = {[testenv:py37-install]commands} +skip_install = {[testenv:install]skip_install} +commands = {[testenv:install]commands} -[testenv:py38-install] -skip_install = {[testenv:py37-install]skip_install} -commands = {[testenv:py37-install]commands} +[testenv:py37-install] +skip_install = {[testenv:install]skip_install} +commands = {[testenv:install]commands} -[testenv:py36-docs] -changedir=docs -deps = - -rrequirements/runtime.txt - -rrequirements/docs.txt -commands=sphinx-build -b html . _build +[testenv:py38-install] +skip_install = {[testenv:install]skip_install} +commands = {[testenv:install]commands} [pytest] pep8ignore =