Validation#

Docstring Validation using Pre-Commit Hook#

To enable validation of docstrings as you commit files, add the following to your .pre-commit-config.yaml file:

- repo: https://github.com/numpy/numpydoc
  rev: <version>
  hooks:
    - id: numpydoc-validation

After installing numpydoc, run the following to see available command line options for this hook:

$ python -m numpydoc.hooks.validate_docstrings --help

Using a config file provides additional customization. Both pyproject.toml and setup.cfg are supported; however, if the project contains both you must use the pyproject.toml file. The example below configures the pre-commit hook as follows:

  • checks: Report findings on all checks except EX01, SA01, and ES01 (using the same logic as the validation during Sphinx build for numpydoc_validation_checks).

  • exclude: Don’t report issues on objects matching any of the regular regular expressions \.undocumented_method$ or \.__repr__$. This maps to numpydoc_validation_exclude from the Sphinx build configuration.

  • override_SS05: Allow docstrings to start with “Process “, “Assess “, or “Access “. To override different checks, add a field for each code in the form of override_<code> with a collection of regular expression(s) to search for in the contents of a docstring, not the object name. This maps to numpydoc_validation_overrides from the Sphinx build configuration.

pyproject.toml:

[tool.numpydoc_validation]
checks = [
    "all",   # report on all checks, except the below
    "EX01",
    "SA01",
    "ES01",
]
exclude = [  # don't report on objects that match any of these regex
    '\.undocumented_method$',
    '\.__repr__$',
]
override_SS05 = [  # override SS05 to allow docstrings starting with these words
    '^Process ',
    '^Assess ',
    '^Access ',
]

setup.cfg:

[tool:numpydoc_validation]
checks = all,EX01,SA01,ES01
exclude = \.undocumented_method$,\.__repr__$
override_SS05 = ^Process ,^Assess ,^Access ,

In addition to the above, inline ignore comments can be used to ignore findings on a case by case basis.

If any issues are found when committing, a report is printed out, and the commit is halted:

numpydoc-validation......................................................Failed
- hook id: numpydoc-validation
- exit code: 1

+----------------------+----------------------+---------+--------------------------------------+
| file                 | item                 | check   | description                          |
+======================+======================+=========+======================================+
| src/pkg/utils.py:1   | utils                | GL08    | The object does not have a docstring |
| src/pkg/utils.py:90  | utils.normalize      | PR04    | Parameter "field" has no type        |
| src/pkg/module.py:12 | module.MyClass       | GL08    | The object does not have a docstring |
| src/pkg/module.py:33 | module.MyClass.parse | RT03    | Return value has no description      |
+----------------------+----------------------+---------+--------------------------------------+

See below for a full listing of checks.

Docstring Validation using Python#

To see the Restructured Text generated for an object, the numpydoc module can be called. For example, to do it for numpy.ndarray, use:

$ python -m numpydoc numpy.ndarray

This will validate that the docstring can be built.

For an exhaustive validation of the formatting of the docstring, use the --validate parameter. This will report the errors detected, such as incorrect capitalization, wrong order of the sections, and many other issues. Note that this will honor inline ignore comments, but will not look for any configuration like the pre-commit hook or Sphinx extension do.

Docstring Validation during Sphinx Build#

It is also possible to run docstring validation as part of the Sphinx build process. This behavior is controlled by the numpydoc_validation_checks configuration parameter in conf.py. For example, to verify that all of the parameters in the function signature are accounted for in the Parameters section of the docstring, add the following line to conf.py:

numpydoc_validation_checks = {"PR01"}

This will cause a Sphinx warning to be raised for any (non-module) docstring that has undocumented parameters in the signature. The full set of validation checks can be activated by:

numpydoc_validation_checks = {"all"}

The complete validation suite contains many checks including some for style, capitalization, and grammar. It is unlikely that reporting all validation warnings is desirable for most use-cases. Individual checks can be excluded by including them in the set with the special keyword "all":

# Report warnings for all validation checks except GL01, GL02, and GL05
numpydoc_validation_checks = {"all", "GL01", "GL02", "GL05"}

