The problem: one inspector, one language
docvet checks whether your Python docstrings are present, complete, accurate, and renderable. Since v1.0, it's caught missing Raises: sections, stale docstrings after code changes, broken mkdocs rendering, and more — 22 rules across five check modules.
But it only understood Google-style.
That's a problem, because a huge portion of the Python ecosystem uses something else:
-
Sphinx/RST style (
:param name:,:returns:,:raises:) — Django, Flask, SQLAlchemy, requests, boto3, CPython stdlib - NumPy style (underlined section headers) — NumPy, SciPy, pandas, scikit-learn, matplotlib
If you maintain a Django app or a scientific Python library, docvet's enrichment checks couldn't parse your docstrings. As of v1.13.0, that's fixed.
How style support works
It's a project-level setting, not auto-detection
docvet doesn't guess your style per-file. You tell it once in pyproject.toml:
[tool.docvet]
docstring-style = "sphinx"
Two valid options: "google" (default) and "sphinx". The setting applies project-wide.
The NumPy twist: NumPy-style underlined headers are recognized automatically in the default Google mode. If your project uses NumPy-style docstrings, you don't need to change anything — it already works.
Sphinx/RST parsing
When you set docstring-style = "sphinx", docvet maps field-list directives to the same internal section model used for Google-style:
| Sphinx directive | Maps to |
|---|---|
:param:, :type:
|
Args |
:returns:, :return:, :rtype:
|
Returns |
:raises: |
Raises |
:ivar:, :cvar:
|
Attributes |
.. seealso:: |
See Also |
.. code-block::, >>>
|
Examples |
This means all existing enrichment rules apply — missing-raises, missing-examples, missing-attributes, and the rest.
def connect(host: str, port: int = 5432) -> Connection:
"""Open a database connection.
:param host: Hostname or IP address.
:param port: Port number.
:returns: An active connection object.
:raises ConnectionError: If the host is unreachable.
"""
docvet checks this the same way it checks a Google-style docstring — are all raised exceptions documented? Are there parameters in the signature not covered by :param: directives?
Auto-disabled rules: Five enrichment rules that have no Sphinx/RST equivalent are automatically disabled in Sphinx mode: require_yields, require_receives, require_warns, require_other_parameters, and prefer_fenced_code_blocks. You can override any of them:
[tool.docvet]
docstring-style = "sphinx"
[tool.docvet.enrichment]
require_yields = true # re-enable if your project uses a yields convention
Griffe compatibility: The griffe check is auto-skipped in Sphinx mode, since griffe's parser targets Google-style docstrings.
NumPy section recognition
NumPy-style uses section headers with matching-length underlines:
def transform(data, axis=0):
"""Apply transformation along an axis.
Parameters
----------
data : array_like
Input data.
axis : int, optional
Axis along which to operate.
Returns
-------
result : ndarray
Transformed data.
Raises
------
ValueError
If axis is out of bounds.
"""
In the default Google mode, docvet already recognizes these headers alongside Google colon-format headers. The section parser looks for 3+ consecutive dashes or equals signs on the line following a known header name. No config change needed.
NumPy-specific sections like Notes, References, Warnings, Extended Summary, and Methods are recognized for section boundary detection but don't have their own enforcement rules — they won't trigger findings.
New rules
missing-returns
Functions that return a value should document what they return:
# docvet flags this — return value is undocumented
def calculate_total(items: list[Item]) -> float:
"""Sum all item prices."""
return sum(item.price for item in items)
The rule skips cases where a return section doesn't make sense:
-
Stubs (
...orpassbody) — interface definitions, not implementations -
__init__methods — returnNoneby convention - Properties — the getter docstring describes the attribute, not a return value
- Re-raise-only functions — they don't meaningfully "return"
Works in both Google and Sphinx modes.
overload-has-docstring
@typing.overload signatures describe distinct call patterns. They deserve docstrings explaining when to use each variant:
@overload
def parse(data: str) -> dict: ...
@overload
def parse(data: bytes) -> dict: ...
def parse(data):
"""Parse input data into a dictionary."""
docvet flags the overload signatures missing docstrings. The existing missing-docstring rule skips overloads to avoid double-reporting — each rule owns its scope cleanly.
The bigger picture
This release is about reach. docvet's quality model — six layers from presence to rendering — applies regardless of docstring style. The rules don't change; the parser learned new dialects.
| Style | Configuration | Notes |
|---|---|---|
| Default, no config needed | Original support | |
| NumPy | Default, no config needed | Recognized automatically in Google mode |
| Sphinx/RST | docstring-style = "sphinx" |
One line in pyproject.toml |
If you're on a Django team, a scientific Python project, or any codebase using Sphinx-style docs, docvet is ready.
pip install --upgrade docvet
docvet check --all
22 rules across 5 check modules. Zero runtime dependencies beyond typer.
Top comments (0)