Python Docstring Conventions — Core Concepts

What PEP 257 Says

PEP 257 defines the basic conventions for Python docstrings:

  • Use triple double-quotes (""")
  • The first line is a concise summary ending with a period
  • If more detail is needed, leave a blank line after the summary
  • The closing """ goes on its own line for multi-line docstrings
def connect(host: str, port: int = 5432) -> Connection:
    """Establish a database connection.

    Opens a TCP connection to the specified host and port,
    performs the authentication handshake, and returns a
    ready-to-use Connection object.
    """

Three Major Styles

Google Style

Popular for its readability in source code. Sections use indented blocks under plain-text headings:

def retry(func, max_attempts=3, delay=1.0):
    """Retry a function call on failure.

    Calls the given function up to max_attempts times, waiting
    delay seconds between attempts. Returns the first successful
    result or raises the last exception.

    Args:
        func: A callable to invoke.
        max_attempts: Maximum number of attempts before giving up.
        delay: Seconds to wait between retries.

    Returns:
        The return value of a successful func() call.

    Raises:
        RuntimeError: If all attempts fail.

    Example:
        >>> result = retry(fetch_data, max_attempts=5)
    """

NumPy Style

Common in scientific Python. Uses underlined section headers and a more structured format:

def interpolate(x, y, method="linear"):
    """Interpolate a dataset.

    Compute interpolated values using the specified method.

    Parameters
    ----------
    x : array_like
        The x-coordinates of the data points.
    y : array_like
        The y-coordinates of the data points.
    method : str, optional
        Interpolation method: 'linear', 'cubic', or 'nearest'.
        Default is 'linear'.

    Returns
    -------
    callable
        A function that accepts new x values and returns
        interpolated y values.

    See Also
    --------
    scipy.interpolate.interp1d : SciPy's interpolation function.
    """

reStructuredText (reST) Style

The native Sphinx format. Uses field-list syntax:

def send_email(to, subject, body):
    """Send an email message.

    :param to: Recipient email address.
    :type to: str
    :param subject: Email subject line.
    :type subject: str
    :param body: Email body content.
    :type body: str
    :returns: Message ID of the sent email.
    :rtype: str
    :raises SMTPError: If the mail server rejects the message.
    """

Which Style to Choose?

FactorGoogleNumPyreST
Readability in sourceBestGoodDense
Sphinx supportVia NapoleonVia NapoleonNative
Common inWeb/app developmentData scienceOlder projects
IDE renderingExcellentGoodGood

Recommendation: Google style for most projects. NumPy style if your team works heavily with scientific Python. Avoid reST style for new projects — it’s verbose and harder to read in source.

What to Document

Functions and Methods

  • What the function does (first line)
  • Parameters with types and meaning
  • Return value with type
  • Exceptions that callers should handle
  • Examples for non-obvious usage

Classes

Document the class purpose at the class level and __init__ parameters either at the class level or in __init__:

class RateLimiter:
    """Controls request rate to external services.

    Uses a token bucket algorithm to enforce rate limits.
    Thread-safe for concurrent usage.

    Args:
        rate: Maximum requests per second.
        burst: Maximum burst size above the sustained rate.
    """

    def __init__(self, rate: float, burst: int = 10):
        ...

Modules

A module docstring at the top of the file explains the module’s purpose:

"""HTTP client with automatic retry and circuit breaking.

This module provides a high-level HTTP client that handles
transient failures, rate limiting, and connection pooling.

Typical usage:
    client = HttpClient(base_url="https://api.example.com")
    response = client.get("/users")
"""

Enforcing Docstring Quality

pydocstyle

Checks docstrings against PEP 257 and style conventions:

pip install pydocstyle
pydocstyle my_package/ --convention=google

ruff

ruff includes pydocstyle rules (the D rule set):

# pyproject.toml
[tool.ruff.lint]
select = ["D"]

[tool.ruff.lint.pydocstyle]
convention = "google"

interrogate

Measures docstring coverage:

pip install interrogate
interrogate my_package/ -v --fail-under 80

This ensures at least 80% of public functions have docstrings.

Common Misconception

“Type hints replace docstrings.” Type hints tell you what types go in and come out. Docstrings tell you what the function does, why parameters matter, and when exceptions are raised. They serve different purposes. timeout: int tells you it is an integer; the docstring tells you it is in seconds, that zero means no timeout, and that negative values raise ValueError.

The one thing to remember: Pick one docstring style for your entire project, enforce it with a linter, and focus on writing why and when, not just what — type hints already cover the what.

pythondocumentationbest-practices

See Also