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 to ignore three checks and specifies exceptions to the checks SS05 (allow docstrings to start with “Process “, “Assess “, or “Access “) and GL08 (allow the class/method/function with name “__init__” to not have a docstring).

pyproject.toml:

[tool.numpydoc_validation]
ignore = [
    "EX01",
    "SA01",
    "ES01",
]
override_SS05 = '^((Process|Assess|Access) )'
override_GL08 = '^(__init__)$'

setup.cfg:

[tool:numpydoc_validation]
ignore = EX01,SA01,ES01
override_SS05 = ^((Process|Assess|Access) )
override_GL08 = ^(__init__)$

For more fine-tuned control, you can also include inline comments to tell the validation hook to ignore certain checks:

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

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

If any issues are found when commiting, 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.

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"}

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",
}