Skip to content

88. Documentation Workflow

Doc/ Sphinx source layout, building docs with make html, and the process for submitting documentation fixes.

CPython documentation is part of the implementation. It describes the language, the standard library, the C API, command-line behavior, build configuration, and development process. A CPython change is incomplete when the behavior changes but the documentation still describes the old behavior.

The documentation is maintained in the CPython repository, reviewed with code changes, built locally by contributors, and published for Python users and extension authors.

88.1 Where Documentation Lives

Most CPython documentation lives in:

Doc/

Important areas:

PathPurpose
Doc/library/Standard library reference
Doc/reference/Language reference
Doc/tutorial/Python tutorial
Doc/c-api/C API reference
Doc/extending/Extension and embedding guide
Doc/using/Installing, invoking, and using Python
Doc/whatsnew/Version-specific change notes
Doc/howto/Topic-focused guides
Doc/tools/Documentation build tooling
Doc/conf.pySphinx configuration

The documentation source uses reStructuredText, usually called reST.

88.2 Documentation Is Built With Sphinx

CPython uses Sphinx to convert reST source files into HTML, text, man pages, and other formats.

The basic build command is usually:

make -C Doc html

The generated HTML appears under:

Doc/build/html/

Open:

Doc/build/html/index.html

A local documentation build catches many mistakes before review.

88.3 Installing Documentation Dependencies

From a CPython checkout, documentation dependencies are usually installed with:

python -m pip install -r Doc/requirements.txt

Then build:

make -C Doc html

When working inside a fresh checkout, use the Python executable you intend to use for building documentation. This may be the system Python or the newly built CPython, depending on the workflow.

88.4 Common Documentation Build Targets

The Doc makefile provides useful targets.

CommandPurpose
make -C Doc htmlBuild HTML documentation
make -C Doc suspiciousDetect suspicious markup
make -C Doc linkcheckCheck external links
make -C Doc cleanRemove generated output
make -C Doc venvCreate docs build environment when supported
make -C Doc checkRun documentation checks when available

A typical local workflow:

make -C Doc html
make -C Doc suspicious

Use linkcheck selectively. It can be slow and affected by network instability.

88.5 reStructuredText Basics

A documentation page is written in reST.

Example:

Title
=====

This paragraph describes the feature.

Subsection
----------

Use ``literal`` markup for code-like names.

.. code-block:: python

   print("hello")

Common inline markup:

MarkupMeaning
nameLiteral text
:func:\len``Function reference
:class:\dict``Class reference
:mod:\sys``Module reference
:meth:\str.split``Method reference
:attr:\object.class``Attribute reference
:exc:\ValueError``Exception reference
:c:func:\Py_INCREF``C API function reference

Use semantic roles instead of plain literals when linking to documented APIs.

88.6 Headings

CPython documentation uses consistent heading levels within each file.

Typical style:

Main title
==========

Section
-------

Subsection
~~~~~~~~~~

Sub-subsection
^^^^^^^^^^^^^^

Do not change heading levels casually. It affects navigation structure, anchors, generated table of contents, and cross-references.

88.7 Code Blocks

Use explicit language names.

.. code-block:: python

   def add(a, b):
       return a + b

For shell commands:

.. code-block:: shell

   python -m test test_dict

For C code:

.. code-block:: c

   PyObject *obj = PyLong_FromLong(1);
   if (obj == NULL) {
       return NULL;
   }

Code examples should be correct, minimal, and copyable.

88.8 Cross-References

Cross-references are one of the main reasons CPython uses Sphinx.

Examples:

Use :func:`len` to get the length of a container.

See also :mod:`gc` for garbage collector controls.

Extension authors should call :c:func:`Py_INCREF` when taking a new reference.

Good cross-references improve navigation and reduce ambiguity.

Prefer:

:c:func:`PyObject_GetAttr`

over:

``PyObject_GetAttr``

when the C API is documented.

88.9 Version Markers

Documentation often needs version markers.

Examples:

.. versionadded:: 3.13

.. versionchanged:: 3.14

.. deprecated:: 3.15

Use these when behavior changes across Python versions.

Example:

.. versionchanged:: 3.14
   The function now accepts path-like objects.

A version marker should explain the change, not merely state that something changed.

88.10 Documentation for New Features

A new feature may require updates in several places.

Change typeLikely documentation files
New standard library functionDoc/library/<module>.rst
New syntaxDoc/reference/, Doc/tutorial/, Doc/whatsnew/
New C APIDoc/c-api/
New command-line flagDoc/using/cmdline.rst
New environment variableDoc/using/cmdline.rst
New moduleDoc/library/, Doc/whatsnew/
New behaviorExisting reference or library docs
DeprecationRelevant docs plus Doc/whatsnew/

Do not document only the implementation detail. Document the user-visible contract.

88.11 What's New Entries

Important changes need an entry in:

Doc/whatsnew/

For a new Python version, the main file is usually:

Doc/whatsnew/3.x.rst

A good entry states:

what changed
why it matters
where to find the affected API
whether compatibility is affected

Example shape:

module_name
-----------

* Added :func:`module_name.new_function`, which ...

For small bug fixes, a news entry may be enough and What's New may not be required. For visible features, deprecations, and compatibility changes, update What's New.

88.12 News Entries

CPython uses news entries for changelog generation.

They are usually created with blurb.

Typical command:

blurb add

The entry records:

category
issue or pull request number
short user-facing change description

