A Python docstring linter that checks arguments, returns, yields, and raises sections
npx @tessl/cli install tessl/pypi-pydoclint@0.7.0A high-performance Python docstring linter that validates docstring sections (arguments, returns, raises, yields) against function signatures and implementations. Pydoclint supports three major docstring styles (NumPy, Google, and Sphinx) and can run thousands of times faster than similar tools like darglint, making it suitable for large codebases.
pip install pydoclintpip install pydoclint[flake8]import pydoclintFor programmatic usage:
# Main entry points
from pydoclint.main import main, _checkFile, _checkPaths
from pydoclint.visitor import Visitor
from pydoclint.utils.violation import Violation
# Utility classes for argument and docstring handling
from pydoclint.utils.arg import Arg, ArgList
from pydoclint.utils.doc import Doc
from pydoclint.utils.parse_docstring import parseDocstring
# AST analysis utilities
from pydoclint.utils.return_yield_raise import (
hasReturnAnnotation, hasYieldStatements, hasRaiseStatements
)
from pydoclint.utils.generic import collectFuncArgs, getDocstring
# Package version
import pydoclint
print(pydoclint.__version__)For flake8 integration (automatic):
# The plugin is automatically available after installation
# No explicit import needed - use via flake8 command line# Check a single Python file
pydoclint myfile.py
# Check multiple files with specific style
pydoclint --style=google src/*.py
# Check with custom configuration
pydoclint --config=pyproject.toml --exclude="tests/" src/
# Generate baseline for gradual adoption
pydoclint --generate-baseline --baseline=violations.txt src/
pydoclint --baseline=violations.txt src/ # Only report new violations# Use as flake8 plugin (DOC error codes)
flake8 --select=DOC src/
# Configure in setup.cfg or pyproject.toml
[flake8]
select = DOC
style = numpyfrom pathlib import Path
from pydoclint.main import _checkFile
from pydoclint.visitor import Visitor
import ast
# Check a single file
violations = _checkFile(
Path("myfile.py"),
style="numpy",
checkArgOrder=True,
checkReturnTypes=True
)
# Use visitor directly for custom analysis
with open("myfile.py") as f:
source = f.read()
tree = ast.parse(source)
visitor = Visitor(style="google", checkClassAttributes=True)
visitor.visit(tree)
violations = visitor.violations
# Process violations
for violation in violations:
print(f"Line {violation.line}: {violation.fullErrorCode} - {violation.msg}")Pydoclint's architecture is built around several key components:
Complete command-line tool for docstring linting with extensive configuration options, style detection, and baseline management for gradual adoption in large codebases.
def main(
ctx: click.Context,
quiet: bool,
exclude: str,
style: str,
paths: tuple[str, ...],
# ... extensive configuration parameters
) -> None: ...
def validateStyleValue(
context: click.Context,
param: click.Parameter,
value: str | None,
) -> str | None: ...Seamless integration with flake8 linting workflow, providing docstring validation as part of standard Python code quality checks with DOC error codes.
class Plugin:
name: str
version: str
def __init__(self, tree: ast.AST) -> None: ...
@classmethod
def add_options(cls, parser: Any) -> None: ...
@classmethod
def parse_options(cls, options: Any) -> None: ...
def run(self) -> Generator[tuple[int, int, str, Any], None, None]: ...AST-based analysis engine that traverses Python code to validate docstring compliance against function signatures, with support for all docstring styles and comprehensive validation rules.
class Visitor(ast.NodeVisitor):
def __init__(
self,
style: str = 'numpy',
argTypeHintsInSignature: bool = True,
argTypeHintsInDocstring: bool = True,
checkArgOrder: bool = True,
checkReturnTypes: bool = True,
checkYieldTypes: bool = True,
checkClassAttributes: bool = True,
# ... many more configuration options
) -> None: ...
def visit(self, node: ast.AST) -> None: ...
@property
def violations(self) -> list[Violation]: ...TOML-based configuration system with support for pyproject.toml integration and command-line overrides, enabling flexible project-specific setup.
def injectDefaultOptionsFromUserSpecifiedTomlFilePath(
ctx: click.Context,
param: click.Parameter,
value: str | None,
) -> str | None: ...
def parseToml(paths: Sequence[str] | None) -> dict[str, Any]: ...
def parseOneTomlFile(tomlFilename: Path) -> dict[str, Any]: ...Support for baseline files that enable gradual adoption of pydoclint in large codebases by tracking existing violations and only reporting new ones.
def generateBaseline(
violationsAllFiles: dict[str, list[Violation]] | dict[str, list[str]],
path: Path,
) -> None: ...
def parseBaseline(path: Path) -> dict[str, list[str]]: ...
def reEvaluateBaseline(
baseline: dict[str, list[str]],
actualViolationsInAllFiles: dict[str, list[Violation]],
) -> tuple[bool, dict[str, list[str]], dict[str, list[Violation]]]: ...Comprehensive violation reporting system with specific error codes (DOC0xx-DOC6xx) covering all categories of docstring issues, from formatting to argument mismatches.
class Violation:
code: int
line: int
msg: str
msgPostfix: str
def __init__(
self,
code: int,
line: int = 0,
msgPrefix: str = '',
msgPostfix: str = '',
) -> None: ...
@property
def fullErrorCode(self) -> str: ...
def getInfoForFlake8(self) -> tuple[int, int, str]: ...
VIOLATION_CODES: dict[int, str]Comprehensive utility classes and functions for programmatic docstring analysis, including argument handling, AST processing, and docstring parsing.
class Arg:
name: str
typeHint: str
def __init__(self, name: str, typeHint: str) -> None: ...
def nameEquals(self, other: 'Arg') -> bool: ...
def hasTypeHint(self) -> bool: ...
def isStarArg(self) -> bool: ...
@classmethod
def fromDocstringParam(cls, param: DocstringParam) -> 'Arg': ...
@classmethod
def fromAstArg(cls, astArg: ast.arg) -> 'Arg': ...
class ArgList:
infoList: list[Arg]
def __init__(self, infoList: list[Arg]) -> None: ...
def length(self) -> int: ...
def equals(self, other: 'ArgList') -> bool: ...
def subtract(self, other: 'ArgList') -> 'ArgList': ...
class Doc:
def __init__(self, docstring: str, style: str = 'numpy') -> None: ...
@property
def isShortDocstring(self) -> bool: ...
@property
def argList(self) -> ArgList: ...
@property
def hasReturnsSection(self) -> bool: ...
@property
def hasYieldsSection(self) -> bool: ...
# AST analysis functions
def hasReturnAnnotation(node: FuncOrAsyncFuncDef) -> bool: ...
def hasYieldStatements(node: FuncOrAsyncFuncDef) -> bool: ...
def hasRaiseStatements(node: FuncOrAsyncFuncDef) -> bool: ...
def collectFuncArgs(node: FuncOrAsyncFuncDef) -> list[ast.arg]: ...
def parseDocstring(docstring: str, style: str) -> Doc | None: ...# Package metadata
__version__: str # Package version string from metadata# CLI entry point (installed as 'pydoclint' command)
# Defined in pyproject.toml: pydoclint = "pydoclint.main:main"
# Flake8 plugin entry point (DOC error codes)
# Defined in pyproject.toml: DOC = "pydoclint.flake8_entry:Plugin"# Core data types
class Violation:
code: int
line: int
msg: str
msgPostfix: str
fullErrorCode: str
class Visitor(ast.NodeVisitor):
violations: list[Violation]
# Utility data types
class Arg:
name: str
typeHint: str
class ArgList:
infoList: list[Arg]
class Doc:
"""Parsed docstring representation"""
pass
@dataclass
class ReturnArg:
type: str
description: str
@dataclass
class YieldArg:
type: str
description: str
# AST node unions
FuncOrAsyncFuncDef = Union[ast.FunctionDef, ast.AsyncFunctionDef]
ClassOrFunctionDef = Union[ast.ClassDef, ast.FunctionDef, ast.AsyncFunctionDef]
# Enumerations
class MethodType(Enum):
FUNCTION = "function"
METHOD = "method"
CLASSMETHOD = "classmethod"
STATICMETHOD = "staticmethod"
PROPERTY = "property"
# Configuration types
ConfigDict = dict[str, Any]
ViolationsDict = dict[str, list[Violation]]
BaselineDict = dict[str, list[str]]
# Custom exceptions
class EdgeCaseError(Exception):
"""Exception for edge cases in analysis"""
pass
# External types from dependencies
DocstringParam = Any # From docstring_parser_fork
DocstringAttr = Any # From docstring_parser_fork