In addition, you can exclude any findings on certain objects with numpydoc_validation_exclude, which maps to exclude in the pre-commit hook setup:

# don't report on objects that match any of these regex
numpydoc_validation_exclude = [
    '\.undocumented_method$',
    '\.__repr__$',
]

Overrides based on docstring contents are also supported, but the structure is slightly different than the pre-commit hook setup:

numpydoc_validation_overrides = {
    "SS02": [  # override SS05 to allow docstrings starting with these words
        '^Process ',
        '^Assess ',
        '^Access ',
    ]
}

Ignoring Validation Checks with Inline Comments#

Sometimes you only want to ignore a specific check or set of checks for a specific piece of code. This level of fine-tuned control is provided via inline comments:

class SomeClass:  # numpydoc ignore=EX01,SA01,ES01
    """This is the docstring for SomeClass."""

    def __init__(self):  # numpydoc ignore=GL08
        pass

This is supported by the CLI, pre-commit hook, and Sphinx extension.

Built-in Validation Checks#

The numpydoc.validation module provides a mapping with all of the checks that are run as part of the validation procedure. The mapping is of the form: error_code : <explanation> where error_code provides a shorthand for the check being run, and <explanation> provides a more detailed message. For example:

"EX01" : "No examples section found"

The full mapping of validation checks is given below.

ERROR_MSGS = {
    "GL01": "Docstring text (summary) should start in the line immediately "
    "after the opening quotes (not in the same line, or leaving a "
    "blank line in between)",
    "GL02": "Closing quotes should be placed in the line after the last text "
    "in the docstring (do not close the quotes in the same line as "
    "the text, or leave a blank line between the last text and the "
    "quotes)",
    "GL03": "Double line break found; please use only one blank line to "
    "separate sections or paragraphs, and do not leave blank lines "
    "at the end of docstrings",
    "GL05": 'Tabs found at the start of line "{line_with_tabs}", please use '
    "whitespace only",
    "GL06": 'Found unknown section "{section}". Allowed sections are: '
    "{allowed_sections}",
    "GL07": "Sections are in the wrong order. Correct order is: {correct_sections}",
    "GL08": "The object does not have a docstring",
    "GL09": "Deprecation warning should precede extended summary",
    "GL10": "reST directives {directives} must be followed by two colons",
    "SS01": "No summary found (a short summary in a single line should be "
    "present at the beginning of the docstring)",
    "SS02": "Summary does not start with a capital letter",
    "SS03": "Summary does not end with a period",
    "SS04": "Summary contains heading whitespaces",
    "SS05": "Summary must start with infinitive verb, not third person "
    '(e.g. use "Generate" instead of "Generates")',
    "SS06": "Summary should fit in a single line",
    "ES01": "No extended summary found",
    "PR01": "Parameters {missing_params} not documented",
    "PR02": "Unknown parameters {unknown_params}",
    "PR03": "Wrong parameters order. Actual: {actual_params}. "
    "Documented: {documented_params}",
    "PR04": 'Parameter "{param_name}" has no type',
    "PR05": 'Parameter "{param_name}" type should not finish with "."',
    "PR06": 'Parameter "{param_name}" type should use "{right_type}" instead '
    'of "{wrong_type}"',
    "PR07": 'Parameter "{param_name}" has no description',
    "PR08": 'Parameter "{param_name}" description should start with a '
    "capital letter",
    "PR09": 'Parameter "{param_name}" description should finish with "."',
    "PR10": 'Parameter "{param_name}" requires a space before the colon '
    "separating the parameter name and type",
    "RT01": "No Returns section found",
    "RT02": "The first line of the Returns section should contain only the "
    "type, unless multiple values are being returned",
    "RT03": "Return value has no description",
    "RT04": "Return value description should start with a capital letter",
    "RT05": 'Return value description should finish with "."',
    "YD01": "No Yields section found",
    "SA01": "See Also section not found",
    "SA02": "Missing period at end of description for See Also "
    '"{reference_name}" reference',
    "SA03": "Description should be capitalized for See Also "
    '"{reference_name}" reference',
    "SA04": 'Missing description for See Also "{reference_name}" reference',
    "EX01": "No examples section found",
}