Docstring & Type Hint Guidelines¶
This page defines the conventions for writing docstrings (see Docstring Guidelines) and using type hints (see Typing Guidelines) in this project. We follow NumPy-style docstrings and use Python type hints as the single source of truth for parameter and return types. Target runtime: Python ≥ 3.11.
1. General Principles¶
- Always use Python type hints → types live in the function signature, not duplicated in the docstring.
 - 
Docstrings focus on:
 - 
What the function does.
 - Meaning and units of parameters.
 - Return value meaning.
 - State/variables updated (Modifies).
 - Functions called (Calls).
 - Expected errors (Raises).
 - Use NumPy-style sections for readability and doc tool compatibility.
 
2. Example Function with Full Docstring¶
Below is an example that demonstrates the recommended style for docstrings and type hints in this project. It shows how to document parameters, returns, modifications, calls, and exceptions.
from pathlib import Path
from typing import Final
import numpy as np
import numpy.typing as npt
import pydicom
from pydicom.dataset import FileDataset
# Example constant with a type hint
EPS: Final[float] = 1e-12
def update_dose_matrix(
    rt_dose: FileDataset,
    new_matrix: npt.NDArray[np.float32],  # shape: (z, y, x), Gy
    normalize: bool = True,
) -> None:
    """
    Update the dose matrix inside an RTDOSE DICOM object.
    Parameters
    ----------
    rt_dose
        DICOM RTDOSE dataset to update.
    new_matrix
        New 3D dose grid ``(z, y, x)`` in **Gy**.
    normalize
        If ``True``, rescale values to match ``DoseGridScaling``.
    Returns
    -------
    None
    Modifies
    --------
    rt_dose.pixel_array
        Replaces the internal dose grid with ``new_matrix``.
    rt_dose.DoseGridScaling
        Updated if ``normalize=True``.
    Calls
    -----
    validate_dose_matrix, rescale_dose
    Raises
    ------
    ValueError
        If ``new_matrix`` has incompatible shape or contains NaNs.
    """
    # (implementation here)
    pass
3. Typing Examples (Python 3.11 syntax)¶
Use modern forms (| unions, built‑in generics) and concrete library types.
from pathlib import Path
import SimpleITK as sitk
import pydicom
from pydicom.dataset import FileDataset
# Accept both strings and Paths; may return nothing
def load_rtplan(path: str | Path | None = None) -> FileDataset | None:
    ...
# Simple union narrowing
def parse_value(x: int | float) -> float:
    ...
# Tuples with built-in generics
def resample_ct(img: sitk.Image, spacing: tuple[float, float, float]) -> sitk.Image:
    ...
# Collections with built-in generics
def summarize(ds_list: list[FileDataset]) -> dict[str, str]:
    ...
Tip: For arrays, prefer
numpy.typing.NDArraywith explicit dtypes, e.g.npt.NDArray[np.float32].
4. Docstring Template (NumPy style)¶
Copy this template when adding new functions.
def function_name(param1: int, param2: str | None = None) -> bool:
    """
    One-sentence summary in the imperative mood.
    Extended description (what, why, and context). Keep types in the signature,
    and focus here on meaning, units, shapes, side effects, and behavior.
    Parameters
    ----------
    param1
        Meaning of param1; units if applicable.
    param2
        Meaning of param2; when ``None`` is allowed and what it means.
    Returns
    -------
    bool
        What ``True``/``False`` indicate.
    Modifies
    --------
    obj.attr
        What object/attribute is modified (if any).
    Calls
    -----
    other_function, helper
    Raises
    ------
    ValueError
        When inputs are invalid (describe conditions).
    RuntimeError
        When an unexpected state is encountered.
    """
    ...
5. Common Pitfalls¶
- Don’t duplicate types in the docstring — keep them in the signature.
 - Document shapes and units (e.g., 
(z, y, x),mm,Gy) in the docstring text. - Prefer concrete library types: 
sitk.Image,pydicom.dataset.FileDataset. - Be precise with 
Path: acceptstr | Pathin public APIs. - Use 
Finalfor constants and annotate dataclass/attrs fields.