epythet.validation.docstrings

Docstring extraction from Python source, without importing anything.

Every level below the build reads docstrings straight from the ast, so the package under validation never has to be importable (and never runs). What autodoc would see is approximated with inspect.cleandoc(), which is what Sphinx’s prepare_docstring does modulo tab expansion.

Each Docstring carries both the processed text (what Python hands to Sphinx) and the literal’s source segment (what the author typed), because one seed rule (DR020, backslashes eaten by a non-raw string) is only visible in the latter.

Functions

count_public_objects(package_dir, *[, ignore])

Count public modules, classes and functions, and those without a docstring.

is_ignored(path, ignore)

Whether path matches the --ignore list: any token is a substring of its POSIX form.

iter_docstrings(package_dir, *[, ignore, ...])

Yield every docstring in a package directory tree.

iter_file_docstrings(path, *[, root, on_skip])

Yield the module, class and function docstrings of one file, in source order.

iter_python_files(package_dir, *[, ignore])

Every .py in the package tree, skipping caches, non-package dirs and ignore substrings.

Classes

Coverage([checked, undocumented])

How many public objects were seen and how many lack a docstring.

Docstring(file, line, def_line, qualname, ...)

One docstring and where it came from.

class epythet.validation.docstrings.Coverage(checked=0, undocumented=0)[source]

Bases: object

How many public objects were seen and how many lack a docstring.

class epythet.validation.docstrings.Docstring(file, line, def_line, qualname, kind, text, source, is_raw)[source]

Bases: object

One docstring and where it came from.

property lines: list[str]

The processed text, split into lines.

epythet.validation.docstrings.count_public_objects(package_dir, *, ignore=())[source]

Count public modules, classes and functions, and those without a docstring.

“Public” means no leading underscore anywhere in the dotted name below the package. Nested functions are counted like any other def.

Return type:

Coverage

epythet.validation.docstrings.is_ignored(path, ignore)[source]

Whether path matches the --ignore list: any token is a substring of its POSIX form.

The one predicate every level uses, so a file the parse level skips is also absent from the lint, coverage and repair results.

Return type:

bool

>>> is_ignored("/p/pkg/tests/test_x.py", ["tests/"]), is_ignored("/p/pkg/x.py", ["tests/"])
(True, False)
epythet.validation.docstrings.iter_docstrings(package_dir, *, ignore=(), on_skip=None)[source]

Yield every docstring in a package directory tree.

Return type:

Iterator[Docstring]

epythet.validation.docstrings.iter_file_docstrings(path, *, root=None, on_skip=None)[source]

Yield the module, class and function docstrings of one file, in source order.

A file that does not parse or decode is skipped; on_skip(path, reason) is called so the caller can report it (a syntax error is the linter’s business, but silence would hide a docstring from the ledger).

Return type:

Iterator[Docstring]

epythet.validation.docstrings.iter_python_files(package_dir, *, ignore=())[source]

Every .py in the package tree, skipping caches, non-package dirs and ignore substrings.

Return type:

Iterator[Path]