pydoclint

Notes for users


Table of Contents


1. Cases that pydoclint is not designed to handle

pydoclint uses a static syntax analyzer (Python’s official AST module) to analyze the incoming Python source code, and docstring_parser_fork to parse docstrings. It never imports or runs your code.

The static syntax analysis is very fast because it doesn’t execute or evaluate any code. For example, this piece of Python code is not runnable:

a = b

because b is not defined. But the static syntax analyzer does not “know” this: it doesn’t need to “know” this to analyze the syntactic structure of a = b.

As a result, pydoclint is not designed to handle cases where Pythonic naming conventions are broken, such as:

hello = classmethod

class MyClass:
    @hello
    def myClassMethod(cls):
        pass
class MyClass:
    def myMethod(hello, arg1):  # the 1st argument is `self` by convention
        pass

    @classmethod
    def myClassMethod(hey, arg2):  # the 1st argument is `cls` by convention
        pass
from typing import List as hello
from typing import Optional as world

def myFunc(arg1: hello[int], arg2: world[str]) -> None:
    """
    An example function.

    pydoclint expects consistency between signature type annotation (`hello[int]`)
    and docstring type annotation (`List[int]`).

    Parameters
    ----------
    arg1 : List[int]
        Arg 1
    arg2 : world[str]
        Arg 2
    """
    print(arg1, arg2)

The authors of pydoclint feel that this is a sensible design choice to achieve and maintain pydoclint’s speed.

2. Notes on writing type hints

As mentioned in Section 1 above, pydoclint uses static syntax analysis. As a result, it cannot really “know” that these type annotations are in fact equivalent:

Type annotation Equivalent version
Optional[str] str \| None
Union[str, int] int \| str
Tuple[str, int] tuple[str, int]

Additionally, pydoclint does not recognize some docstring conventions allowed in the docstring style guide, such as using “int, optional” for Optional[int].

Right now, the only way to make pydoclint stop reporting style violations is to make sure the docstring type annotations match the signature type annotations verbatim.

Again, the authors of pydoclint feel that this is a reasonable price to pay in order to achieve fast linting and reduce ambiguity.

3. How to integrate pydoclint with different editors or IDEs

3.1. Integrate pydoclint with Neovim using null-ls

If you use Neovim, you can integrate pydoclint with your editor using the null-ls plugin. null-ls allows you to use linters and formatters in Neovim in a simple and efficient way. First, make sure you have installed null-ls using your preferred package manager. Next, add the following configuration to your Neovim config file to register pydoclint as a diagnostic source:

local null_ls = require("null-ls")

null_ls.setup({
    sources = {
        null_ls.builtins.diagnostics.pydoclint,
    },
})

This will enable pydoclint to provide diagnostic messages for your Python code directly in Neovim. You can further customize the behavior of pydoclint by passing additional options:

local null_ls = require("null-ls")

null_ls.setup({
    sources = {
        null_ls.builtins.diagnostics.pydoclint.with({
            extra_args = {"--style=google", "--check-return-types=False"},
        }),
    },
})

Adjust extra_args based on your preferred pydoclint configuration. With this setup, you can now enjoy the benefits of pydoclint’s fast and comprehensive docstring linting directly within your Neovim editing environment.