Skip to content

ruff not picking up missing docstrings (e.g. D417) #18

Open
@jdeschamps

Description

In my hands ruff never really helped much when it came to docstrings. For instance, I don't get D417. Here is a python class example in a pyrepo copier example:

class MyClass:
    """A class."""

    def __init__(self, myparam: int) -> None:
        """A constructor."""
        self.myparam = myparam

    def mymethod(self, myarg: int) -> int:
        """A method."""
        if myarg < 0:
            raise ValueError("myarg must be positive.")

        return self.myparam * myarg

With ruff only

.pre-commit-config.yaml:

  - repo: https://github.com/charliermarsh/ruff-pre-commit
    rev: v0.1.3
    hooks:
      - id: ruff
        args: [--fix]

pyproject.toml

[tool.ruff]
line-length = 88
target-version = "py38"
src = ["src"]
# https://beta.ruff.rs/docs/rules/
select = [
    "E",    # style errors
    "W",    # style warnings
    "F",    # flakes
    "D",    # pydocstyle
    "I",    # isort
    "UP",   # pyupgrade
    "C4",   # flake8-comprehensions
    "B",    # flake8-bugbear
    "A001", # flake8-builtins
    "RUF",  # ruff-specific rules
]
# I do this to get numpy-style docstrings AND retain
# D417 (Missing argument descriptions in the docstring)
# otherwise, see:
# https://beta.ruff.rs/docs/faq/#does-ruff-support-numpy-or-google-style-docstrings
# https://github.com/charliermarsh/ruff/issues/2606
ignore = [
    "D100", # Missing docstring in public module
    "D107", # Missing docstring in __init__
    "D203", # 1 blank line required before class docstring
    "D212", # Multi-line docstring summary should start at the first line
    "D213", # Multi-line docstring summary should start at the second line
    "D401", # First line should be in imperative mood
    "D413", # Missing blank line after last section
    "D416", # Section name should end with a colon
]

[tool.ruff.pydocstyle]
convention = "numpy"

[tool.ruff.per-file-ignores]
"tests/*.py" = ["D", "S"]
"setup.py" = ["D"]

This is what I get when running pre-commit:

(pydev) ➜  mytest git:(main) ✗ pre-commit run --all
Validate pyproject.toml..................................................Passed
ruff.....................................................................Passed
black....................................................................Passed
mypy.....................................................................Passed

Minimum ruff

pyproject.toml:

[tool.ruff]
line-length = 88
target-version = "py38"
src = ["src"]
# https://beta.ruff.rs/docs/rules/
select = [
    "D", # pydocstyle
]

[tool.ruff.pydocstyle]
convention = "numpy"

Result:

Validate pyproject.toml..................................................Passed
ruff.....................................................................Failed
- hook id: ruff
- exit code: 1

src/my_project/main.py:1:1: D100 Missing docstring in public module
src/my_project/main.py:5:9: D401 First line of docstring should be in imperative mood: "A constructor."
src/my_project/main.py:9:9: D401 First line of docstring should be in imperative mood: "A method."
tests/test_my_project.py:1:1: D100 Missing docstring in public module
tests/test_my_project.py:1:5: D103 Missing docstring in public function
Found 5 errors.

black....................................................................Passed
mypy.....................................................................Passed

With numpydoc (#16)

Adding the following to .pre-commit-config.yaml:

  # check docstrings
  - repo: https://github.com/numpy/numpydoc
    rev: v1.6.0
    hooks:
      - id: numpydoc-validation

And to the pyproject.toml:

# https://numpydoc.readthedocs.io/en/latest/format.html
[tool.numpydoc_validation]
checks = [
    "all",  # report on all checks, except the ones below
    "EX01", # No examples section found
    "SA01", # See Also section not found
    "ES01", # No extended summary found
]
exclude = [ # don't report on objects that match any of these regex
    "test_*",
]
(pydev) ➜  mytest git:(main) ✗ pre-commit run --all
Validate pyproject.toml..................................................Passed
ruff.....................................................................Passed
black....................................................................Passed
mypy.....................................................................Passed
numpydoc-validation......................................................Failed
- hook id: numpydoc-validation
- exit code: 1

+--------------------------+-----------------------+---------+---------------------------------------+
| file                     | item                  | check   | description                           |
+==========================+=======================+=========+=======================================+
| src/my_project/main.py:1 | main                  | GL08    | The object does not have a docstring  |
+--------------------------+-----------------------+---------+---------------------------------------+
| src/my_project/main.py:1 | main.MyClass          | PR01    | Parameters {'myparam'} not documented |
+--------------------------+-----------------------+---------+---------------------------------------+
| src/my_project/main.py:4 | main.MyClass.__init__ | PR01    | Parameters {'myparam'} not documented |
+--------------------------+-----------------------+---------+---------------------------------------+
| src/my_project/main.py:8 | main.MyClass.mymethod | PR01    | Parameters {'myarg'} not documented   |
+--------------------------+-----------------------+---------+---------------------------------------+
| src/my_project/main.py:8 | main.MyClass.mymethod | RT01    | No Returns section found              |
+--------------------------+-----------------------+---------+---------------------------------------+

Note: I used the pyrepo template, but because copier takes the v1.0 tag, I manually updated the pyproject.toml and .pre-commit-config.yaml files (and updated the ruff version).

Any idea what could go wrong with ruff then? If not, I'll open an issue on ruff directly.

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions