# Docstring Style Guide (for Sphinx Autodoc) This project uses Sphinx with the Napoleon extension (`sphinx.ext.napoleon`) and MyST (`myst_parser`). Write docstrings in NumPy style so Sphinx autodoc can render modules, classes, functions, and methods consistently. The goal is to be precise, brief, and useful to readers. Prefer concise summaries and clear parameter/return sections over narrative text. Favor linking to symbols over repeating implementation details. ## Quick Rules - Use NumPy-style sections: Summary, Parameters, Returns, Yields, Raises, Attributes/Properties, See Also, Notes, Examples. - Keep the first line a short, imperative summary sentence (ends with a period). - Put a blank line after the summary before additional details or sections. - Prefer type hints in code; use the docstring to clarify shapes, units, or semantics. - Use inline code backticks for names/paths (e.g., `context["export"]`, `K`, `(H, W, 2)`). - Cross-reference symbols using Sphinx roles: :mod:`s6.app`, :class:`s6.vision.camera.Camera`, :func:`s6.app._pipeline.pipeline`. - Document optional/defaults and units where relevant (e.g., "radius in pixels"). - Keep private helpers minimally documented unless referenced by public APIs. ## Module Docstrings Use a short overview (3–8 lines) stating what the module provides. Optionally add a “Key Concepts” list. Mention how it relates to adjacent modules and what it produces/consumes. Example: ```python """Camera model and image-space transforms for Sense Core. Defines a differentiable pinhole camera with distortion and helpers to map between world, camera, and pixel coordinates. Supports batched tensors and GPU execution via PyTorch. Key concepts ------------ - Intrinsic matrix `K`; extrinsic (world-to-camera) matrix `E`. - Projection/unprojection; warping points and images between views. """ ``` ## Class Docstrings Start with a one-sentence purpose. Follow with a short paragraph on behavior or relationships (e.g., what spaces it transforms between). If the class has notable public fields or properties, include an "Attributes" or "Properties" section. For alternative constructors, document them under classmethods. Prefer to document properties with one-line docstrings explaining meaning and units. Example: ```python class Camera: """Pinhole camera with optional lens distortion. Most methods accept batched tensors and preserve leading dimensions. Parameters ---------- intrinsic : Tensor | ndarray | None 3x3 matrix `K` or 4-vector `(cx, cy, fx, fy)`. If None, inferred from `fov`. extrinsic : Tensor | None 4x4 world-to-camera transform. Defaults to identity. ... """ @property def fx(self) -> torch.Tensor: """Focal length along x (in pixels).""" ``` ## Function and Method Docstrings - First line: imperative summary. - Then a blank line and optional longer description (when needed). - Parameters section describes each argument, type, meaning, and default. - Returns/Yields section describes the returned value(s) and shape/units. - Raises lists only the exceptions callers should reasonably handle. Shape notation: use `(..., 2)` for broadcasting-friendly trailing dimensions and `(H, W[, C])` for images. Clarify units (e.g., meters vs. pixels) and frames (world vs. camera). Example: ```python def project(self, points: torch.Tensor) -> torch.Tensor: """Project 3D camera-space points into pixel coordinates. Parameters ---------- points : Tensor Array of shape `(..., 3)` in camera coordinates. Returns ------- Tensor Pixel coordinates of shape `(..., 2)`. """ ``` ## Pydantic Models and Data Containers For `BaseModel` types (e.g., `Vector2D`, `BoundingBox2D`): - Document the model’s intent in the class docstring. - Use an "Attributes" section or one-line property/field docstrings to clarify units and coordinate conventions. - For methods that transform data (e.g., `crop_points`, `uncrop_points`), document the expected input types and output invariants. ## Special Cases - Web/API endpoints: describe the JSON shape; show minimal response examples or keys (e.g., `{"export": {...}, "stats": {"queue_size": 3}}`). - Decorators: state how inputs/outputs are reshaped or coerced. - Generators: use a "Yields" section instead of "Returns". ## Cross-References Use Sphinx roles to link to internal APIs where helpful: - :class:`s6.schema.primitives.Vector3D` - :mod:`s6.app._pipeline` - :func:`s6.vision.drawing.Markers.vector_text` Keep names fully-qualified for cross-package links. ## Notes and Examples Add a "Notes" section for non-obvious behavior or algorithmic context. Add a short "Examples" section when a one- or two-line snippet makes usage obvious. Prefer minimal, focused examples. Example: ```python Notes ----- Points behind the near/far planes are ignored during warping. Examples -------- >>> cam.project(torch.tensor([0.0, 0.0, 1.0])) tensor([cx, cy]) ``` ## Style Details - Line length: soft limit ~88 characters; wrap where it improves readability. - Use American English and consistent terminology (camera/world space, pixel coordinates). - Prefer present tense and active voice. - Avoid duplicating type hints in the docstring unless it clarifies shapes/units. - When documenting defaults, prefer "by default X" over repeating signature. ## Checklist - Summary sentence is present and concise. - Parameters/Returns sections exist and specify shapes/units where relevant. - Exceptions that callers should handle are documented in Raises. - Properties and important attributes have one-line docstrings. - Cross-references use Sphinx roles. - Module-level docstring explains purpose and relationships. ## Building the Docs Assuming the `torch` conda env with dependencies is available: ```bash cd docs make html # outputs to docs/_build/html ``` Open `_build/html/index.html` in a browser to preview. Ensure your docstrings render as expected under the relevant module/class/function pages. --- When in doubt, copy an existing docstring from `src/s6/vision/camera.py` or `src/s6/schema/primitives.py` and adapt it, keeping summaries short and parameters specific.