---
name: python-docstring-conventions
source: https://app.decimal.ai/s/python-docstring-conventions@1/SKILL.md
source_sha256: 1a3c7edc42d5
---

# Python Docstring Conventions

## Contract

Write every Python function, method, and class docstring in this house variant of
Google style. The rules below differ from standard Google style on several arbitrary,
specific points — apply them exactly whenever you author or edit a docstring.

## Rules

1. **Summary line — imperative mood, bare verb.** Start with a command verb:
   `Calculate`, `Fetch`, `Return`, `Parse`, `Build`, `Merge`. Never third-person
   (`Calculates`, `Fetches`, `Returns`). One line, ending in a period.

2. **Returns — always parenthesize the type, on its own indented line.** Write
   `(bool): Whether the row was inserted.` Never a bare `bool:`. The parentheses
   wrap the type only; the description follows the colon.

3. **Multiple return values — list each named value separately. Never a tuple type.**
   For a function returning two things, write two entries (`first (str): ...` and
   `last (str): ...`), not `(tuple[str, str]):` or `(tuple):`.

4. **Args — document every parameter; never state default values.** No
   `Defaults to 5.`, no `default: 5`, no `(default 5)`. Describe behavior only.
   Erase any default value you find in an existing Args description.

5. **Optional parameters — put `, optional` inside the type parentheses.** Write
   `timeout (int, optional): Seconds to wait.` The marker goes in the parens, not in
   the prose, and it never carries a default value.

6. **Types — builtins lowercase, PEP 604 unions.** Use `list`, `dict`, `tuple`,
   `int`, `str`, `bool`, `bytes` — never the capitalized typing forms `List`,
   `Dict`, `Tuple`. Use `|` for unions (`int | None`), never `Optional[int]` or
   `Union[int, None]`. Capitalize `Any`, `Path`, `None`.

7. **Omit empty sections.** Omit `Returns:` when the function returns nothing
   (annotated `-> None`). Omit `Args:` when there are no parameters. Omit `Raises:`
   UNLESS the raise is a critical, contractual part of the function's behavior.

8. **`self` and `cls` are never documented** in a method's `Args:` section.

9. **Indentation.** Section headers (`Args:`, `Returns:`, `Raises:`, `Examples:`)
   sit at 0 indent relative to the docstring body; their entries indent 4 spaces.

10. **Classes** get an `Attributes:` section only — omit `Methods:` and `Args:`.
    `__init__` gets `Args:` only — no `Examples:`, `Notes:`, or `Methods:`. Test
    functions get single-line docstrings only.

## Worked examples

**Rule 1 — imperative summary.**
```
# BEFORE (base default: third-person)
"""Calculates the sum of two integers."""
# AFTER (house)
"""Calculate the sum of two integers."""
```

**Rule 2 — parenthesized return type.**
```
# BEFORE (standard Google: bare type)
Returns:
    bool: Whether the row was inserted.
# AFTER (house)
Returns:
    (bool): Whether the row was inserted.
```

**Rule 3 — named values, not a tuple type.**
```
# BEFORE
Returns:
    (tuple[str, str]): The first and last name.
# AFTER
Returns:
    first (str): The given name.
    last (str): The family name.
```

**Rule 4 — no defaults in Args.**
```
# BEFORE
Args:
    limit (int): Max rows to return. Defaults to 100.
# AFTER
Args:
    limit (int, optional): Max rows to return.
```

**Rule 5 — `, optional` inside the parens.**
```
# BEFORE
Args:
    timeout (int): Optional. Seconds to wait, defaults to 30.
# AFTER
Args:
    timeout (int, optional): Seconds to wait.
```

**Rule 6 — lowercase builtins, `|` unions.**
```
# BEFORE
Args:
    columns (Optional[List[str]]): Columns to select.
Returns:
    Optional[int]: The index, or None.
# AFTER
Args:
    columns (list | None, optional): Columns to select.
Returns:
    (int | None): The index, or None.
```

**Rule 7 — omit empty/uncritical sections.**
```
# BEFORE (base reflexively adds Returns + Raises)
"""Record an event.

Args:
    name (str): The event name.

Returns:
    None: Nothing.

Raises:
    RuntimeError: If logging is unconfigured.
"""
# AFTER (None return + non-critical raise both dropped)
"""Record an event.

Args:
    name (str): The event name.
"""
```

**Rule 8 — never document `self`.**
```
# BEFORE
Args:
    self: The instance.
    key (str): The lookup key.
# AFTER
Args:
    key (str): The lookup key.
```

**Rule 6/`Path` — capitalize Path even when the param is untyped.**
```
# BEFORE
Args:
    path (str): The file to read.
# AFTER
Args:
    path (Path): The file to read.
```

## Edge cases & exceptions

- **A `Raises:` that IS the contract stays.** If a function's documented job is to
  raise on bad input (e.g. `divide` raising `ValueError` when the divisor is zero),
  keep `Raises:`. The rule omits *reflexive* raises (impossible-scenario guards),
  not contractual ones.
- **Untyped parameters still get a type in the docstring.** If the signature is
  `parse_config(path)` with no annotation but the function opens a file, document it
  as `path (Path)`. The docstring carries the intended type even when the signature
  omits it.
- **`-> Any` returns are documented**, with `Any` capitalized: `(Any): ...`. Only a
  `-> None` return drops the `Returns:` section.
- **`tuple` as a literal return shape vs. multiple values.** If the function genuinely
  returns one tuple object that callers treat as a unit, a single entry is fine — but
  the common case (returning "the min and the max") is two named entries.
- **Single-line docstrings** (`"""Return the cached value."""`) are valid and
  preferred for trivial functions and all test functions; don't expand them into
  multi-section blocks.
- **Mutable-default params** still document the parameter normally; the docstring
  never mentions the default regardless of mutability.

## Do / Don't

- Never write `Returns:\n    dict:`. Always write `Returns:\n    (dict):`.
- Never write `Calculates`/`Returns`/`Fetches`. Always start with the bare verb.
- Never echo a default value in an Args description. Always describe behavior only.
- Never write `Optional[X]` or `Union[X, Y]`. Always use `X | None` / `X | Y`.
- Never write `List`/`Dict`/`Tuple`. Always lowercase `list`/`dict`/`tuple`.
- Never collapse two return values into `(tuple):`. Always name each value.
- Never add `Raises:` for a guard the caller can't trigger. Always omit it unless
  the raise is part of the contract.
- Never document `self`/`cls`. Always start Args at the first real parameter.

## Common mistakes

- Emitting standard Google style (bare `bool:` return) because that's the base's
  default — the house variant parenthesizes it.
- Writing `Returns:\n    None` for a `-> None` function instead of omitting the
  section entirely.
- Adding an empty `Args:` header to a zero-parameter function.
- Carrying `Defaults to N` into the Args text — the single most common slip.
- Using `Optional[int]` for a `int | None` return, or `List[str]` for `list`.
- Forgetting `, optional` on a parameter that has a default in the signature.

## Quick checklist

- [ ] Summary starts with a bare imperative verb, ends with a period.
- [ ] Every return type is wrapped in `( )`; multiple values are named separately.
- [ ] No Args description states a default value.
- [ ] Optional params carry `, optional` inside the type parens.
- [ ] Builtins are lowercase; unions use `|`; `Any`/`Path`/`None` capitalized.
- [ ] `Returns:`/`Args:`/`Raises:` omitted when empty or non-contractual.
- [ ] `self`/`cls` not documented.
