Sphinx extension to support docstrings in Numpy format
52
Evaluation — 52%
↑ 1.13xAgent success when using this tile
The numpydoc validation module provides extensive docstring validation functionality with configurable error codes, detailed error messages, and support for both programmatic and command-line validation workflows.
class Validator:
"""
Main docstring validation class with extensive validation methods.
Performs comprehensive validation of NumPy-style docstrings according
to configurable rules, checking formatting, content, structure, and
cross-reference consistency.
Parameters
----------
obj_name : str
Fully qualified name of object to validate (e.g., 'numpy.array')
obj : object, optional
The actual Python object (loaded if not provided)
**kwargs
Additional configuration options
Attributes
----------
obj_name : str
Name of the object being validated
obj : object
The Python object being validated
code : str
Source code of the object
raw_doc : str
Raw docstring content
clean_doc : str
Processed docstring content
doc : NumpyDocString
Parsed docstring object
errors : list of tuple
List of (error_code, message) validation errors
"""The Validator class provides many properties to access different aspects of the parsed docstring and object being validated:
@property
def name(self) -> str:
"""Fully qualified name of the object being validated."""
@property
def type(self) -> str:
"""Type name of the object (e.g., 'function', 'method', 'class')."""
@property
def is_function_or_method(self) -> bool:
"""True if the object is a function or method."""
@property
def is_mod(self) -> bool:
"""True if the object is a module."""
@property
def is_generator_function(self) -> bool:
"""True if the object is a generator function."""
@property
def summary(self) -> str:
"""Summary section of the docstring (single line)."""
@property
def num_summary_lines(self) -> int:
"""Number of lines in the summary section."""
@property
def extended_summary(self) -> str:
"""Extended summary section content."""
@property
def doc_parameters(self) -> Dict:
"""Dictionary of documented parameters from Parameters section."""
@property
def doc_other_parameters(self) -> Dict:
"""Dictionary of documented parameters from Other Parameters section."""
@property
def doc_all_parameters(self) -> Dict:
"""Combined dictionary of all documented parameters."""
@property
def signature_parameters(self) -> Dict:
"""Dictionary of parameters from the function signature."""
@property
def parameter_mismatches(self) -> List:
"""List of parameter mismatches between signature and documentation."""
@property
def see_also(self) -> Dict:
"""See Also section content organized by reference type."""
@property
def examples(self) -> str:
"""Examples section content."""
@property
def returns(self) -> List:
"""Returns section content."""
@property
def yields(self) -> List:
"""Yields section content."""
@property
def deprecated(self) -> bool:
"""True if the object has a deprecation notice."""
@property
def source_file_name(self) -> str:
"""Name of the source file containing the object."""
@property
def source_file_def_line(self) -> int:
"""Line number where the object is defined."""def validate(obj_name, validator_cls=None, **validator_kwargs):
"""
Validate the docstring for a given object name.
Parameters
----------
obj_name : str
The name of the object whose docstring will be evaluated, e.g.
'pandas.read_csv'. The string must include the full, unabbreviated
package/module names, i.e. 'pandas.read_csv', not 'pd.read_csv' or
'read_csv'.
validator_cls : Validator, optional
The Validator class to use. By default, Validator will be used.
**validator_kwargs
Keyword arguments to pass to validator_cls upon initialization.
Note that obj_name will be passed as a named argument as well.
Returns
-------
dict
A dictionary containing all the information obtained from validating
the docstring, including error codes and validation results.
Examples
--------
>>> result = validate('numpy.mean')
>>> if result['errors']:
... print(f"Found {len(result['errors'])} validation issues")
"""def get_validation_checks(validation_checks):
"""
Process validation configuration into standardized format.
Converts validation check specifications (strings, sets, dicts)
into normalized format for use by validators.
Parameters
----------
validation_checks : str, set, or dict
Validation configuration:
- str: 'all' enables all checks, 'none' disables all
- set: Set of specific error codes to check
- dict: Mapping of check names to enabled status
Returns
-------
set
Set of enabled validation check codes
Examples
--------
>>> get_validation_checks('all')
{'GL01', 'GL02', 'GL03', ...}
>>> get_validation_checks({'SS01', 'PR01'})
{'SS01', 'PR01'}
"""def error(code: str, **kwargs) -> str:
"""
Generate error message for validation error code.
Creates formatted error message using the error code template
and provided keyword arguments for parameter substitution.
Parameters
----------
code : str
Error code (e.g., 'GL01', 'SS01', 'PR01')
**kwargs
Parameters for message template substitution
Returns
-------
str
Formatted error message
Examples
--------
>>> error('GL01')
'Docstring text (summary) should start in the line immediately after the opening quotes'
>>> error('PR01', param_name='x')
"No description given for parameter 'x'"
"""
def extract_ignore_validation_comments(lines: List[str]) -> Set[str]:
"""
Extract ignore validation comments from source code lines.
Parses special comments that disable validation for specific
error codes, supporting both inline and block ignore patterns.
Parameters
----------
lines : list of str
Source code lines to scan for ignore comments
Returns
-------
set of str
Set of error codes to ignore during validation
Examples
--------
>>> lines = [
... '# numpydoc ignore=GL01,SS01',
... 'def func():',
... ' pass # numpydoc ignore=PR01'
... ]
>>> extract_ignore_validation_comments(lines)
{'GL01', 'SS01', 'PR01'}
"""def _unwrap(obj):
"""
Traverse obj.__wrapped__ until unwrapped object found.
Handles decorated functions and objects that use __wrapped__
to provide access to the original undecorated object.
Parameters
----------
obj : object
Object to unwrap
Returns
-------
object
Unwrapped object (original if no __wrapped__ attribute)
"""
def _check_desc(desc: List[str], code_no_desc: str, code_no_upper: str,
code_no_period: str, **kwargs) -> List[Tuple[str, str]]:
"""
Validate description content for proper formatting.
Checks description sections for common formatting issues like
missing descriptions, capitalization, and punctuation.
Parameters
----------
desc : list of str
Description lines to validate
code_no_desc : str
Error code for missing description
code_no_upper : str
Error code for improper capitalization
code_no_period : str
Error code for missing period
**kwargs
Additional parameters for error message formatting
Returns
-------
list of tuple
List of (error_code, error_message) validation errors
"""ERROR_MSGS: Dict[str, str]
"""
Dictionary mapping validation error codes to message templates.
Contains templates for all validation error messages with placeholders
for dynamic content like parameter names, section names, etc.
Key error codes include:
- GL01-GL08: General formatting issues
- SS01-SS06: Summary section issues
- ES01: Extended summary issues
- PR01-PR10: Parameter section issues
- RT01-RT05: Returns section issues
- YD01: Yields section issues
- EX01-EX04: Examples section issues
- SA01-SA04: See Also section issues
- """
ALLOWED_SECTIONS: List[str]
"""
List of allowed docstring sections in NumPy format.
Standard sections include: Summary, Extended Summary, Parameters,
Returns, Yields, Other Parameters, Raises, See Also, Notes,
References, Examples, and Attributes.
"""
DIRECTIVES: List[str] = ["versionadded", "versionchanged", "deprecated"]
"""List of allowed reStructuredText directives in docstrings."""
DIRECTIVE_PATTERN: Pattern[str]
"""Regular expression pattern for matching reStructuredText directives."""
IGNORE_STARTS: Tuple[str, ...] = (" ", "* ", "- ")
"""Tuple of line prefixes to ignore during certain validations."""
IGNORE_COMMENT_PATTERN: Pattern[str]
"""Regular expression for matching numpydoc ignore comments."""from numpydoc.validate import validate, Validator
# Validate a function
errors = validate('numpy.array')
for code, message in errors:
print(f"{code}: {message}")
# Use validator class directly
validator = Validator('scipy.stats.norm')
errors = validator.validate()
print(f"Found {len(errors)} validation issues")from numpydoc.validate import Validator, get_validation_checks
# Configure specific checks
checks = get_validation_checks({'GL01', 'SS01', 'PR01'})
validator = Validator('mymodule.func', validation_checks=checks)
errors = validator.validate()
# Validate with all checks enabled
validator = Validator('mymodule.func', validation_checks='all')
errors = validator.validate()from numpydoc.validate import error
# Generate specific error messages
msg = error('GL01')
print(msg) # "Docstring text (summary) should start in the line..."
msg = error('PR01', param_name='x')
print(msg) # "No description given for parameter 'x'"
msg = error('RT02', returned_type='dict')
print(msg) # "The first line of the Returns section should contain only the type, unless multiple values are being returned"from numpydoc.validate import extract_ignore_validation_comments
source_lines = [
'# numpydoc ignore=GL01',
'def my_function(x, y):',
' """Function with validation issues."""',
' pass # numpydoc ignore=PR01,RT01'
]
ignored = extract_ignore_validation_comments(source_lines)
print(ignored) # {'GL01', 'PR01', 'RT01'}# In Sphinx conf.py
numpydoc_validation_checks = {
'all', # Enable all validation
'GL08', # Check specific formatting
'SS01', # Check summary sections
'PR01', # Check parameter documentation
}
numpydoc_validation_exclude = {
r'\.tests\..*', # Exclude test modules
r'.*\._private_func$' # Exclude private functions
}
# Per-object validation overrides
numpydoc_validation_overrides = {
'mypackage.special_func': {'GL01': False}, # Disable GL01 for this function
'mypackage.legacy.*': {'all': False} # Disable all validation for legacy code
}Install with Tessl CLI
npx tessl i tessl/pypi-numpydocevals
scenario-1
scenario-2
scenario-3
scenario-4
scenario-5
scenario-6
scenario-7
scenario-8
scenario-9