# GSDFC Docstring Guide This page is the practical companion to the authoritative GSDFC specification in the `docforge/__init__.py` package docstring. It describes how to write docstrings that render correctly in MkDocs and stay machine-parseable by doc-forge, MkDocs, and MCP clients. ## Overview - Docstrings are the single source of truth. - `doc-forge` compiles docstrings but never rewrites them. - Every public symbol should have a complete, accurate docstring. - Type hints live in signatures; prose entries repeat the type in parentheses and must match the signature. ## Module docstrings Modules use Markdown headings and `---` separators. Recommended sections: - `# Summary` — what the subsystem does - `# Examples` — a representative usage snippet - `# Notes` — guarantees, lifecycle, and thread-safety notes ## Class docstrings Recommended sections, in order: - summary line describing responsibility - `Attributes:` — instance attributes with `name (Type):` entries - `Notes:` — grouped subsections such as **Guarantees**, **Lifecycle** - `Example:` — indented `python` code block ## Function and method docstrings Recommended section order: 1. `Args:` 2. `Returns:` 3. `Raises:` 4. `Yields:` 5. `Notes:` 6. `Example:` Formatting rules: - `Args:` entries are `name (Type):` followed by an indented description. - `Returns:` entries are `Type:` followed by an indented description. - `Raises:` entries are `ExceptionType:` followed by an indented condition. - `Yields:` replaces `Returns:` for generators. - Summaries are written in the imperative mood. - Fenced `python` blocks are allowed inside `Example:` sections, indented four spaces. ## Property docstrings Properties document their return values with a `Returns:` section and, when meaningful, an `Example:`. ## Example ```python def process(foo: Foo, multiplier: int) -> int: """Process a Foo instance. Args: foo (Foo): Foo instance to process. multiplier (int): Value used to scale foo. Returns: int: Processed result. Raises: ValueError: If multiplier is negative. Example: Process foo: ```python foo = Foo("example", value=10) result = process(foo, multiplier=2) print(result) ``` """ ``` ## Keeping stubs in sync Every `.py` module ships a matching `.pyi` stub. When a signature or a public symbol changes, update both files. Signature annotations in the stub must match the implementation. ## Enforcement `pydoclint` (Google style) runs in CI and verifies that `Args:`/`Returns:` sections match function signatures, including types. - `allow-init-docstring = true` — `__init__` docstrings are allowed. - `skip-checking-raises = true` — `Raises:` sections are descriptive and are not required to map to literal `raise` statements. - `check-class-attributes = false` — `Attributes:` sections document instance attributes without class-level annotations.