A good news entry is concise and written for users, not for the patch author.

Weak:

Fix bug in foo.

Better:

Fix ``module.foo()`` returning an incorrect result when called with an empty mapping.

Some changes do not need a news entry, such as typo fixes, internal refactoring, or tests that do not affect user-visible behavior.

88.13 C API Documentation

C API documentation must be precise about ownership, lifetime, error behavior, and version availability.

A C API entry should answer:

Does the function return a new reference?
Can it return NULL?
Does it set an exception on failure?
Does it borrow or steal references?
Is it part of the stable ABI?
Which version added or changed it?

Example documentation concern:

Return value: New reference.

Return ``NULL`` with an exception set on failure.

C API documentation is a contract for extension authors. Ambiguity here causes crashes in downstream code.

88.14 Documenting Reference Ownership

Reference ownership should be explicit.

Use language such as:

Return value: New reference.
Return value: Borrowed reference.
The function steals a reference to item.

Example:

Return value: New reference.

Return a new reference to the attribute named *name*.

For stolen references:

This function steals a reference to *item*.

Do not rely on examples alone to communicate ownership.

88.15 Documenting Exceptions

Document exceptions when they are part of the contract.

Example:

Raise :exc:`TypeError` if *path* is not path-like.
Raise :exc:`ValueError` if *mode* is invalid.

Avoid documenting incidental exceptions from implementation details unless users can reasonably depend on them.

For C API functions, describe failure state:

Return ``-1`` with an exception set on failure.

or:

Return ``NULL`` with an exception set on failure.

88.16 Documenting Implementation Details

Some documentation intentionally describes CPython behavior.

Use directives when behavior is implementation-specific:

.. impl-detail::

   CPython currently uses reference counting as its primary memory
   management mechanism.

Implementation details should be useful but clearly separated from language guarantees.

A behavior that other Python implementations need not share should not be presented as universal Python semantics.

88.17 Documentation Tests

Some documentation examples are tested with doctest-like mechanisms.

Example style:

>>> sorted({"b": 2, "a": 1})
['a', 'b']

Interactive examples should be stable across platforms and Python builds.

Avoid examples that depend on:

object addresses
hash randomization
dictionary order unless relevant
locale
filesystem state
network access
timing

When output is unstable, avoid exact doctest output or use a different example style.

88.18 Suspicious Markup

Run:

make -C Doc suspicious

This checks for suspicious constructs such as:

broken inline markup
unclosed literals
bad references
unexpected indentation
malformed links

Warnings should be investigated. Many documentation failures are caused by small reST syntax mistakes.

88.19 Link Checking

Run:

make -C Doc linkcheck

This checks external links.

Caveats:

slow execution
network failures
rate limits
temporary server errors
redirects

Use link checking when adding or changing external links. For normal text edits, html and suspicious are usually more important.

88.20 Style Guidelines

Good CPython documentation is direct and precise.

Prefer:

Return a list of open file descriptors.

over:

This function will return a list containing all of the currently open file descriptors.

Prefer active voice when it improves clarity.

Use terms consistently:

argument
parameter
attribute
method
function
object
exception
iterator
context manager

Avoid marketing tone. Documentation should explain behavior, not promote it.

88.21 Updating Existing Documentation

When changing behavior, search for all affected documentation.

A single runtime change can require updates in:

library reference
language reference
C API reference
What's New
command-line documentation
environment variable documentation
tests
docstrings

Examples:

new import behavior
    → importlib docs
    → language reference
    → What's New

new C API function
    → C API docs
    → stable ABI notes if relevant
    → What's New

changed warning behavior
    → library docs
    → deprecation notes
    → tests

88.22 Docstrings vs Documentation

Docstrings and documentation serve different roles.

LocationPurpose
DocstringRuntime help and introspection
Doc/ sourceFull reference documentation
What's NewVersion-level change summary
News entryChangelog item

A public API change may require all four.

Docstrings should be concise. Full explanations belong in Doc/.

88.23 Reviewing Documentation Changes

A documentation review checks:

technical correctness
version accuracy
cross-reference validity
public contract clarity
style consistency
platform correctness
implementation-detail boundaries

For C API docs, review must also check:

reference ownership
exception behavior
stable ABI status
threading requirements
lifetime constraints

Good documentation review is technical review.

88.24 Common Mistakes

MistakeBetter approach
Documenting only the patch mechanicsDocument user-visible behavior
Omitting version markersAdd versionadded or versionchanged when needed
Using literals instead of semantic linksUse Sphinx roles
Forgetting What's NewAdd entry for visible features
Ambiguous C API ownershipState new, borrowed, or stolen reference
Depending on unstable doctest outputUse stable examples
Changing headings casuallyPreserve document structure
Ignoring suspicious warningsFix markup warnings

88.25 Practical Workflow

A normal documentation workflow:

1. Identify the user-visible behavior.
2. Find the relevant files under Doc/.
3. Update the reference text.
4. Add version markers when needed.
5. Add or update examples.
6. Add C API ownership details if relevant.
7. Add What's New entry for visible changes.
8. Add a news entry when required.
9. Build HTML locally.
10. Run suspicious checks.
11. Review generated output in a browser.

Commands:

make -C Doc html
make -C Doc suspicious

88.26 Core Principle

CPython documentation is executable project memory.

It records the contract that users, extension authors, tool builders, and maintainers rely on. Code changes behavior. Tests protect behavior. Documentation explains behavior. For CPython work, all three must move together.