CLI Reference¶
docvet provides ten subcommands. Global options are generally placed before the subcommand; discovery flags and check-specific options are placed after it.
Global Options¶
| Option | Type | Default | Description |
|---|---|---|---|
--verbose |
flag | off | Show file count, per-check timing, and active checks |
-q / --quiet |
flag | off | Suppress non-finding output (summary, timing, verbose details). Config warnings are always shown. |
--summary |
flag | off | Print per-check quality percentages after findings |
--format |
terminal | markdown | json |
terminal |
Output format |
--output |
PATH |
stdout | Write report to file |
--config |
PATH |
auto-detected | Path to pyproject.toml |
--version |
flag | Show version and exit |
When --output is specified without --format, the format defaults to markdown. When --format json is used, output is always a JSON object (even when no findings exist).
JSON Output¶
The --format json option produces a structured JSON object for programmatic consumption. The schema includes a findings array and a summary object:
{
"findings": [
{
"file": "src/app/utils.py",
"line": 12,
"symbol": "my_func",
"rule": "missing-raises",
"message": "Function 'my_func' raises ValueError but...",
"category": "required",
"severity": "high"
}
],
"suppressed": [
{
"file": "src/app/utils.py",
"line": 30,
"symbol": "internal_helper",
"rule": "missing-examples",
"message": "Public symbol lacks an Examples section",
"category": "recommended",
"severity": "low"
}
],
"summary": {
"total": 1,
"by_category": { "required": 1, "recommended": 0, "scaffold": 0 },
"files_checked": 42
}
}
- Each finding has seven fields:
file,line,symbol,rule,message,category,severity. - The
severityfield is derived fromcategory:"required"maps to"high","scaffold"maps to"medium","recommended"maps to"low". It is a convenience alias, not a separate signal. - The
summaryobject includestotal,by_category(withrequired,recommended, andscaffoldcounts), andfiles_checked. - A
suppressedarray is included containing findings that were suppressed by inline# docvet: ignorecomments. Each entry has the same seven fields as a finding. - Whitespace and indentation are not part of the schema contract — always parse with a JSON parser.
- Exit codes:
0when no active (non-suppressed) findings match afail_oncheck,1when active findings exist in afail_oncheck.
Quality Summary (--summary)¶
The --summary flag prints per-check quality percentages to stderr after findings:
enrichment 96% (8 findings)
freshness 100% (0 findings)
coverage 92% (1 findings)
griffe 100% (0 findings)
Only checks that actually ran appear in the output. When combined with --format json, a quality object is added to the JSON output:
{
"findings": [...],
"summary": {...},
"quality": {
"enrichment": {"items_checked": 200, "items_with_findings": 8, "percentage": 96, "unit": "symbols"},
"freshness": {"items_checked": 200, "items_with_findings": 0, "percentage": 100, "unit": "symbols"},
"coverage": {"items_checked": 12, "items_with_findings": 1, "percentage": 92, "unit": "packages"},
"griffe": {"items_checked": 15, "items_with_findings": 0, "percentage": 100, "unit": "files"}
}
}
When --quiet and --summary are both set, the terminal summary is suppressed (--quiet wins). The machine-readable path is --format json --summary.
--verbose and --quiet can be placed before or after the subcommand name (dual-registered). Both positions are equivalent:
docvet --verbose check --all # before subcommand
docvet check --all --verbose # after subcommand — also valid
docvet check --all -q # quiet after subcommand
When both --quiet and --verbose are specified, --quiet wins.
Output Tiers¶
docvet uses a three-tier output model. Findings always go to stdout; metadata goes to stderr.
| Tier | Trigger | stderr | stdout |
|---|---|---|---|
| Quiet | -q / --quiet |
(nothing) | Findings only |
| Default | (no flags) | Summary line | Findings only |
| Verbose | --verbose |
File count + per-check timing + summary | Findings only |
Parse and availability warnings always appear regardless of output tier.
Default output (zero findings):
Default output (with findings):
src/app/utils.py:12: missing-raises Raises section missing for ValueError [required]
src/app/utils.py:30: stale-signature Docstring may be stale (signature changed) [required]
Vetted 42 files [enrichment, freshness, coverage] — 2 findings (2 required, 0 recommended). (0.4s)
The summary line uses the brand verb "Vetted" and always includes the elapsed time and list of checks that ran. When griffe is not installed, it is omitted from the check list.
Discovery Modes¶
All subcommands accept the same set of discovery modes. These are mutually exclusive — use only one at a time.
| Mode | Description |
|---|---|
| (default) | Files from git diff (unstaged changes) |
--staged |
Files from git diff --cached (staged changes) |
--all |
All Python files in the project |
| (positional) | Specific files as positional arguments |
--files |
Specific files (repeatable alternative) |
Pass files as positional arguments (preferred) or with the --files flag:
docvet check src/app/utils.py src/app/models.py
docvet check --files src/app/utils.py --files src/app/models.py # equivalent
Commands¶
docvet check¶
Run all enabled checks.
docvet check # unstaged changes (default)
docvet check --staged # staged files
docvet check --all # entire codebase
docvet check src/foo.py src/bar.py # specific files
This runs presence, enrichment, freshness, coverage, and griffe (if installed) in sequence and produces a unified report.
docvet presence¶
Check for missing docstrings and report coverage.
Detects public symbols (modules, classes, functions, methods) that lack a docstring. Reports per-file findings and aggregate coverage statistics.
Default output (with findings):
src/myapp/utils.py:12: missing-docstring Public function has no docstring [required]
src/myapp/models.py:5: missing-docstring Public class has no docstring [required]
Vetted 10 files [presence] — 2 findings (2 required, 0 recommended), 98.0% coverage. (0.2s)
Verbose output (with coverage detail):
src/myapp/utils.py:12: missing-docstring Public function has no docstring [required]
Docstring coverage: 99/100 symbols (99.0%) — below 100.0% threshold
Vetted 10 files [presence] — 1 finding (1 required, 0 recommended), 99.0% coverage. (0.2s)
The verbose summary shows documented/total symbols, percentage, and threshold comparison when min-coverage is set.
docvet enrichment¶
Check for missing docstring sections.
Analyzes Python AST to detect missing Raises, Yields, Attributes, Examples, and other sections that should be present based on the code's behavior. 10 rules covering functions, classes, modules, and format conventions.
docvet freshness¶
Detect stale docstrings.
| Option | Type | Default | Description |
|---|---|---|---|
--mode |
diff | drift |
diff |
Freshness check strategy |
Diff mode maps git diff hunks to AST symbols and flags code changes without matching docstring updates. Fast, targeted feedback.
Drift mode uses git blame timestamps to find docstrings that haven't been updated relative to their code. Sweeps the entire codebase for long-stale documentation.
docvet coverage¶
Find files invisible to mkdocs.
Walks the directory tree from each discovered file up to the source root, checking for missing __init__.py files that would make packages invisible to documentation generators.
docvet griffe¶
Check mkdocs rendering compatibility.
Loads packages with the griffe parser and captures warnings that would cause broken rendering in mkdocs-material sites. Detects unknown parameters, missing type annotations, and docstring format issues.
Note
Requires the optional griffe extra: pip install docvet[griffe]
docvet fix¶
Scaffold missing docstring sections. Runs enrichment to find missing sections, inserts placeholder content, and writes modified files. Use --dry-run to preview changes as a unified diff without modifying any files.
docvet fix # Fix files in git diff (default)
docvet fix --all # Fix entire codebase
docvet fix --staged # Fix staged files only
docvet fix src/app.py # Fix a specific file
docvet fix --dry-run --all # Preview changes without writing
Unique options:
| Option | Description |
|---|---|
--dry-run |
Show unified diff of changes without writing files |
All standard discovery modes are supported (--all, --staged, positional files, --files).
Workflow: After running docvet fix, run docvet check to see scaffold-incomplete findings for each [TODO: ...] placeholder. Fill in the placeholders with real descriptions, then docvet check produces zero findings.
# Typical fix workflow
docvet fix --all # Insert scaffolded sections
docvet check --all # See scaffold-incomplete findings
# ... fill in [TODO: ...] markers ...
docvet check --all # Zero findings
docvet config¶
Show effective configuration with source annotations.
docvet config # TOML output (default)
docvet --format json config # JSON output
docvet config --show-defaults # same as plain `docvet config`
Prints the merged config (user values + built-in defaults) so you can see exactly which settings are active and where they come from. Each value is annotated with # (user) or # (default).
TOML output (default):
[tool.docvet]
src-root = "src" # (default)
exclude = ["tests", "scripts"] # (default)
fail-on = ["enrichment"] # (user)
warn-on = ["presence", "freshness", "griffe", "coverage"] # (default)
[tool.docvet.freshness]
drift-threshold = 30 # (default)
age-threshold = 90 # (default)
[tool.docvet.enrichment]
require-raises = false # (user)
require-yields = true # (default)
...
The TOML output is copy-paste-ready — you can paste it directly into your pyproject.toml.
JSON output (--format json):
{
"config": {
"src-root": "src",
"exclude": ["tests", "scripts"],
"fail-on": ["enrichment"],
"warn-on": ["presence", "freshness", "griffe", "coverage"],
"freshness": { "drift-threshold": 30, "age-threshold": 90 },
"enrichment": { "require-raises": false, "require-yields": true }
},
"user_configured": ["fail-on", "enrichment.require-raises"]
}
The user_configured array lists which keys were explicitly set in your pyproject.toml.
When no pyproject.toml is found, a note is printed to stderr and all built-in defaults are shown.
docvet lsp¶
Start the LSP server for real-time diagnostics.
Launches a Language Server Protocol server on stdio that publishes docstring quality diagnostics on file open and save events.
Note
Requires the optional lsp extra: pip install docvet[lsp]
docvet mcp¶
Start the MCP server for agentic integration.
Launches a Model Context Protocol server on stdio that exposes docstring quality checks as MCP tools for AI agents. Agents can call docvet_check to run checks on files or directories, and docvet_rules to retrieve the full rule catalog.
Note
Requires the optional mcp extra: pip install docvet[mcp]
Configuration¶
docvet reads configuration from the [tool.docvet] section in pyproject.toml. If the section is missing, sensible defaults are used.
Specify a custom config path with:
Exit Codes¶
| Code | Meaning |
|---|---|
0 |
No findings (or no findings in fail_on checks) |
1 |
Findings detected in fail_on checks |
2 |
Usage error (invalid arguments or options) |
Inline Suppression¶
Suppress specific findings with inline comments. Suppression operates as a post-filter — all checks run normally, then matching findings are partitioned into suppressed.
Line-Level Suppression¶
Place a # docvet: ignore[rule] comment on the def or class keyword line:
Suppress multiple rules with comma separation:
def connect(host, port): # docvet: ignore[missing-raises,missing-returns]
"""Connect to the server."""
...
Suppress all rules on a symbol with a blanket ignore:
Note
The comment must be on the def/class keyword line itself — not on a decorator line. For multi-line signatures, place it on the def line: def long_name( # docvet: ignore[rule].
File-Level Suppression¶
Place a # docvet: ignore-file[rule] comment before the first def or class:
Suppress all rules for the entire file:
Behavior¶
- Exit code: Suppressed findings do NOT count toward the exit code. Only active findings determine pass/fail.
- Verbose mode: When
--verboseis active, suppressed findings are listed separately on stderr with a[suppressed]tag. - JSON output:
--format jsonincludes a"suppressed"array alongside"findings". - Invalid rules: If a suppression comment specifies a non-existent rule ID, a warning is emitted to stderr. The directive is recorded for forward-compatibility, but only matching rule IDs suppress findings — a typo will not hide anything.
- Always active: Suppression requires no configuration toggle — it is always available.
Cross-Tool Syntax Reference¶
| Tool | Syntax | Scope |
|---|---|---|
| ruff | # noqa: E501 |
Line |
| pylint | # pylint: disable=C0114 |
Line/block |
| mypy | # type: ignore[attr-defined] |
Line |
| docvet | # docvet: ignore[rule] |
Line (symbol) |
| docvet | # docvet: ignore-file[rule] |
File |
Examples¶
Check staged files before committing:
Generate a markdown report for CI:
Produce structured JSON output for agents or CI pipelines:
Write JSON findings to a file:
Run only the freshness drift sweep with verbose output:
Suppress all non-finding output (useful in scripts and CI):
Check specific files: