Pure Programmer
Blue Matrix


Cluster Map

Documentation

Every program describes how to accomplish some task in the language of mathematics and logic. While high level languages help us to express programming concepts easily and clearly, they are often not the best way to explain the abstract concepts involved. This is where programming documentation comes to the rescue. Documentation in the form of program comments interspersed in the source code are a means to explain in plain English the expected workings of a program and the high level concepts involved. They are a way to include information that is not obvious or clear in the programming statements themselves.

In this site we will use a standard block of comments at the beginning of each file to explain the purpose of the program in the file. We will include the program author, the date that the program was written and any updates that were made. This last use of comments to document the update history is one that should only be used for programs that are not under source code control. For complex multi-file programs a [[source code control system]] will be a necessity and will perform the task of managing the update history of files.

Basic comments are written on a single line. Such single-line comments begin with a hash symbol (#) and continue to the end of the current line. They can start at the beginning of the line or anywhere in the middle of a line. The following are examples of comments.

# This is a comment

Each program file, class or function/method should have a comment preceding it that describes the purpose and typical usage of the item being documented. Comments should document the high-level behavior and not get involved in the specifics of the current implementation. Implementation details can change but the interface described by the comment should rarely change. It also helps to know how the program, class or function/method is intended to perform when the code itself is found to have a bug. The following is an example of what a program file comment might look like.

######################################################################
# This program computes ...
#
# Copyright © 2023 Richard Lesh.  All rights reserved.
######################################################################

Modern Python Documentation

Modern Python documentation has two layers:

  1. Human-facing guides: README, tutorials, architecture notes, examples
  2. API/reference docs: generated from source using docstrings

What Should Be Documented

Modern Python documentation should describe:

This aligns better with how modern Python libraries are read and maintained. Python has a built-in documentation mechanism called a docstring. A docstring is a string literal placed as the first statement in a module, class, function, or method. Documentation tools such as Sphinx, pydoc, and IDEs can read docstrings and generate API documentation automatically.

Python Docstrings

Python docstrings usually use triple-quoted strings such as """ ... """. A common style is to begin with a short summary line, followed by a blank line and more detailed explanation. Many projects use a structured style such as Google style, NumPy style, or reStructuredText field lists.

For example, a docstring for a function might look like this:

def circle_area(radius: float) -> float:
    """
    Compute the area of a circle.

    Uses the standard formula pi * r^2.

    Args:
        radius: Radius of the circle in meters. Must be non-negative.

    Returns:
        Area in square meters.

    Raises:
        ValueError: If radius is negative.
    """
    if radius < 0:
        raise ValueError("radius must be non-negative")
    return 3.141592653589793 * radius * radius

This is a typical Python documentation block. Unlike ordinary comments beginning with #, a docstring is associated directly with the function and can be inspected at runtime and extracted by documentation tools.

The docstring is placed immediately inside the function definition as the first statement, which tells Python and documentation tools that the text applies to that function.

The first line provides a short summary of the function.

Most documentation systems display the summary description in:

The summary should explain what the function does, not how it works internally.

After the summary line, you can include additional explanatory text.

This section may describe:

Documentation tools treat this as the detailed description of the function.

The Args: section documents each formal parameter of the function.

Good parameter documentation usually explains:

Each function parameter should normally have its own entry.

The Returns: section explains what value the function returns.

It should describe:

Even if the return type is obvious from the code, describing the meaning of the result is helpful for readers.

The Raises: section documents exceptions that the function may raise.

It should include:

This helps programmers understand the error conditions that must be handled when calling the function.

Structured documentation like this serves several purposes:

  1. Readable source code documentation
  2. Automatically generated API reference manuals
  3. Improved IDE tooltips and code navigation
  4. Clear documentation of interface contracts

Tools such as Sphinx and pydoc can scan these docstrings and generate HTML documentation directly from the source code.

Classes, enumerations, modules, and generic type hints can also have docstrings. For example:

Class Example

class Account:
    """
    Represent a bank account with a running balance.

    Instances of this class are not thread-safe.
    """

    def __init__(self) -> None:
        self._balance = 0.0

    def deposit(self, amount: float) -> None:
        """
        Deposit money into the account.

        Args:
            amount: Amount to deposit. Must be positive.
        """
        self._balance += amount

    def get_balance(self) -> float:
        """
        Return the current balance.

        Returns:
            Current balance in dollars.
        """
        return self._balance

Enumeration Example

from enum import Enum

class TaskState(Enum):
    """States a task can be in during execution."""

    PENDING = "pending"
    RUNNING = "running"
    COMPLETE = "complete"
    FAILED = "failed"

Generic Type Example

from typing import TypeVar

T = TypeVar("T")

def max_value(a: T, b: T) -> T:
    """
    Return the larger of two values.

    Args:
        a: First value.
        b: Second value.

    Returns:
        The larger of a and b.
    """
    return a if a >= b else b

Python uses type hints and the typing module to express generic type parameters such as TypeVar. In documentation, these are usually explained in the surrounding prose rather than with special tags like Java's @param <T>.

Python also supports documenting modules and abstract interfaces.

Module Example

"""
Utility functions for common mathematical operations.
"""

Abstract Base Class Example

from abc import ABC, abstractmethod

class Shape(ABC):
    """Define a simple shape with an area."""

    @abstractmethod
    def area(self) -> float:
        """
        Compute the area of the shape.

        Returns:
            Area of the shape.
        """
        raise NotImplementedError

Modern docs are much easier to learn from when each API item includes a short usage example.

def to_upper(text: str) -> str:
    """
    Convert a string to uppercase.

    Example:
        >>> s = to_upper("Hello")
        >>> s
        'HELLO'

    Args:
        text: Input text.

    Returns:
        Uppercase copy of the input text.
    """
    return text.upper()

In Python docstrings, code examples are usually written as indented text. Many projects use interactive Python shell examples beginning with >>>, which work well with doctest and are easy for readers to follow.

Indented blocks preserve formatting and make examples safer and clearer to display in generated documentation.

Generating Documentation with Python Tools

Once your Python code contains docstrings, you can automatically generate a browsable documentation website.

View Documentation with pydoc

If Python is installed, the pydoc tool is usually available.

Linux and
Raspberry Pi

$ python3 -m pydoc mymodule

macOS

% python3 -m pydoc mymodule

Windows

> py -m pydoc mymodule

This displays the documentation in a terminal-friendly format.

Generate HTML Documentation with pydoc

You can also generate an HTML file from your module documentation.

Linux and
Raspberry Pi

$ python3 -m pydoc -w mymodule

macOS

% python3 -m pydoc -w mymodule

Windows

> py -m pydoc -w mymodule

This writes an HTML file for the module in the current directory.

Generate Larger Documentation Sites with Sphinx

For larger projects, it is common to use Sphinx to build full documentation sites from docstrings and reStructuredText or Markdown pages.

$ pip install sphinx $ sphinx-quickstart

This initializes a Sphinx documentation project that can be configured to extract API documentation from your Python modules.

View the Generated Documentation

The generated documentation will appear in the output directory. Open the HTML files in a web browser to browse your project’s API documentation.

References