---
name: numpy-docstring-format
source: https://app.decimal.ai/s/numpy-docstring-format@1/SKILL.md
source_sha256: 5e4fc09621a6
---

# NumPy-Style Docstring Convention

## Contract

Every Python function, method, class, and generator is documented with a **NumPy-style**
docstring: hyphen-underlined section headers, `name : type` parameter lines, and a bare-type
`Returns`. Apply this whenever you write or edit a docstring. Do **not** use Google style
(`Args:`), reStructuredText (`:param:`), or Epytext (`@param`) — those are the defaults to avoid.

## Rules (the complete spec)

1. **Quotes and summary.** Open with `"""` and put the one-line summary on the line
   immediately after the opening `"""` — not on the same line as the quotes. The summary is a
   single sentence in the **imperative mood** ("Compute…", "Fetch…", not "Computes…" /
   "Returns the…") and **ends with a period**. Close with `"""` on its own line.

2. **Blank line, then sections.** Leave one blank line after the summary, then emit the
   applicable sections in this **exact order**, omitting any that do not apply:
   `Parameters` → `Returns` (or `Yields`) → `Raises`. (Less common sections, when used, slot in
   as: `Parameters`, `Returns`/`Yields`, `Other Parameters`, `Raises`, `See Also`, `Notes`,
   `Examples`.)

3. **Header underline.** Write each section header as a plain word on its own line, followed
   immediately by a line of hyphens (`-`) **exactly as long as the header text** — never a
   trailing colon:
   - `Parameters` then `----------` (10 hyphens)
   - `Returns` then `-------` (7 hyphens)
   - `Raises` then `------` (6 hyphens)
   - `Yields` then `------` (6 hyphens)

4. **Parameter lines.** Document each parameter as `name : type` — name, **single space,
   colon, single space**, type — on its own line. The description goes on the **following**
   line(s), indented **four spaces**. Multiple types are joined with `or` (`int or None`).
   Optional arguments append `, optional` after the type: `page : int, optional`.

5. **Returns.** Give the **bare type on its own line — no parameter name** — with the
   description indented four spaces beneath it. A name before the colon (`result : dict`) is a
   Returns-line error; that form is only for `Parameters`.

6. **Raises.** List each raised exception as the **bare `ExceptionType`** on its own line,
   with the triggering condition indented four spaces beneath it. One entry per distinct
   exception, in the order they can be raised.

7. **Generators.** Use a `Yields` section (not `Returns`) for the yielded value, formatted
   exactly like `Returns` — bare type, description indented beneath.

8. **self / cls.** Never document `self` or `cls` in `Parameters`. For a class, the `Parameters`
   section documents the constructor (`__init__`) arguments.

9. **Variadics.** Document `*args` as `*args : type` and `**kwargs` as `**kwargs : type`
   (keep the stars), or under their real names (`*dicts : dict`).

10. **Forbidden tokens.** Never emit `Args:`, `Arguments:`, `Attributes:`, `:param`,
    `:returns:`, `:raises:`, `@param`, or any colon-terminated header. Headers are *always*
    underlined with hyphens.

## Worked examples (BEFORE = the wrong default, AFTER = conforming)

**Rule 1 + 3 — summary placement and underlines.** Base default = Google style.

```python
# BEFORE (Google)
def to_celsius(f):
    """Convert Fahrenheit to Celsius.

    Args:
        f: Temperature in Fahrenheit.
    """
# AFTER (NumPy)
def to_celsius(f):
    """Convert Fahrenheit to Celsius.

    Parameters
    ----------
    f : float
        Temperature in Fahrenheit.
    """
```

**Rule 4 — `name : type` spacing.** Base writes `f: float` or `f (float):`.

```python
# BEFORE
    """...
    Parameters
    ----------
    f: float            # no space before colon
        ...
    """
# AFTER
    """...
    Parameters
    ----------
    f : float           # space, colon, space
        ...
    """
```

**Rule 5 — Returns is a bare type, no name.** Base names the return value.

