Sphinx documentation scripts used by our projects:
- The
.readthedocs.yamlfile is a configuration file used by readthedocs.org. - The
autodoc_typehints.pyscript is a custom Sphinx plugin to automatically document types for attributes and function signatures, based on Python's type hints. - The
docsfolder contains all documentation-building scripts.
Additionally, the docs/intersphinx folder contains object inventories for our most commonly used libraries, for use by the intersphinx extension.
When adding these scripts to a project, replace the following placeholders
throughout the docs folder (a project-wide find-and-replace is the
quickest way):
| Placeholder | Replace with | Example |
|---|---|---|
PROJECT_NAME |
Project/distribution name, as published on PyPI. | example-project |
PACKAGE_NAME |
Top-level importable package name. | example_project |
COPYRIGHT_HOLDER |
Copyright holder shown in the docs footer. | 2025, Example Org |
AUTHOR_NAME |
Author name shown in the docs metadata. | Example Org |
GITHUB_ORG |
GitHub organization or user that owns the repository. | example-org |
The placeholders appear in the following files:
docs/conf.py:project(PROJECT_NAME),copyright(COPYRIGHT_HOLDER) andauthor(AUTHOR_NAME). Also setreleaseandversionto the desired version numbers.docs/make-api.json:pkg_name(PACKAGE_NAME).docs/api-toc.rst: theapi/PACKAGE_NAMEentry. Add any other module names here (e.g.api/PACKAGE_NAME.SCRIPT_MODULE_NAMEfor a script package).docs/index.rst: the title and GitHub repository link (PROJECT_NAME,GITHUB_ORG). Write a brief description of the project (e.g. the description at the start of the GitHub README file).docs/getting-started.rst: the PyPI release link, thepip installinstructions and the GitHub repository link (PROJECT_NAME,GITHUB_ORG). Write an introductory description of the project, with basic usage instructions/examples.
In docs/requirements.txt, replace PROJECT_NAME
with the project itself and add any further package dependencies needed to
import it while building the documentation.
Building the documentation requires Python 3.14 or later: the autodoc_typehints.py plugin reads string-form type annotations through the annotationlib module, so that it works whether a project uses from __future__ import annotations or the lazy annotations that are the default from Python 3.14 onwards. The documented project itself may target any Python version it likes.
To make the documentation, run the following commands from the docs folder:
make api
make clean
make html
The make-api-clean-html.bat can be run from the docs folder to this effect.
Missing references can be skipped by adding the full name to the skip_missing_references set in docs/conf.py.
The following keys can be set in docs/make-api.json:
"type_aliases": dict[str, list[str]],
"include_members": dict[str, list[str]],
"exclude_members": dict[str, list[str]],
"include_modules": list[str],
"exclude_modules": list[str],
"member_fullnames": dict[str, dict[str, str]],
"special_class_members": dict[str, list[str]],
"manual_doc": dict[str, list[str]],Type aliases declared with the PEP 695 type statement (e.g. type Vec = list[float]) are detected automatically and included in the documentation, attributed to the module that defines them. For these, no configuration is needed.
The type_aliases key remains available for aliases that auto-detection cannot see — most commonly legacy aliases declared as X: TypeAlias = ... or as bare assignments. An entry maps a module name to a list of module-level type alias names to include. Entries listed here take precedence over auto-detected ones, so they also serve to pin the module a given alias name is attributed to when it is re-exported from several modules.
Including a type alias (whether auto-detected or listed here) impacts documentation more broadly, making it available to docstrings for other modules.
The following usage example is adapted from tensorsat:
"type_aliases": {
"tensorsat.diagrams": [
"Box", "Shape", "Slot", "Block", "Port", "Wire",
"Slots", "Ports", "Wires", "BoxClass"
],
"tensorsat.lang.fin_rel": [
"Size", "El", "Point", "NumpyUInt8Array", "FinSetShape"
],
"tensorsat.lib.sat": ["Clause", "CNFDiagramMode"],
"tensorsat.viz.diagrams": ["DiagramGraphNodeKind", "DiagramGraphNode"],
"tensorsat.contractions": ["Contraction"],
"tensorsat.contractions.simple": [
"ContractionPath", "Contract2Args", "OptEinsumOptimize"
],
"tensorsat.contractions.cotengra": [
"CotengraOptimizer", "ReusableCotengraOptimizer"
]
}The include_members key can be set to a dictionary, where an entry maps a module name to a list of module-level names which should be explicitly included in the documentation, because Autodoc wouldn't otherwise recognise them.
Typically, this is used to force Sphinx to document exported module-level variables/constants, or to include protected/private members that should nonetheless be publicly documented.
The following usage example is adapted from tensorsat:
"include_members": {
"tensorsat.lib.bincirc": [
"bit",
"not_",
"and_",
"or_",
"xor_",
"bit_0",
"bit_1",
"bit_unk",
"binop_labels"
]
}The exclude_members key can be set to a dictionary, where an entry maps a module name to a list of module-level type alias names which should be explicitly excluded from the documentation.
Typically, these are members which are public but shouldn't be publicly documented, e.g. because they are not user-facing.
The following usage example is adapted from multiformats:
"exclude_members": {
"multiformats.multicodec": ["build_multicodec_tables"],
"multiformats.multibase": ["build_multibase_tables"],
"multiformats.multibase.raw": ["RawEncoder", "RawDecoder"],
"multiformats.cid": ["CIDVersionNumbers", "byteslike"],
"multiformats.multiaddr.raw": [
"ip4_encoder", "ip4_decoder", "ip6_encoder",
"ip6_decoder", "tcp_udp_encoder", "tcp_udp_decoder"
]
},The include_modules key can be set to a list of module names to be explicitly included in the documentation, because because Autodoc wouldn't otherwise recognise them.
The exclude_modules key can be set to a list of module names to be explicitly excluded from the documentation.
Typically, these are utility modules which shouldn't be documented in the public API.
The following usage example is adapted from dag-cbor:
"exclude_modules": [
"dag_cbor.decoding._err",
"dag_cbor.decoding._err_utils",
"dag_cbor.decoding._stream"
],The member_fullnames key can be set to a dictionary, where an entry maps a module name to a dictionary of member fullnames.
Each entry in a dictionary of member fullnames maps the local name exported by the module to the corresponding full name, qualified to indicate where the exported member was originally defined.
Typically, this is used to document constants exported by modules but defined in sub-modules.
The following usage example is adapted from bases:
"member_fullnames": {
"bases": {
"base2": "bases.encoding.base2",
"base8": "bases.encoding.base8",
"base10": "bases.encoding.base10",
"base16": "bases.encoding.base16",
"base32": "bases.encoding.base32",
"base32hex": "bases.encoding.base32hex",
"base32z": "bases.encoding.base32z",
"base36": "bases.encoding.base36",
"base64": "bases.encoding.base64",
"base64url": "bases.encoding.base64url",
"base10": "bases.encoding.base10",
"base36": "bases.encoding.base36",
"base58btc": "bases.encoding.base58btc",
"base58flickr": "bases.encoding.base58flickr",
"base58ripple": "bases.encoding.base58ripple",
"base45": "bases.encoding.base45"
}
}The special_class_members key can be set to a dictionary, where an entry maps a class name to a list of special member names to be explicitly included in the documentation.
The following usage example is adapted from dag-cbor:
"special_class_members": {
"dag_cbor.ipld.IPLDObjPath": ["__new__", "__truediv__", "__rtruediv__", "__le__", "__lt__", "__repr__", "__rshift__"]
}Note. This example is outdated, and recent versions of the Sphinx docscripts automatically include all the special class names listed above. The full list of special class names which are automatically included is given below, and special_class_members is only necessary to document special names not listed there.
Special class names documented:
# Comparison:
__eq__
__gt__
__ge__
__lt__
__le__
__ne__
# Unary operators:
__abs__
__not__
__inv__
__invert__
__neg__
__pos__
# Binary operators:
__add__
__and__
__concat__
__floordiv__
__lshift__
__mod__
__mul__
__matmul__
__or__
__pow__
__rshift__
__sub__
__truediv__
__xor__
# Inplace binary operators:
__iadd__
__iand__
__iconcat__
__ifloordiv__
__ilshift__
__imod__
__imul__
__imatmul__
__ior__
__ipow__
__irshift__
__isub__
__itruediv__
__ixor__
# RHS binary operators:
__radd__
__rand__
__rconcat__
__rfloordiv__
__rlshift__
__rmod__
__rmul__
__rmatmul__
__ror__
__rpow__
__rrshift__
__rsub__
__rtruediv__
__rxor__
# Conversion methods:
__bool__
__int__
__float__
__complex__
__bytes__
__str__
# Other methods:
__init__
__new__
__call__
__repr__
__index__
__contains__
__delitem__
__getitem__
__setitem__
__getattr__
__setattr__
__delattr__
__set_name__
__set__
__get__The manual_doc key can be set to a dictionary, where an entry maps a member's full name to a list of reStructuredText lines to insert immediately before that member's autodoc directive.
This is useful for members that Autodoc cannot describe on its own, most commonly union type aliases.
The following usage example is adapted from tensorsat:
"manual_doc": {
"tensorsat.diagrams.Block": [
"Type alias for a block in a diagram, which can be either:",
"",
"- a box, as an instance of a subclass of :class:`Box`;",
"- a sub-diagram, as an instance of :class:`Diagram`.",
""
]
}