Hello community,

here is the log from the commit of package python-pydocstyle for 
openSUSE:Factory checked in at 2020-10-29 09:47:24
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/python-pydocstyle (Old)
 and      /work/SRC/openSUSE:Factory/.python-pydocstyle.new.3463 (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Package is "python-pydocstyle"

Thu Oct 29 09:47:24 2020 rev:9 rq:841138 version:5.1.1

Changes:
--------
--- /work/SRC/openSUSE:Factory/python-pydocstyle/python-pydocstyle.changes      
2020-05-28 09:08:18.431874660 +0200
+++ 
/work/SRC/openSUSE:Factory/.python-pydocstyle.new.3463/python-pydocstyle.changes
    2020-10-29 09:47:31.656124493 +0100
@@ -1,0 +2,22 @@
+Sat Oct 10 18:42:12 UTC 2020 - Arun Persaud <[email protected]>
+
+- update to version 5.1.1:
+  * Bug Fixes
+    + Fix IndexError crash on one-line backslashed docstrings (#506).
+
+- changes from version 5.1.0 :
+  * New Features
+    + Skip function arguments prefixed with _ in D417 check (#440).
+  * Bug Fixes
+    + Update convention support documentation (#386, #393)
+    + Detect inner asynchronous functions for D202 (#467)
+    + Fix indentation error while parsing class methods (#441).
+    + Fix a bug in parsing Google-style argument description. 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).
+
+-------------------------------------------------------------------

Old:
----
  pydocstyle-5.0.2.tar.gz

New:
----
  pydocstyle-5.1.1.tar.gz

++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Other differences:
------------------
++++++ python-pydocstyle.spec ++++++
--- /var/tmp/diff_new_pack.lRRdcO/_old  2020-10-29 09:47:32.476125267 +0100
+++ /var/tmp/diff_new_pack.lRRdcO/_new  2020-10-29 09:47:32.476125267 +0100
@@ -19,7 +19,7 @@
 %{?!python_module:%define python_module() python-%{**} python3-%{**}}
 %define skip_python2 1
 Name:           python-pydocstyle
-Version:        5.0.2
+Version:        5.1.1
 Release:        0
 Summary:        Python docstring style checker
 License:        MIT

++++++ pydocstyle-5.0.2.tar.gz -> pydocstyle-5.1.1.tar.gz ++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/pydocstyle-5.0.2/.appveyor.yml 
new/pydocstyle-5.1.1/.appveyor.yml
--- old/pydocstyle-5.0.2/.appveyor.yml  2020-01-08 13:37:01.000000000 +0100
+++ new/pydocstyle-5.1.1/.appveyor.yml  1970-01-01 01:00:00.000000000 +0100
@@ -1,17 +0,0 @@
-environment:
-  matrix:
-    - TOXENV: "py35-tests"
-    - TOXENV: "py35-install"
-    - TOXENV: "py36-tests"
-    - TOXENV: "py36-install"
-    - TOXENV: "py37-tests"
-    - TOXENV: "py37-install"
-    - TOXENV: "py36-docs"
-
-install:
-  - pip install tox
-
-build: off
-
-test_script:
-  - tox -e %TOXENV%
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/pydocstyle-5.0.2/.bumpversion.cfg 
new/pydocstyle-5.1.1/.bumpversion.cfg
--- old/pydocstyle-5.0.2/.bumpversion.cfg       2020-01-08 13:37:01.000000000 
+0100
+++ new/pydocstyle-5.1.1/.bumpversion.cfg       2020-08-29 22:52:53.000000000 
+0200
@@ -1,5 +1,5 @@
 [bumpversion]
-current_version = 5.0.2
+current_version = 5.1.1
 commit = True
 parse = (?P<major>\d+)\.(?P<minor>\d+)\.(?P<patch>\d+)((?P<release>.*))?
 serialize = 
@@ -16,4 +16,3 @@
 [bumpversion:file:setup.py]
 
 [bumpversion:file:src/pydocstyle/utils.py]
-
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/pydocstyle-5.0.2/.github/workflows/test.yml 
new/pydocstyle-5.1.1/.github/workflows/test.yml
--- old/pydocstyle-5.0.2/.github/workflows/test.yml     1970-01-01 
01:00:00.000000000 +0100
+++ new/pydocstyle-5.1.1/.github/workflows/test.yml     2020-08-29 
22:52:53.000000000 +0200
@@ -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 -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/pydocstyle-5.0.2/.gitignore 
new/pydocstyle-5.1.1/.gitignore
--- old/pydocstyle-5.0.2/.gitignore     2020-01-08 13:37:01.000000000 +0100
+++ new/pydocstyle-5.1.1/.gitignore     2020-08-29 22:52:53.000000000 +0200
@@ -54,3 +54,6 @@
 
 # PyCharm files
 .idea
+
+# VS Code
+.vscode/
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/pydocstyle-5.0.2/.travis.yml 
new/pydocstyle-5.1.1/.travis.yml
--- old/pydocstyle-5.0.2/.travis.yml    2020-01-08 13:37:01.000000000 +0100
+++ new/pydocstyle-5.1.1/.travis.yml    1970-01-01 01:00:00.000000000 +0100
@@ -1,29 +0,0 @@
-# Travis (http://travis-ci.org/) is a continuous integration
-# service for open source projects. This file configures
-# Travis to install and run "tox" test runner, which is
-# configured in tox.ini file.
-
-sudo: false
-language: python
-install: pip install tox
-script: tox
-matrix:
-  include:
-    - python: 3.5
-      env: TOXENV=py35-tests
-    - python: 3.5
-      env: TOXENV=py35-install
-    - python: 3.6
-      env: TOXENV=py36-tests
-    - python: 3.6
-      env: TOXENV=py36-install
-    - python: 3.7
-      env: TOXENV=py37-tests
-    - python: 3.7
-      env: TOXENV=py37-install
-    - python: 3.8
-      env: TOXENV=py38-tests
-    - python: 3.8
-      env: TOXENV=py38-install
-    - python: 3.6
-      env: TOXENV=docs
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/pydocstyle-5.0.2/README.rst 
new/pydocstyle-5.1.1/README.rst
--- old/pydocstyle-5.0.2/README.rst     2020-01-08 13:37:01.000000000 +0100
+++ new/pydocstyle-5.1.1/README.rst     2020-08-29 22:52:53.000000000 +0200
@@ -2,11 +2,8 @@
 ====================================
 
 
-.. image:: https://travis-ci.org/PyCQA/pydocstyle.svg?branch=master
-    :target: https://travis-ci.org/PyCQA/pydocstyle
-
-.. image:: 
https://ci.appveyor.com/api/projects/status/40kkc366bmrrttca/branch/master?svg=true
-    :target: https://ci.appveyor.com/project/Nurdok/pydocstyle/branch/master
+.. image:: https://github.com/PyCQA/pydocstyle/workflows/Run%20tests/badge.svg
+    :target: 
https://github.com/PyCQA/pydocstyle/actions?query=workflow%3A%22Run+tests%22+branch%3Amaster
 
 .. image:: https://readthedocs.org/projects/pydocstyle/badge/?version=latest
     :target: https://readthedocs.org/projects/pydocstyle/?badge=latest
@@ -15,6 +12,8 @@
 .. image:: https://img.shields.io/pypi/pyversions/pydocstyle.svg
     :target: https://pypi.org/project/pydocstyle
 
+.. image:: https://pepy.tech/badge/pydocstyle
+    :target: https://pepy.tech/project/pydocstyle
 
 **pydocstyle** is a static analysis tool for checking compliance with Python
 docstring conventions.
@@ -55,7 +54,7 @@
 Links
 -----
 
-* `Read the full documentation here <http://pydocstyle.org>`_.
+* `Read the full documentation here <http://pydocstyle.org/en/stable/>`_.
 
 * `Fork pydocstyle on GitHub <http://github.com/PyCQA/pydocstyle>`_.
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/pydocstyle-5.0.2/docs/conf.py 
new/pydocstyle-5.1.1/docs/conf.py
--- old/pydocstyle-5.0.2/docs/conf.py   2020-01-08 13:37:01.000000000 +0100
+++ new/pydocstyle-5.1.1/docs/conf.py   2020-08-29 22:52:53.000000000 +0200
@@ -58,7 +58,7 @@
 # The short X.Y version.
 version = pydocstyle.__version__
 # The full version, including alpha/beta/rc tags.
-release = '1.0.0'
+release = pydocstyle.__version__
 
 # The language for content autogenerated by Sphinx. Refer to documentation
 # for a list of supported languages.
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/pydocstyle-5.0.2/docs/error_codes.rst 
new/pydocstyle-5.1.1/docs/error_codes.rst
--- old/pydocstyle-5.0.2/docs/error_codes.rst   2020-01-08 13:37:01.000000000 
+0100
+++ new/pydocstyle-5.1.1/docs/error_codes.rst   2020-08-29 22:52:53.000000000 
+0200
@@ -9,19 +9,23 @@
 Default conventions
 -------------------
 
-Not all error codes are checked for by default.  There are three
-conventions that may be used by pydocstyle: ``pep257``, ``numpy`` and 
``google``.
+Not all error codes are checked for by default.  There are three conventions
+that may be used by pydocstyle: ``pep257``, ``numpy`` and ``google``.
 
-The pep257 convention, which is enabled by default in pydocstyle,
-checks for all of the above errors except for D203, D212, D213, D214,
-D215, D404, D405, D406, D407, D408, D409, D410, D411, D413, D415, D416 and D417
-(as specified in `PEP257 <http://www.python.org/dev/peps/pep-0257/>`_).
+The ``pep257`` convention (specified in `PEP257
+<http://www.python.org/dev/peps/pep-0257/>`_), which is enabled by default in
+pydocstyle, checks for all of the above errors except for D203, D212, D213,
+D214, D215, D404, D405, D406, D407, D408, D409, D410, D411, D413, D415, D416
+and D417.
 
-The numpy convention checks for all of the above errors except for
-D107, D203, D212, D213, D402, D413, D415, D416 and D417.
+The ``numpy`` convention added in v2.0.0 supports the `numpydoc docstring
+<https://github.com/numpy/numpydoc>`_ standard. This checks all of of the
+errors except for D107, D203, D212, D213, D402, D413, D415, D416, and D417.
 
-The google convention checks for all of the above errors except for
-D203, D204, D213, D215, D400, D401, D404, D406, D407, D408, D409 and D413.
+The ``google`` convention added in v4.0.0 supports the `Google Python Style
+Guide <https://google.github.io/styleguide/pyguide.html>`_. This checks for
+all the errors except D203, D204, D213, D215, D400, D401, D404, D406, D407,
+D408, D409 and D413.
 
 These conventions may be specified using `--convention=<name>` when
 running pydocstyle from the command line or by specifying the
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/pydocstyle-5.0.2/docs/release_notes.rst 
new/pydocstyle-5.1.1/docs/release_notes.rst
--- old/pydocstyle-5.0.2/docs/release_notes.rst 2020-01-08 13:37:01.000000000 
+0100
+++ new/pydocstyle-5.1.1/docs/release_notes.rst 2020-08-29 22:52:53.000000000 
+0200
@@ -4,6 +4,35 @@
 **pydocstyle** version numbers follow the
 `Semantic Versioning <http://semver.org/>`_ specification.
 
+
+5.1.1 - August 29th, 2020
+---------------------------
+
+Bug Fixes
+
+* Fix ``IndexError`` crash on one-line backslashed docstrings (#506).
+
+
+5.1.0 - August 22nd, 2020
+---------------------------
+
+New Features
+
+* Skip function arguments prefixed with `_` in D417 check (#440).
+
+Bug Fixes
+
+* Update convention support documentation (#386, #393)
+* Detect inner asynchronous functions for D202 (#467)
+* Fix indentation error while parsing class methods (#441).
+* Fix a bug in parsing Google-style argument description.
+  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 -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/pydocstyle-5.0.2/docs/snippets/publicity.rst 
new/pydocstyle-5.1.1/docs/snippets/publicity.rst
--- old/pydocstyle-5.0.2/docs/snippets/publicity.rst    2020-01-08 
13:37:01.000000000 +0100
+++ new/pydocstyle-5.1.1/docs/snippets/publicity.rst    2020-08-29 
22:52:53.000000000 +0200
@@ -10,7 +10,9 @@
 considered *public* if -
 
 1. Its immediate parent is public *and*
-2. Its name does not contain a single leading underscore.
+2. Its name does *not* start with a single or double underscore.
+
+    a. Note, names that start and end with a double underscore are *public* 
(e.g. ``__init__.py``).
 
 A construct's immediate parent is the construct that contains it. For example,
 a method's parent is a class object. A class' parent is usually a module, but
@@ -25,6 +27,12 @@
 also considered private since its parent is a private class, even though its
 name does not begin with a single underscore.
 
+Note, a module's parent is recursively checked upward until we reach a 
directory
+in ``sys.path`` to avoid considering the complete filepath of a module.
+For example, consider the module ``/_foo/bar/baz.py``.
+If ``PYTHONPATH`` is set to ``/``, then ``baz.py`` is *private*.
+If ``PYTHONPATH`` is set to ``/_foo/``, then ``baz.py`` is *public*.
+
 Modules are parsed to look if ``__all__`` is defined. If so, only those top
 level constructs are considered public. The parser looks for ``__all__``
 defined as a literal list or tuple. As the parser doesn't execute the module,
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/pydocstyle-5.0.2/setup.py 
new/pydocstyle-5.1.1/setup.py
--- old/pydocstyle-5.0.2/setup.py       2020-01-08 13:37:01.000000000 +0100
+++ new/pydocstyle-5.1.1/setup.py       2020-08-29 22:52:53.000000000 +0200
@@ -2,7 +2,7 @@
 import sys
 
 # Do not update the version manually - it is managed by `bumpversion`.
-version = '5.0.2'
+version = '5.1.1'
 
 
 requirements = [
@@ -42,4 +42,7 @@
             'pydocstyle = pydocstyle.cli:main',
         ],
     },
+    project_urls={
+        'Release Notes': 
'http://www.pydocstyle.org/en/latest/release_notes.html',
+    },
 )
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/pydocstyle-5.0.2/src/pydocstyle/checker.py 
new/pydocstyle-5.1.1/src/pydocstyle/checker.py
--- old/pydocstyle-5.0.2/src/pydocstyle/checker.py      2020-01-08 
13:37:01.000000000 +0100
+++ new/pydocstyle-5.1.1/src/pydocstyle/checker.py      2020-08-29 
22:52:53.000000000 +0200
@@ -96,9 +96,9 @@
         r"(\w+)"        # Followed by 1 or more unicode chars, numbers or 
underscores
                         # The above is captured as the first group as this is 
the paramater name.
         r"\s*"          # Followed by 0 or more whitespace characters
-        r"\(?(.*?)\)?"  # Matches patterns contained within round brackets.
-                        # The `(.*?)` is the second capturing group which 
matches any sequence of
-                        # characters in a non-greedy way (denoted by the `*?`)
+        r"(\(.*?\))?"   # Matches patterns contained within round brackets.
+                        # The `.*?`matches any sequence of characters in a 
non-greedy
+                        # way (denoted by the `*?`)
         r"\s*"          # Followed by 0 or more whitespace chars
         r":"            # Followed by a colon
         ".+"            # Followed by 1 or more characters - which is the 
docstring for the parameter
@@ -203,7 +203,7 @@
                 # class.
                 if not (
                     blanks_after_count == 1 and
-                    re(r"\s+(?:(?:class|def)\s|@)").match(after)
+                    re(r"\s+(?:(?:class|def|async def)\s|@)").match(after)
                 ):
                     yield violations.D202(blanks_after_count)
 
@@ -278,14 +278,17 @@
             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()
-                if (len(indents) > 1 and min(indents[:-1]) > indent or
-                        indents[-1] > indent):
+                if (len(indents) > 1 and min(indents[:-1]) > indent) or (
+                    len(indents) > 0 and indents[-1] > indent
+                ):
                     yield violations.D208()
-                if min(indents) < indent:
+                if len(indents) > 0 and min(indents) < indent:
                     yield violations.D207()
 
     @check_for(Definition)
@@ -703,7 +706,9 @@
         """
         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
@@ -764,6 +769,13 @@
             # positional argument as it is `cls` or `self`
             if definition.kind == 'method' and not definition.is_static:
                 function_args = function_args[1:]
+            # Filtering out any arguments prefixed with `_` marking them
+            # as private.
+            function_args = [
+                arg_name
+                for arg_name in function_args
+                if not is_def_arg_private(arg_name)
+            ]
             missing_args = set(function_args) - docstring_args
             if missing_args:
                 yield violations.D417(", ".join(sorted(missing_args)),
@@ -996,10 +1008,24 @@
     if result is not None:
         return result.group()
 
+def is_def_arg_private(arg_name):
+    """Return a boolean indicating if the argument name is private."""
+    return arg_name.startswith("_")
 
-def get_function_args(function_string):
+def get_function_args(function_source):
     """Return the function arguments given the source-code string."""
-    function_arg_node = 
ast.parse(textwrap.dedent(function_string)).body[0].args
+    # We are stripping the whitespace from the left of the
+    # function source.
+    # This is so that if the docstring has incorrectly
+    # indented lines, which are at a lower indent than the
+    # function source, we still dedent the source correctly
+    # and the AST parser doesn't throw an error.
+    try:
+        function_arg_node = ast.parse(function_source.lstrip()).body[0].args
+    except SyntaxError:
+        # If we still get a syntax error, we don't want the
+        # the checker to crash. Instead we just return a blank list.
+        return []
     arg_nodes = function_arg_node.args
     kwonly_arg_nodes = function_arg_node.kwonlyargs
     return [arg_node.arg for arg_node in chain(arg_nodes, kwonly_arg_nodes)]
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/pydocstyle-5.0.2/src/pydocstyle/cli.py 
new/pydocstyle-5.1.1/src/pydocstyle/cli.py
--- old/pydocstyle-5.0.2/src/pydocstyle/cli.py  2020-01-08 13:37:01.000000000 
+0100
+++ new/pydocstyle-5.1.1/src/pydocstyle/cli.py  2020-08-29 22:52:53.000000000 
+0200
@@ -71,7 +71,7 @@
 
 
 def setup_stream_handlers(conf):
-    """Setup logging stream handlers according to the options."""
+    """Set up logging stream handlers according to the options."""
     class StdoutFilter(logging.Filter):
         def filter(self, record):
             return record.levelno in (logging.DEBUG, logging.INFO)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/pydocstyle-5.0.2/src/pydocstyle/config.py 
new/pydocstyle-5.1.1/src/pydocstyle/config.py
--- old/pydocstyle-5.0.2/src/pydocstyle/config.py       2020-01-08 
13:37:01.000000000 +0100
+++ new/pydocstyle-5.1.1/src/pydocstyle/config.py       2020-08-29 
22:52:53.000000000 +0200
@@ -463,7 +463,7 @@
                         'known errors: %s', part)
                 expanded_codes.update(codes_to_add)
         except TypeError as e:
-            raise IllegalConfiguration(e)
+            raise IllegalConfiguration(e) from e
 
         return expanded_codes
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/pydocstyle-5.0.2/src/pydocstyle/parser.py 
new/pydocstyle-5.1.1/src/pydocstyle/parser.py
--- old/pydocstyle-5.0.2/src/pydocstyle/parser.py       2020-01-08 
13:37:01.000000000 +0100
+++ new/pydocstyle-5.1.1/src/pydocstyle/parser.py       2020-08-29 
22:52:53.000000000 +0200
@@ -1,10 +1,12 @@
 """Python code parser."""
 
+import sys
 import textwrap
 import tokenize as tk
 from itertools import chain, dropwhile
 from re import compile as re
 from io import StringIO
+from pathlib import Path
 
 from .utils import log
 
@@ -14,6 +16,8 @@
 
 
 class ParseError(Exception):
+    """An error parsing contents of a Python file."""
+
     def __str__(self):
         return "Cannot parse file."
 
@@ -111,7 +115,40 @@
 
     @property
     def is_public(self):
-        return not self.name.startswith('_') or self.name.startswith('__')
+        """Return True iff the module is considered public.
+
+        This helps determine if it requires a docstring.
+        """
+        module_name = Path(self.name).stem
+        return (
+            not self._is_inside_private_package() and
+            self._is_public_name(module_name)
+        )
+
+    def _is_inside_private_package(self):
+        """Return True if the module is inside a private package."""
+        path = Path(self.name).parent  # Ignore the actual module's name.
+        syspath = [Path(p) for p in sys.path]  # Convert to pathlib.Path.
+
+        # Bail if we are at the root directory or in `PYTHONPATH`.
+        while path != path.parent and path not in syspath:
+            if self._is_private_name(path.name):
+                return True
+            path = path.parent
+
+        return False
+
+    def _is_public_name(self, module_name):
+        """Determine whether a "module name" (i.e. module or package name) is 
public."""
+        return (
+            not module_name.startswith('_') or (
+                module_name.startswith('__') and module_name.endswith('__')
+            )
+        )
+
+    def _is_private_name(self, module_name):
+        """Determine whether a "module name" (i.e. module or package name) is 
private."""
+        return not self._is_public_name(module_name)
 
     def __str__(self):
         return 'at module level'
@@ -183,6 +220,7 @@
 
     @property
     def is_static(self):
+        """Return True iff the method is static."""
         for decorator in self.decorators:
             if decorator.name == "staticmethod":
                 return True
@@ -221,6 +259,7 @@
     the start and end of the token.
 
     """
+
     def __new__(cls, v, start, end):
         return str.__new__(cls, v)
 
@@ -372,9 +411,9 @@
         return None
 
     def parse_decorators(self):
-        """Called after first @ is found.
+        """Parse decorators into self._accumulated_decorators.
 
-        Parse decorators into self._accumulated_decorators.
+        Called after first @ is found.
         Continue to do so until encountering the 'def' or 'class' start token.
         """
         name = []
@@ -576,12 +615,20 @@
     def parse_skip_comment(self):
         """Parse a definition comment for noqa skips."""
         skipped_error_codes = ''
-        if self.current.kind == tk.COMMENT:
-            if 'noqa: ' in self.current.value:
-                skipped_error_codes = ''.join(
-                     self.current.value.split('noqa: ')[1:])
-            elif self.current.value.startswith('# noqa'):
-                skipped_error_codes = 'all'
+        while self.current.kind in (tk.COMMENT, tk.NEWLINE, tk.NL):
+            if self.current.kind == tk.COMMENT:
+                if 'noqa: ' in self.current.value:
+                    skipped_error_codes = ''.join(
+                        self.current.value.split('noqa: ')[1:])
+                elif self.current.value.startswith('# noqa'):
+                    skipped_error_codes = 'all'
+            self.stream.move()
+            self.log.debug("parsing comments before docstring, token is %r 
(%s)",
+                           self.current.kind, self.current.value)
+
+            if skipped_error_codes:
+                break
+
         return skipped_error_codes
 
     def check_current(self, kind=None, value=None):
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/pydocstyle-5.0.2/src/pydocstyle/utils.py 
new/pydocstyle-5.1.1/src/pydocstyle/utils.py
--- old/pydocstyle-5.0.2/src/pydocstyle/utils.py        2020-01-08 
13:37:01.000000000 +0100
+++ new/pydocstyle-5.1.1/src/pydocstyle/utils.py        2020-08-29 
22:52:53.000000000 +0200
@@ -7,7 +7,7 @@
 
 
 # Do not update the version manually - it is managed by `bumpversion`.
-__version__ = '5.0.2'
+__version__ = '5.1.1'
 log = logging.getLogger(__name__)
 
 #: Regular expression for stripping non-alphanumeric characters
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/pydocstyle-5.0.2/src/pydocstyle/wordlists.py 
new/pydocstyle-5.1.1/src/pydocstyle/wordlists.py
--- old/pydocstyle-5.0.2/src/pydocstyle/wordlists.py    2020-01-08 
13:37:01.000000000 +0100
+++ new/pydocstyle-5.1.1/src/pydocstyle/wordlists.py    2020-08-29 
22:52:53.000000000 +0200
@@ -35,8 +35,8 @@
                 yield line
 
 
-#: A dict mapping stemmed verbs to the imperative form
 def make_imperative_verbs_dict(wordlist: Iterator[str]) -> Dict[str, Set[str]]:
+    """Create a dictionary mapping stemmed verbs to the imperative form."""
     imperative_verbs = {}  # type: Dict[str, Set[str]]
     for word in wordlist:
         imperative_verbs.setdefault(stem(word), set()).add(word)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/pydocstyle-5.0.2/src/tests/parser_test.py 
new/pydocstyle-5.1.1/src/tests/parser_test.py
--- old/pydocstyle-5.0.2/src/tests/parser_test.py       2020-01-08 
13:37:01.000000000 +0100
+++ new/pydocstyle-5.1.1/src/tests/parser_test.py       2020-08-29 
22:52:53.000000000 +0200
@@ -4,6 +4,7 @@
 import sys
 import pytest
 import textwrap
+from pathlib import Path
 
 from pydocstyle.parser import Parser, ParseError
 
@@ -562,19 +563,75 @@
     assert inner_function.decorators[0].name == 'a'
 
 
-def test_module_publicity():
-    """Test that a module that has a single leading underscore is private."""
[email protected]("public_path", (
+    Path(""),
+    Path("module.py"),
+    Path("package") / "module.py",
+    Path("package") / "__init__.py",
+    Path("") / "package" / "module.py",
+    Path("") / "__dunder__" / "package" / "module.py"
+))
+def test_module_publicity_with_public_path(public_path):
+    """Test module publicity with public path.
+
+    Module names such as my_module.py are considered public.
+
+    Special "dunder" modules,
+    with leading and trailing double-underscores (e.g. __init__.py) are public.
+
+    The same rules for publicity apply to both packages and modules.
+    """
     parser = Parser()
     code = CodeSnippet("")
-
-    module = parser.parse(code, "filepath")
+    module = parser.parse(code, str(public_path))
     assert module.is_public
 
-    module = parser.parse(code, "_filepath")
+
[email protected]("private_path", (
+    # single underscore
+    Path("_private_module.py"),
+    Path("_private_package") / "module.py",
+    Path("_private_package") / "package" / "module.py",
+    Path("") / "_private_package" / "package" / "module.py",
+
+    # double underscore
+    Path("__private_module.py"),
+    Path("__private_package") / "module.py",
+    Path("__private_package") / "package" / "module.py",
+    Path("") / "__private_package" / "package" / "module.py"
+))
+def test_module_publicity_with_private_paths(private_path):
+    """Test module publicity with private path.
+
+    Module names starting with single or double-underscore are private.
+    For example, _my_private_module.py and __my_private_module.py.
+
+    Any module within a private package is considered private.
+
+    The same rules for publicity apply to both packages and modules.
+    """
+    parser = Parser()
+    code = CodeSnippet("")
+    module = parser.parse(code, str(private_path))
     assert not module.is_public
 
-    module = parser.parse(code, "__filepath")
-    assert module.is_public
+
[email protected]("syspath,is_public", (
+    ("/", False),
+    ("_foo/", True),
+))
+def test_module_publicity_with_different_sys_path(syspath,
+                                                  is_public,
+                                                  monkeypatch):
+    """Test module publicity for same path and different sys.path."""
+    parser = Parser()
+    code = CodeSnippet("")
+
+    monkeypatch.syspath_prepend(syspath)
+
+    path = Path("_foo") / "bar" / "baz.py"
+    module = parser.parse(code, str(path))
+    assert module.is_public == is_public
 
 
 def test_complex_module():
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/pydocstyle-5.0.2/src/tests/test_cases/expected.py 
new/pydocstyle-5.1.1/src/tests/test_cases/expected.py
--- old/pydocstyle-5.0.2/src/tests/test_cases/expected.py       2020-01-08 
13:37:01.000000000 +0100
+++ new/pydocstyle-5.1.1/src/tests/test_cases/expected.py       2020-08-29 
22:52:53.000000000 +0200
@@ -4,13 +4,13 @@
     def __init__(self):
         self.expected = set()
 
-    def expect(self, *args, arg_count=0):
+    def expect(self, *args, arg_count=0, func_name=""):
         """Decorator that expects a certain PEP 257 violation."""
         # The `arg_count` parameter helps the decorator
         # with functions that have positional arguments.
         if len(args) == 1:
             def decorate(f):
-                self.expected.add((f.__name__, args[0]))
+                self.expected.add((func_name or f.__name__, args[0]))
                 f(*[None]*arg_count)
                 return f
             return decorate
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/pydocstyle-5.0.2/src/tests/test_cases/functions.py 
new/pydocstyle-5.1.1/src/tests/test_cases/functions.py
--- old/pydocstyle-5.0.2/src/tests/test_cases/functions.py      2020-01-08 
13:37:01.000000000 +0100
+++ new/pydocstyle-5.1.1/src/tests/test_cases/functions.py      2020-08-29 
22:52:53.000000000 +0200
@@ -29,6 +29,15 @@
     pass
 
 
+def func_with_inner_async_func_after():
+    """Test a function with inner async function after docstring."""
+
+    async def inner():
+        pass
+
+    pass
+
+
 def fake_decorator(decorated):
     """Fake decorator used to test decorated inner func."""
     return decorated
@@ -44,6 +53,16 @@
     pass
 
 
+def func_with_inner_decorated_async_func_after():
+    """Test a function with inner decorated async function after docstring."""
+
+    @fake_decorator
+    async def inner():
+        pass
+
+    pass
+
+
 def func_with_inner_class_after():
     """Test a function with inner class after docstring."""
 
@@ -51,3 +70,8 @@
         pass
 
     pass
+
+
+def func_with_weird_backslash():
+    """Test a function with a weird backslash.\
+"""
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/pydocstyle-5.0.2/src/tests/test_cases/noqa.py 
new/pydocstyle-5.1.1/src/tests/test_cases/noqa.py
--- old/pydocstyle-5.0.2/src/tests/test_cases/noqa.py   2020-01-08 
13:37:01.000000000 +0100
+++ new/pydocstyle-5.1.1/src/tests/test_cases/noqa.py   2020-08-29 
22:52:53.000000000 +0200
@@ -1,3 +1,4 @@
+# -*- coding: utf-8 -*-
 # noqa: D400,D415
 """Test case for "# noqa" comments"""
 from .expected import Expectation
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/pydocstyle-5.0.2/src/tests/test_cases/sections.py 
new/pydocstyle-5.1.1/src/tests/test_cases/sections.py
--- old/pydocstyle-5.0.2/src/tests/test_cases/sections.py       2020-01-08 
13:37:01.000000000 +0100
+++ new/pydocstyle-5.1.1/src/tests/test_cases/sections.py       2020-08-29 
22:52:53.000000000 +0200
@@ -274,11 +274,30 @@
     """
 
 
+@expect("D417: Missing argument descriptions in the docstring "
+        "(argument(s) y are missing descriptions in "
+        "'bar' docstring)", func_name="bar")
+def _test_nested_functions():
+    x = 1
+
+    def bar(y=2):  # noqa: D207, D213, D406, D407
+        """Nested function test for docstrings.
+
+        Will this work when referencing x?
+
+        Args:
+            x: Test something
+that is broken.
+
+        """
+        print(x)
+
+
 @expect(_D213)
 @expect("D417: Missing argument descriptions in the docstring "
         "(argument(s) y are missing descriptions in "
         "'test_missing_google_args' docstring)")
-def test_missing_google_args(x=1, y=2):  # noqa: D406, D407
+def test_missing_google_args(x=1, y=2, _private=3):  # noqa: D406, D407
     """Toggle the gizmo.
 
     Args:
@@ -290,7 +309,7 @@
 class TestGoogle:  # noqa: D203
     """Test class."""
 
-    def test_method(self, test, another_test):  # noqa: D213, D407
+    def test_method(self, test, another_test, _):  # noqa: D213, D407
         """Test a valid args section.
 
         Args:
@@ -301,8 +320,8 @@
 
     @expect("D417: Missing argument descriptions in the docstring "
             "(argument(s) test, y, z are missing descriptions in "
-            "'test_missing_args' docstring)", arg_count=4)
-    def test_missing_args(self, test, x, y, z=3):  # noqa: D213, D407
+            "'test_missing_args' docstring)", arg_count=5)
+    def test_missing_args(self, test, x, y, z=3, _private_arg=3):  # noqa: 
D213, D407
         """Test a valid args section.
 
         Args:
@@ -313,8 +332,8 @@
     @classmethod
     @expect("D417: Missing argument descriptions in the docstring "
             "(argument(s) test, y, z are missing descriptions in "
-            "'test_missing_args_class_method' docstring)", arg_count=4)
-    def test_missing_args_class_method(cls, test, x, y, z=3):  # noqa: D213, 
D407
+            "'test_missing_args_class_method' docstring)", arg_count=5)
+    def test_missing_args_class_method(cls, test, x, y, _, z=3):  # noqa: 
D213, D407
         """Test a valid args section.
 
         Args:
@@ -326,8 +345,8 @@
     @staticmethod
     @expect("D417: Missing argument descriptions in the docstring "
             "(argument(s) a, y, z are missing descriptions in "
-            "'test_missing_args_static_method' docstring)", arg_count=3)
-    def test_missing_args_static_method(a, x, y, z=3):  # noqa: D213, D407
+            "'test_missing_args_static_method' docstring)", arg_count=4)
+    def test_missing_args_static_method(a, x, y, _test, z=3):  # noqa: D213, 
D407
         """Test a valid args section.
 
         Args:
@@ -335,18 +354,49 @@
 
         """
 
+    @staticmethod
+    @expect("D417: Missing argument descriptions in the docstring "
+            "(argument(s) a, b are missing descriptions in "
+            "'test_missing_docstring' docstring)", arg_count=2)
+    def test_missing_docstring(a, b):  # noqa: D213, D407
+        """Test a valid args section.
+
+        Args:
+            a:
+
+        """
+
+    @staticmethod
+    @expect("D417: Missing argument descriptions in the docstring "
+            "(argument(s) skip, verbose are missing descriptions in "
+            "'test_missing_docstring_another' docstring)", arg_count=2)
+    def test_missing_docstring_another(skip, verbose):  # noqa: D213, D407
+        """Do stuff.
+
+        Args:
+            skip (:attr:`.Skip`):
+                Lorem ipsum dolor sit amet, consectetur adipiscing elit.
+                Etiam at tellus a tellus faucibus maximus. Curabitur tellus
+                mauris, semper id vehicula ac, feugiat ut tortor.
+            verbose (bool):
+                If True, print out as much infromation as possible.
+                If False, print out concise "one-liner" information.
+
+        """
+
 
 @expect(_D213)
 @expect("D417: Missing argument descriptions in the docstring "
         "(argument(s) y are missing descriptions in "
         "'test_missing_numpy_args' docstring)")
-def test_missing_numpy_args(x=1, y=2):  # noqa: D406, D407
+def test_missing_numpy_args(_private_arg=0, x=1, y=2):  # noqa: D406, D407
     """Toggle the gizmo.
 
     Parameters
     ----------
     x : int
-        The greatest integer.
+        The greatest integer in the history \
+of the entire world.
 
     """
 
@@ -354,13 +404,19 @@
 class TestNumpy:  # noqa: D203
     """Test class."""
 
-    def test_method(self, test, another_test, x=1, y=2):  # 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.
 
@@ -368,8 +424,8 @@
 
     @expect("D417: Missing argument descriptions in the docstring "
             "(argument(s) test, y, z are missing descriptions in "
-            "'test_missing_args' docstring)", arg_count=4)
-    def test_missing_args(self, test, x, y, z=3, t=1):  # noqa: D213, D407
+            "'test_missing_args' docstring)", arg_count=5)
+    def test_missing_args(self, test, x, y, z=3, t=1, _private=0):  # noqa: 
D213, D407
         """Test a valid args section.
 
         Parameters
@@ -425,3 +481,20 @@
             Zoneeeeee!
 
         """
+
+
+class TestIncorrectIndent:  # noqa: D203
+    """Test class."""
+
+    @expect("D417: Missing argument descriptions in the docstring "
+            "(argument(s) y are missing descriptions in "
+            "'test_incorrect_indent' docstring)", arg_count=3)
+    def test_incorrect_indent(self, x=1, y=2):  # noqa: D207, D213, D407
+        """Reproducing issue #437.
+
+Testing this incorrectly indented docstring.
+
+        Args:
+            x: Test argument.
+
+        """
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/pydocstyle-5.0.2/src/tests/test_integration.py 
new/pydocstyle-5.1.1/src/tests/test_integration.py
--- old/pydocstyle-5.0.2/src/tests/test_integration.py  2020-01-08 
13:37:01.000000000 +0100
+++ new/pydocstyle-5.1.1/src/tests/test_integration.py  2020-08-29 
22:52:53.000000000 +0200
@@ -150,10 +150,9 @@
 def test_pep257_conformance():
     """Test that we conform to PEP 257."""
     base_dir = (pathlib.Path(__file__).parent / '..').resolve()
-    src_dirs = (base_dir, base_dir / 'tests')
-    src_files = []
-    for src_dir in src_dirs:
-        src_files.extend(str(path) for path in src_dir.glob('*.py'))
+    excluded = base_dir / 'tests' / 'test_cases'
+    src_files = (str(path) for path in base_dir.glob('**/*.py')
+                 if excluded not in path.parents)
 
     ignored = {'D104', 'D105'}
     select = violations.conventions.pep257 - ignored
@@ -1124,3 +1123,70 @@
     out, err, code = env.invoke(args="-v")
     assert code == 0
     assert "IndentationError: unexpected indent" not in err
+
+
+def test_only_comment_file(env):
+    """Test that file with only comments does only cause D100."""
+    with env.open('comments.py', 'wt') as comments:
+        comments.write(
+            '#!/usr/bin/env python3\n'
+            '# -*- coding: utf-8 -*-\n'
+            '# Useless comment\n'
+            '# Just another useless comment\n'
+        )
+
+    out, _, code = env.invoke()
+    assert 'D100' in out
+    out = out.replace('D100', '')
+    for err in {'D1', 'D2', 'D3', 'D4'}:
+        assert err not in out
+    assert code == 1
+
+
+def test_comment_plus_docstring_file(env):
+    """Test that file with comments and docstring does not cause errors."""
+    with env.open('comments_plus.py', 'wt') as comments_plus:
+        comments_plus.write(
+            '#!/usr/bin/env python3\n'
+            '# -*- coding: utf-8 -*-\n'
+            '# Useless comment\n'
+            '# Just another useless comment\n'
+            '"""Module docstring."""\n'
+        )
+
+    out, _, code = env.invoke()
+    assert '' == out
+    assert code == 0
+
+
+def test_only_comment_with_noqa_file(env):
+    """Test that file with noqa and only comments does not cause errors."""
+    with env.open('comments.py', 'wt') as comments:
+        comments.write(
+            '#!/usr/bin/env python3\n'
+            '# -*- coding: utf-8 -*-\n'
+            '# Useless comment\n'
+            '# Just another useless comment\n'
+            '# noqa: D100\n'
+        )
+
+    out, _, code = env.invoke()
+    assert 'D100' not in out
+    assert code == 0
+
+
+def test_comment_with_noqa_plus_docstring_file(env):
+    """Test that file with comments, noqa, docstring does not cause errors."""
+    with env.open('comments_plus.py', 'wt') as comments_plus:
+        comments_plus.write(
+            '#!/usr/bin/env python3\n'
+            '# -*- coding: utf-8 -*-\n'
+            '# Useless comment\n'
+            '# Just another useless comment\n'
+            '# noqa: D400\n'
+            '"""Module docstring without period"""\n'
+        )
+
+    out, _, code = env.invoke()
+    assert '' == out
+    assert code == 0
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/pydocstyle-5.0.2/tox.ini new/pydocstyle-5.1.1/tox.ini
--- old/pydocstyle-5.0.2/tox.ini        2020-01-08 13:37:01.000000000 +0100
+++ new/pydocstyle-5.1.1/tox.ini        2020-08-29 22:52:53.000000000 +0200
@@ -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 @@
     -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 =


Reply via email to