```python
# BEFORE
    """Compute cosine similarity.

    Returns:
        score (float): Similarity in [-1, 1].
    """
# AFTER
    """Compute cosine similarity.

    Returns
    -------
    float
        Similarity in [-1, 1].
    """
```

**Rule 6 — Raises lists bare exception types.** Base uses RST or omits Raises.

```python
# BEFORE
    """Divide a by b.

    :raises ZeroDivisionError: if b is zero.
    """
# AFTER
    """Divide a by b.

    Raises
    ------
    ZeroDivisionError
        If b is zero.
    """
```

**Rule 7 — generators use Yields.** Base writes `Returns`.

```python
# BEFORE
    """Yield fixed-size batches.

    Returns:
        list: Each successive batch.
    """
# AFTER
    """Yield fixed-size batches.

    Yields
    ------
    list
        Each successive batch of items.
    """
```

**Rule 8 — self is not documented.** Base lists `self` under Args.

```python
# BEFORE
    """Withdraw from the account.

    Args:
        self: The account.
        amount (float): Amount to withdraw.
    """
# AFTER
    """Withdraw from the account.

    Parameters
    ----------
    amount : float
        Amount to withdraw.
    """
```

## Edge cases & exceptions

- **No parameters / returns nothing.** Omit the empty section entirely — do not write an
  empty `Parameters` header. For `-> None`, you may omit `Returns` or write a `Returns`
  section whose bare type is `None`; never write a Google `Returns:` header.
- **Optional with default.** Reflect the default in the type, not a separate field:
  `cc : list, optional`. The description states the default behavior ("Defaults to `None`.").
- **Union / multiple types.** Join with `or`: `value : int or float`. Do not use Python typing
  syntax like `Union[int, float]` in the type slot unless that is the literal annotation.
- **Class docstring.** Place it under the `class` line and document constructor args in
  `Parameters`; if you also document instance state, use an `Attributes` *NumPy* section
  (hyphen-underlined, 10 hyphens), never Google's `Attributes:` colon header.
- **Async functions.** Identical rules — `async def` changes nothing about the docstring.
- **Multiple raises.** Each distinct exception gets its own bare-type line under one `Raises`
  header; do not collapse them into one line or repeat the `Raises` header.

## Do / Don't

- **Never** end a section header with a colon (`Parameters:`). **Always** underline it with
  hyphens matching the header length.
- **Never** write `name: type` or `name (type):`. **Always** write `name : type` (spaced colon).
- **Never** put a name on the `Returns` type line. **Always** give the bare type only.
- **Never** use `:param:` / `@param:` / `Args:`. **Always** use the hyphen-underlined headers.
- **Never** document `self`/`cls`. **Always** start `Parameters` at the first real argument.
- **Never** put the summary on the same line as the opening `"""`. **Always** drop it to the
  next line.

## Common mistakes (the base's wrong defaults)

- Falling back to **Google style** (`Args:` / `Returns:`) — the single most frequent miss.
- Using `name: type` (Python annotation spacing) instead of `name : type`.
- Writing `Returns\n-------\nresult : dict` — putting a parameter name on the Returns line.
- Underlining with the wrong count (e.g. `Parameters` with 8 hyphens) or omitting the
  underline and using a colon instead.
- Using `Returns` for a generator instead of `Yields`.
- Documenting `self` as the first parameter.
- Mixing RST (`:raises:`) into an otherwise NumPy docstring.

## Quick checklist

- [ ] Summary on the line after `"""`, imperative, ends with a period.
- [ ] Sections in order: Parameters → Returns/Yields → Raises; empties omitted.
- [ ] Every header underlined with hyphens of matching length (10 / 7 / 6 / 6), no colons.
- [ ] Params as `name : type`, description indented 4 spaces; `self`/`cls` excluded.
- [ ] `Returns`/`Yields` = bare type, no name. `Raises` = bare exception types.
- [ ] Zero occurrences of `Args:`, `:param`, `@param`, or any colon-terminated header.
