Stop writing boilerplate docstrings by hand.
docstring_generatorreads your type hints and generates professional, standards-compliant documentation in seconds — keeping your codebase clean, consistent, and AI-ready.
Python documentation tooling that automatically generates docstrings for functions and class methods from their type hints, with full support for NumPy, Google, and reStructuredText styles.
Good documentation is no longer optional. AI coding assistants, static analysis tools, and auto-generated API docs all depend on structured, accurate docstrings. Yet writing them by hand is tedious, error-prone, and rarely kept up-to-date.
docstring_generator solves this by:
- ⚡ Saving hours — generate docs for an entire codebase in one command
- 🔄 Staying in sync — re-running only updates what changed in the function signature
- ✍️ Preserving your words — existing descriptions and custom notes are never overwritten
- 🧠 AI-workflow friendly — well-structured docstrings improve context quality for LLM-assisted development
- 🚨 Exception-aware — automatically detects
raisestatements and documents them in aRaisessection, so failure modes are part of your API contract - 🙈 Convention-correct —
selfandclsare automatically excluded from generated parameter sections, matching every major docstring standard - ⚙️ Async-ready — handles both
defandasync deffunctions transparently, no extra configuration needed - 🎨 Style-safe — detects the existing docstring style and refuses to silently mix conventions; explicit opt-in required to convert styles
- 🏎️ Blazing fast — core engine written in C++ via pybind11
One command. Any file or directory:
pip install docstring-generatorgendocs_new file.py # single file
gendocs_new mydir/ # entire directoryThat's it. Your functions now have properly formatted docstrings.
| Style | Flag | Description |
|---|---|---|
| NumPy | --style numpy |
Standard in scientific Python (default) |
--style google |
Preferred in many enterprise codebases | |
| reStructuredText | --style rest |
Compatible with Sphinx auto-documentation |
Default: numpy
Scan a file or directory and get a coverage overview without modifying anything:
gendocs_new mydir/ --checkOutputs a per-file summary showing which functions are documented and which are missing docstrings.
By default, a function with any docstring counts as documented. Strict mode raises the bar:
gendocs_new mydir/ --check --strictA partial docstring (e.g. missing parameter sections) is treated as undocumented in strict mode.
Fail the check if coverage drops below a given percentage (0–100):
gendocs_new mydir/ --check --threshold 80Useful in CI pipelines to enforce documentation standards across the codebase.
Exclude one or more files from processing by name. Can be passed multiple times:
gendocs_new mydir/ --exclude-file conftest.py --exclude-file settings.pyFiles whose name matches any of the provided values are skipped during docstring generation.
Exclude one or more directories from processing. Can be passed multiple times:
gendocs_new mydir/ --exclude-dir tests --exclude-dir migrationsAny file whose path contains one of the given directory names is skipped.
Run the generator in read-only mode and see exactly what would be added or changed as a unified diff:
gendocs_new mydir/ --dry-runFiles that already have complete docstrings print <file>: no changes. Files with missing docstrings show a +/- diff so you can review before committing. Combine with --style or --overwrite-style to preview a style migration:
gendocs_new mydir/ --style google --overwrite-style --dry-runRestrict processing to files that are modified or staged in git — perfect for large repos where running on the full src/ directory on every commit would be slow:
gendocs_new mydir/ --changed-onlyInternally runs git diff --name-only HEAD and git diff --cached --name-only to collect the list of changed and staged .py files, then intersects that list with the paths you provided. If git is not installed or not available on PATH, the command aborts immediately with a clear error message rather than silently processing everything.
Combines well with --dry-run to preview what would change for only the files you touched:
gendocs_new mydir/ --changed-only --dry-runExclude dunder methods such as __init__, __str__, __repr__, __eq__, etc. from docstring generation. These are often implementation details that add noise rather than value to public documentation:
gendocs_new mydir/ --ignore-magicCan also be enabled permanently via pyproject.toml so every invocation skips magic methods without an explicit flag:
[tool.docstring_generator]
ignore_magic = trueForce regeneration of existing docstrings using the specified style, even if they already have content:
gendocs_new mydir/ --style google --overwrite-style trueUseful when migrating a codebase from one docstring convention to another.
Instead of passing flags on every invocation, persist defaults in your project's pyproject.toml under the [tool.docstring_generator] namespace:
[tool.docstring_generator]
strict = true
threshold = 90
exclude_files = ["conftest.py", "settings.py"]
exclude_dirs = ["tests", "migrations"]
ignore_magic = trueCLI flags always override pyproject.toml values. The tool automatically walks up from the target path to find the nearest pyproject.toml.
Write your domain-specific notes once — docstring_generator will place them in the right parameter slot automatically.
Use $1, $2, … in your docstring body to map descriptions to positional parameters:
from typing import List
def foo(val_a: int, val_b: List[int]):
"""
Lorem ipsum dolor sit amet, consetetur sadipscing elitr,
sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam
$1 Lorem ipsum dolor sit amet
$2 nonumy eirmod tempor invidun
"""After running gendocs_new (NumPy style):
from typing import List
def foo(val_a: int, val_b: List[int]):
"""
Lorem ipsum dolor sit amet, consetetur sadipscing elitr,
sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam
Parameters
----------
val_a : argument of type int
Lorem ipsum dolor sit amet
val_b : argument of type List(int)
nonumy eirmod tempor invidun
"""Use >> on its own line inside an existing docstring to provide a description for the return value. On the next gendocs_new run the marker is consumed and wired into the Returns section automatically.
def square(x: int) -> int:
"""Square a number.
>> The squared value of x.
"""
return x * xAfter running gendocs_new (Google style):
def square(x: int) -> int:
"""Square a number.
Args:
x (int):
Returns:
int: The squared value of x.
"""
return x * xCombine $N for parameter descriptions and >> for the return description to fully annotate a function before running the generator — no manual editing of the structured sections needed.
docstring_generator statically analyzes your function body for raise statements and adds a Raises section describing each exception — including the condition that triggers it. This works seamlessly with frameworks like Pydantic, FastAPI, or any custom validation logic.
class PluginConfig(BaseModel):
name: str = Field(default="default")
api_config: dict = Field(default_factory=dict)
@field_validator("api_config", mode='before')
@classmethod
def validate_api_config(cls, values: dict) -> dict:
required_key_obj = values.get("required_keys", None)
if not required_key_obj:
raise ValueError("The first key must be 'required_keys'")
if not isinstance(required_key_obj, dict):
raise ValueError("The 'required_keys' must be a dict")
return valuesclass PluginConfig(BaseModel):
name: str = Field(default="default")
api_config: dict = Field(default_factory=dict)
@field_validator("api_config", mode='before')
@classmethod
def validate_api_config(cls, values: dict) -> dict:
"""
Parameters
----------
values : dict [Argument]
Returns
-------
dict
Raises
-------
ValueError
If not isinstance(required_key_obj, dict)
ValueError
If not required_key_obj
"""
required_key_obj = values.get("required_keys", None)
if not required_key_obj:
raise ValueError("The first key must be 'required_keys'")
if not isinstance(required_key_obj, dict):
raise ValueError("The 'required_keys' must be a dict")
return valuesEvery raise — even multiple ones in the same function — is captured, so complex validators document all their failure modes at once.
No more hunting through code to find out what a function can throw — it's documented right where it matters.
Automatically generate docstrings on every commit using the pre-commit framework.
Add this to your project's .pre-commit-config.yaml:
repos:
- repo: https://github.com/FelixTheC/docstring_generator
rev: v0.3.4 # pin to a release tag
hooks:
- id: gendocs
args: [src/] # directory to processInstall the hook:
pip install pre-commit
pre-commit installThe hook runs gendocs_new before each commit. If it generates or updates any docstrings, the commit is intentionally stopped so you can review and stage the changes:
| Run | What happens | Status |
|---|---|---|
| 1st commit | Hook generates docstrings → files modified | ❌ Stopped (intentional) |
git add modified files |
Stage the generated docstrings | — |
| 2nd commit | Hook runs, nothing changed | ✅ Passed |
This is standard behavior for any auto-fix hook (same as Black or isort).
hooks:
- id: gendocs
args: [src/, --style, google]Nothing is lost. If the function signature hasn't changed, the existing docstring stays untouched. If you add or rename parameters, only the structural part is updated — your custom descriptions are preserved.
Yes. The tool is non-destructive by design. It never deletes content; it only adds or updates parameter sections based on type hints.
Yes — both standalone functions and class methods are fully supported.
Ready-to-run examples are available in the examples/ directory.
pip install docstring-generatorRequires Python 3.13+.
The core engine is implemented in C++ (C++20) and exposed to Python via pybind11, delivering performance that scales to large codebases without slowing down your workflow.
- Extension: docstring-generator-ext — the high-performance backbone of this project
Planned features and areas of investment:
- GitHub Action — publish a ready-to-use Action to the Marketplace so teams can enforce docstring coverage in CI without any local installation
- Coverage badge generation (
--badge) — produce an SVG badge from--checkresults to embed in README, similar to a test-coverage badge - JUnit/SARIF output for
--check— emit machine-readable results for GitHub, GitLab, and Azure DevOps CI panels; enables PR annotations that highlight undocumented functions inline - IDE plugin support (JetBrains, VS Code)
- Watch mode (
--watch) — monitor the project for file saves and regenerate docstrings automatically in the background - Sphinx / mkdocs bridge (
--export-rst) — generate.rstor.mdstubs ready for Sphinx/mkdocs autodoc pipelines - Custom docstring templates — let teams define their own format via
pyproject.tomlfor internal style guides that extend NumPy or Google - LLM-assisted description generation (opt-in enrichment mode) — use a local or remote LLM to fill in meaningful parameter descriptions beyond the type hint
- CI/CD pipeline gate (fail build below coverage threshold)
Community feedback shapes priorities — open an issue to vote on features or suggest new ones.
Follows Semantic Versioning. See the tags for all available releases.
- Felix Eisenmenger — creator & maintainer
MIT License — free to use in personal and commercial projects.