epythet.validation.coverage

Level 0 coverage and quality smells: the queue signals, computed from the ast alone.

The doc-quality research (research_doc_quality.md §2, §6) defines what the fleet sweep should queue, as opposed to gate: a public callable with no docstring, an entry point with no runnable example, a summary that only restates the name, a parameter description that only restates the type, a summary written as meta-language (“This function…”). None of these needs ruff or pydoclint, so the sweep can run them on a checkout that has neither; none of them changes the exit code unless --fail-on info asks for it.

The public surface follows the R1 decision: __all__ is honoured where present, otherwise every non-underscore name; entry points are the names the package’s __init__ binds (its __all__, else what it defines and imports), and only those owe an example.

Each detector is a function PublicObject -> list[str] registered under the name a coverage-kind ledger rule refers to. The two text heuristics are the research’s, verbatim:

  • trivial summary: split the identifier on snake_case/camelCase, split the summary on whitespace, strip stop words, crude lemmatisation; flag when the summary’s content words are a subset of the name’s;

  • type restatement: flag a parameter description whose content words are a subset of the annotation’s tokens (n: int described as “an integer”).

>>> trivial_summary_words("load_config", "Load the config.")
True
>>> trivial_summary_words("load_config", "Read pyproject.toml and setup.cfg into a DocsConfig.")
False

Functions

annotation_words(annotation)

Words a reader could use to restate an annotation: list[int] -> int, list, integer...

content_words(text)

Content words of prose: lower-cased, stop words out, crudely lemmatised.

coverage_detector(name)

Register a coverage detector under the name a rule's detector.function uses.

entry_point_names(package_dir)

Names the package's __init__ exposes: __all__, else what it binds without a leading underscore.

entry_point_without_example(obj)

An entry point (bound by the package __init__) whose docstring has no >>> (DQ002).

evaluate_coverage_rule(rule, obj)

Run one coverage-kind rule over one public object.

iter_coverage_cases(fixture_path)

The tagged specimens of a coverage fixture (a specimen may have no docstring at all).

iter_public_objects(package_dir, *[, ...])

Every public module, class and function under package_dir.

meta_language_summary(obj)

A summary that talks about the object instead of saying what it does (DQ005).

missing_docstring(obj)

A public module, class or function with no docstring at all (DQ001).

name_words(identifier)

Content words of an identifier: load_config -> {"load", "config"}.

param_descriptions(docstring)

{name: description} from an RST, Google or NumPy docstring, first line plus continuations.

restates_type(param)

Whether a parameter's description only restates its annotation.

run_coverage_level(package_dir, ledger, *[, ...])

Level 0 coverage: (findings, objects_checked, objects_undocumented).

trivial_summary(obj)

A summary whose content words all come from the object's name (DQ003).

trivial_summary_words(identifier, summary)

Whether the summary's content words are all in the identifier's (the lazy smell).

type_restatement(obj)

A parameter description that only restates the annotation (DQ004).

Classes

CoverageCase(name, line, expect_hit, ...)

One tagged specimen of a coverage fixture: the object and what the tag promises.

Param(name[, annotation, description])

A signature parameter and, if the docstring describes it, that description.

PublicObject(qualname, kind, file, line, ...)

One public module, class or function, with what a detector needs to judge it.

class epythet.validation.coverage.CoverageCase(name, line, expect_hit, rule_ids, object)[source]

Bases: object

One tagged specimen of a coverage fixture: the object and what the tag promises.

class epythet.validation.coverage.Param(name, annotation=None, description=None)[source]

Bases: object

A signature parameter and, if the docstring describes it, that description.

class epythet.validation.coverage.PublicObject(qualname, kind, file, line, docstring, params=<factory>, is_entry_point=False, name='')[source]

Bases: object

One public module, class or function, with what a detector needs to judge it.

property summary: str

The first non-blank line of the docstring, or "".

epythet.validation.coverage.annotation_words(annotation)[source]

Words a reader could use to restate an annotation: list[int] -> int, list, integer…

Return type:

set[str]

epythet.validation.coverage.content_words(text)[source]

Content words of prose: lower-cased, stop words out, crudely lemmatised.

Return type:

set[str]

epythet.validation.coverage.coverage_detector(name)[source]

Register a coverage detector under the name a rule’s detector.function uses.

epythet.validation.coverage.entry_point_names(package_dir)[source]

Names the package’s __init__ exposes: __all__, else what it binds without a leading underscore.

Return type:

set[str]

epythet.validation.coverage.entry_point_without_example(obj)[source]

An entry point (bound by the package __init__) whose docstring has no >>> (DQ002).

Return type:

list[str]

epythet.validation.coverage.evaluate_coverage_rule(rule, obj)[source]

Run one coverage-kind rule over one public object.

Return type:

list[str]

epythet.validation.coverage.iter_coverage_cases(fixture_path)[source]

The tagged specimens of a coverage fixture (a specimen may have no docstring at all).

Return type:

Iterator[CoverageCase]

epythet.validation.coverage.iter_public_objects(package_dir, *, ignore=(), files=None, all_entry_points=False)[source]

Every public module, class and function under package_dir.

Public means no leading underscore anywhere in the dotted name below the package; a module’s __all__, when present, narrows its public names. all_entry_points treats every top-level name as an entry point (rule fixtures use it: they have no package __init__).

Return type:

Iterator[PublicObject]

epythet.validation.coverage.meta_language_summary(obj)[source]

A summary that talks about the object instead of saying what it does (DQ005).

Return type:

list[str]

epythet.validation.coverage.missing_docstring(obj)[source]

A public module, class or function with no docstring at all (DQ001).

Return type:

list[str]

epythet.validation.coverage.name_words(identifier)[source]

Content words of an identifier: load_config -> {"load", "config"}.

Return type:

set[str]

>>> sorted(name_words("DocsConfig")), sorted(name_words("mk_parser"))
(['config', 'doc'], ['mk', 'parser'])
epythet.validation.coverage.param_descriptions(docstring)[source]

{name: description} from an RST, Google or NumPy docstring, first line plus continuations.

Deliberately not delegated to docstring_parser (an optional extra): a detector’s verdict must not depend on what is installed.

Return type:

dict[str, str]

>>> param_descriptions(":param n: how many\n    retries\n:param delay: seconds")
{'n': 'how many retries', 'delay': 'seconds'}
>>> param_descriptions("Args:\n    n (int): how many\n    delay: seconds\n\nReturns:\n    x")
{'n': 'how many', 'delay': 'seconds'}
>>> param_descriptions("Parameters\n----------\nn : int\n    how many\ndelay\n    seconds\n\nReturns\n-------")
{'n': 'how many', 'delay': 'seconds'}
epythet.validation.coverage.restates_type(param)[source]

Whether a parameter’s description only restates its annotation.

Return type:

bool

>>> restates_type(Param("n", "int", "an integer"))
True
>>> restates_type(Param("n", "int", "how many retries before giving up"))
False
>>> restates_type(Param("n", None, "an integer"))
False
epythet.validation.coverage.run_coverage_level(package_dir, ledger, *, ignore=())[source]

Level 0 coverage: (findings, objects_checked, objects_undocumented).

Return type:

tuple[list[Finding], int, int]

epythet.validation.coverage.trivial_summary(obj)[source]

A summary whose content words all come from the object’s name (DQ003).

Return type:

list[str]

epythet.validation.coverage.trivial_summary_words(identifier, summary)[source]

Whether the summary’s content words are all in the identifier’s (the lazy smell).

Return type:

bool

epythet.validation.coverage.type_restatement(obj)[source]

A parameter description that only restates the annotation (DQ004).

Return type:

list[str]