Autonomous Python documentation agent that discovers public declarations, adds or improves docstrings following PEP 257 and Google Style conventions, and verifies linting passes.
This agent specializes in creating high-quality Python documentation that follows:
- PEP 257 — Docstring Conventions
- PEP 8 — Style Guide for Python Code
- Google Python Style Guide
- PEP 484 — Type Hints
Discovers all Python source files, catalogs missing or deficient docstrings on public declarations, applies fixes, verifies linting, and reports results.
task run:python-doc-comments WORKING_DIR=/path/to/repo
task run:python-doc-comments WORKING_DIR=/path/to/repo MODEL=gpt-4o PROVIDER=openaiProduces a prioritized report of docstring gaps without modifying any files.
task run:python-doc-comments-analyze WORKING_DIR=/path/to/repo
task run:python-doc-comments-analyze WORKING_DIR=/path/to/repo MODEL=gpt-4o PROVIDER=openaiThe agent documents all public (non-underscore) declarations:
- Modules — First statement describing module purpose
- Classes — What instances represent, Attributes section
- Functions/Methods — Summary, Args, Returns, Raises sections
- Properties — What the property represents
- Constants — Purpose and valid values
- Private (leading underscore) functions/methods/classes
- Code logic, signatures, or behavior (only docstrings are modified)
- Test files (
test_*.py,*_test.py) and virtual environments - Trivial functions where a docstring would just restate the name
-> Nonereturn annotations (always inferable)__pycache__directories
Key constraints that prevent common failure modes:
- Only modify docstrings — never change code logic
- Triple double quotes — always use
""", never''' - Start with summary line — imperative mood for functions
- No blank line before docstring — immediately follows def/class
- Complete sentences — fragments are not docstrings
- No redundant docstrings — "Process processes the data" = skip
- Proportional — match docstring length to function complexity
- Focus on WHAT, not HOW — no implementation details
- Match existing style — NumPy/Sphinx if present, else Google
- NEVER add
-> None— it's always inferable
- Changes Summary
- Docstrings Added (with file, line, category, docstring, reason)
- Docstrings Improved (with before/after)
- Declarations Skipped (table with reasons)
- Files Touched
- Validation (
python -m py_compile,ruff check)
- Analysis Summary (files analyzed, finding counts by severity)
- Findings (with severity, category, file, line, suggested docstring)
- Priority Order (ranked by impact)
- Recommendations
def function(arg1: int, arg2: str) -> bool:
"""Summary line.
Args:
arg1: Description of arg1.
arg2: Description of arg2.
Returns:
Description of return value.
Raises:
ValueError: When validation fails.
"""
passdef function(arg1: int, arg2: str) -> bool:
"""Summary line.
Parameters
----------
arg1 : int
Description of arg1.
arg2 : str
Description of arg2.
Returns
-------
bool
Description of return value.
"""
passclass TokenBucket:
def __init__(self, rate: float, capacity: int):
self.rate = rate
self.capacity = capacity
self._tokens = capacity
self._last_refill = time.monotonic()
def consume(self, tokens: int = 1) -> bool:
self._refill()
if self._tokens >= tokens:
self._tokens -= tokens
return True
return False
def _refill(self):
now = time.monotonic()
elapsed = now - self._last_refill
self._tokens = min(self.capacity, self._tokens + elapsed * self.rate)
self._last_refill = nowclass TokenBucket:
"""Fixed-capacity token bucket for rate limiting.
Tokens are added at a constant rate up to a maximum capacity.
Callers consume tokens before performing rate-limited operations.
Attributes:
rate: Tokens added per second.
capacity: Maximum number of tokens the bucket can hold.
"""
def __init__(self, rate: float, capacity: int):
"""Create a bucket that refills at ``rate`` tokens per second.
Args:
rate: Tokens added per second.
capacity: Maximum tokens the bucket can hold. The bucket
starts full.
"""
self.rate = rate
self.capacity = capacity
self._tokens = capacity
self._last_refill = time.monotonic()
def consume(self, tokens: int = 1) -> bool:
"""Attempt to consume tokens from the bucket.
The bucket is refilled based on elapsed time before checking
availability.
Args:
tokens: Number of tokens to consume.
Returns:
True if enough tokens were available, False otherwise.
"""
self._refill()
if self._tokens >= tokens:
self._tokens -= tokens
return True
return False
def _refill(self):
now = time.monotonic()
elapsed = now - self._last_refill
self._tokens = min(self.capacity, self._tokens + elapsed * self.rate)
self._last_refill = nowSee references/python-documentation-standards.md for the complete knowledge base covering PEP 257, docstring styles, comment rules, type hints, codetags, linter directives, and quality checklist.
- python-review — review Python code for best practices
- python-tests — generate Python tests