Skip to main content

pydocformatter

PyPI version Python versions CI Coverage gate: >=95% Platform compatibility Documentation License: GPL-3.0-or-later

pydocformatter is a Ruff-like Python docstring formatter and docstring linter that also formats source comments, including those in fenced Python blocks in Markdown. Its pydocfmt command reports precise rule findings, applies fixes when source changes are safe, and leaves ambiguous or content-creating decisions to the author.

pydocformatter handles documentation and comment source; it does not format ordinary Python expressions or statements. Use it alongside Ruff or another general Python formatter.

Try it

Install the command, check the current repository without changing it, and preview safe fixes:

uv tool install pydocformatter
pydocfmt check
pydocfmt check --diff

Continue with the documentation or inspect the source repository.

Why pydocformatter?

  • It formats prose in docstrings and comments while preserving supported doctests, code fences, directives, lists, tables, and other structured regions.
  • It understands PEP 257, Google-style docstrings, NumPy-style docstrings, and reStructuredText conventions instead of treating every docstring as unstructured text.
  • It checks semantic relationships such as parameter, return, yield, exception, and attribute documentation with precise rule-level diagnostics.
  • It follows a conservative fix model: mechanically safe changes can be automated, while ambiguous rewrites and missing human-authored content remain findings for the author.

Who should use this?

  • Projects that already use Ruff, Black, pre-commit, or similar quality tools and want consistent docstrings and comments too.
  • Libraries and applications with substantial API documentation or prose embedded in source.
  • Teams that enforce a Google, NumPy, reStructuredText, or PEP 257 docstring convention and want formatting plus documentation-consistency checks.

Before and after

This realistic Google-style function combines prose, structured parameter documentation, a protected reStructuredText code directive, and a long source comment. pydocformatter wraps the prose it can change safely, preserves the code example, and leaves the missing default_role documentation and overlong summary for the author.

[settings]
line-length = 88
docstring-convention = "google"

[input]
"""User configuration helpers."""


def load_user(path, default_role):
    """
    Loads a user record from disk and returns normalized settings for the application with predictable defaults.

    Args:
        path: Path to the user configuration file.

    Examples:
        .. code-block:: python

            record = load_user("settings-for-a-very-long-environment-name.toml", default_role="viewer")
    """
    # Keep the fallback role in the returned record so callers can handle incomplete configuration files consistently across environments.
    return {"path": path, "role": default_role}

[output]
"""User configuration helpers."""


def load_user(path, default_role):
    """Loads a user record from disk and returns normalized settings for the application
    with predictable defaults.

    Args:
        path: Path to the user configuration file.

    Examples:
        .. code-block:: python

            record = load_user("settings-for-a-very-long-environment-name.toml", default_role="viewer")
    """
    # Keep the fallback role in the returned record so callers can handle incomplete
    # configuration files consistently across environments.
    return {"path": path, "role": default_role}

[findings]
PDF203: Lines 5-6: Docstring summary spans 2 lines and does not fit on one line
PDF500: Line 4: Function parameter 'default_role' is missing docstring documentation

PDF101 and PCF000 apply the safe wrapping changes. PDF203 and PDF500 remain as diagnostic-only findings for the author to resolve.

What it does

  • Reflows docstring and comment prose, normalizes source layout, and preserves supported structured regions such as doctests, code fences, directives, lists, tables, and block quotes.
  • Understands PEP 257, Google, NumPy, and reStructuredText docstring conventions, including semantic sections and documented parameters, returns, yields, exceptions, and attributes.
  • Formats standalone and trailing comments while protecting recognized type-checker, linter, formatter, security, and IDE directives.
  • Checks and formats supported python, py, and python3 fenced blocks in Markdown while preserving surrounding text.
  • Selects independently documented PCF comment rules and PDF docstring rules, with per-rule diagnostics and explicit fix availability.
  • Uses Ruff-style configuration, file discovery, selectors, per-file ignores, fixability controls, source suppressions, and inspection commands.
  • Preserves evaluated docstring values for source-literal rewrites that require semantic equivalence, while content-formatting rules may intentionally change docstring whitespace, and avoids automatic changes when the intended source rewrite or missing documentation cannot be inferred safely.

Documentation and help

The documentation site is the complete user guide and reference. These links go directly to the relevant help:

Need Resource
Install and complete a first run Tutorial and Installation
Compare tools and inspect a complete tested transformation Comparison and Demonstration
Understand safe formatting and assign tool ownership Why docstrings are hard to format safely and Docstring formatting in a Ruff project
Configure pydocfmt Configuration and generated Settings
Configure the Ruff integration Ruff rule links
Understand a rule or browse available rules Rules or pydocfmt rule RULE
Choose or inspect active, ignored, per-file, and fixable rules Rule selection and pydocfmt check --show-rules
Understand checking, fixing, suppressions, and file discovery Checking, Formatting, Rule suppressions, and File selection
Add pre-commit, CI, or editor workflows Integrations
Understand compatibility, rule lifecycle, and fix guarantees Versioning
Resolve common questions FAQ, pydocfmt --help, pydocfmt check --help, and pydocfmt config SETTING
Report a bug or propose a change GitHub Issues

Installation

pydocformatter officially supports CPython 3.11 or newer. Compatibility with PyPy and GraalPy is intended but is not currently verified or guaranteed. LibCST's native parser does not publish binary wheels for these implementations, so installation may require an unverified source build. Jython and IronPython are unsupported. Ubuntu 20.04 and newer and macOS 14 and newer are supported. Other POSIX Linux systems, including musl-based distributions, receive best-effort support. Native Windows and WSL are unsupported.

Git is conditionally required for the default gitignore-aware recursive file discovery inside Git worktrees. Install Git or pass --no-respect-gitignore when that filtering is not wanted.

Add pydocformatter to a project as a development dependency with uv:

uv add --dev pydocformatter
uv run pydocfmt --version

To install the command independently of a project environment:

uv tool install pydocformatter

See Installation for pip, pipx, and Git pre-commit alternatives. If pydocfmt is already available on PATH, omit uv run from the commands below.

Quick start

Run pydocformatter from a project root to check discovered Python and Markdown files without changing them:

uv run pydocfmt check

Preview automatic fixes as a unified diff, or apply them in place:

uv run pydocfmt check --diff
uv run pydocfmt check --fix

Pass files or directories to limit the run, for example uv run pydocfmt check src tests. With no paths, pydocformatter checks the current directory. Check mode returns a nonzero exit status when it finds rule violations or operational errors, which makes the same command suitable for CI.

Persistent cache

pydocformatter caches strict clean proofs for selected disk files by default. A warm hit still discovers the file and verifies its complete raw contents, settings, selected rules, implementation, and package-path semantics, but skips UTF-8 decoding, LibCST parsing, and rule execution. The cache stores hashes and metadata only, never source text or diagnostics. Cache failures fall back to normal analysis without changing status; a missing or non-directory immediate cache parent also emits one warning.

The default cache is .pydocfmt_cache below the auto-discovered project root. Disable reuse for diagnostics or untrusted restored cache data, inspect opt-in counters, or remove only pydocfmt-owned cache data with:

uv run pydocfmt check --no-cache
uv run pydocfmt check --cache-stats
uv run pydocfmt clean
uv run pydocfmt clean --cache-dir PATH

Use cache-dir or --cache-dir PATH to choose another location. pydocformatter may create that directory, but its immediate parent must already exist as a directory; it does not create missing ancestors. An owned run cache directory below a checked tree is pruned automatically during file discovery; a non-empty unowned directory receives normal include and exclude handling. The persistent cache reference documents invalidation, mode reuse, storage, cleanup, failures, security, statistics, and performance expectations.

Configuration

Place project settings in pyproject.toml. A small configuration might specify only the shared line length and the project's docstring convention:

[tool.pydocfmt]
line-length = 88

[tool.pydocfmt.docstring]
convention = "google"

Sources assigned to Markdown automatically use source-context = "fragment" and docstring-missing-documentation = "has-section". These language-aware defaults avoid complete-module and missing-definition assumptions while retaining checks for documentation that an example contains, and they apply to custom Markdown extensions too. Matching per-file settings can opt selected files into complete-module semantics. Add pydocfmt-skip after a supported fence language for an intentionally malformed or deliberately nonconforming block.

By default, .py, .pyi, and .pyw select Python handling, while .md selects Markdown handling. Map an additional extension separately from directory discovery when a project needs one:

[tool.pydocfmt]
extend-include = ["*.mdx"]

[tool.pydocfmt.extension]
mdx = "markdown"

Inspect the resolved configuration, discovered files, and active rules before changing source:

uv run pydocfmt check --show-settings
uv run pydocfmt check --show-files
uv run pydocfmt check --show-rules
uv run pydocfmt rule PDF101

Use uv run pydocfmt config to list every setting, or pass a setting name such as uv run pydocfmt config line-length for focused help. The documentation table above links the full configuration, settings, rule-selection, and Ruff-compatibility references.

More examples

In each example, [settings] or Settings (when present) shows the relevant pydocformatter settings used, including pertinent defaults. [input] or Before shows the original source, [output] or After shows the source after automatic fixes, and [findings] or Findings shows the diagnostics that remain afterward (not auto-fixable).

Trailing comments and stale suppressions

This retry helper contains an overlong trailing explanation and a suppression that no longer suppresses anything. Moving the explanation and removing the obsolete directive are separate policy decisions, so the relevant rules expose them separately.

[settings]
line-length = 72

[input]
"""Retry policy helpers."""


def _retry_delay(attempt):
    # pydocfmt: ignore[PCF000]
    # Keep retry delays bounded.
    delay = min(2**attempt, 60)#Cap exponential backoff so temporary failures do not stall a worker indefinitely.
    return delay

[output]
"""Retry policy helpers."""


def _retry_delay(attempt):
    # pydocfmt: ignore[PCF000]
    # Keep retry delays bounded.

    # Cap exponential backoff so temporary failures do not stall a
    # worker indefinitely.
    delay = min(2**attempt, 60)
    return delay

[findings]
PCF101: Line 5: Suppression selector 'PCF000' did not suppress any findings

PCF001 normalizes the trailing-comment delimiter before PCF002 moves and wraps the explanation. The blank line preserves separation from the independently authored comment above it. PCF101 reports the stale suppression but deliberately does not delete it.

Using pydocformatter with Ruff

pydocformatter is intended to own docstring and comment formatting where its rules overlap with Ruff. Align shared settings such as indentation and line endings, and disable Ruff rules that would enforce the same docstring or comment policy. The Ruff rule links page provides a paired configuration and rule-by-rule compatibility mapping.

Contributing

See Contributing for the development environment, rule implementation workflow, documentation pipeline, and pull request checks. Project history and current unreleased changes are recorded in the Changelog.

License

pydocformatter is licensed under the GNU General Public License v3.0 or later.

Acknowledgments

pydocformatter draws inspiration from pyformatter, docformatter, and established Python formatting tools such as Ruff.

Metadata

Release files for pydocformatter 1.2.1

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for pydocformatter 1.2.1
File Size Uploaded
pydocformatter-1.2.1.tar.gz 1.0 MB Details

Built distribution (wheel)

Table of built distributions (wheels) for pydocformatter 1.2.1
File Interpreter ABI Platform
pydocformatter-1.2.1-py3-none-any.whl Python 3 none any Details

Total release size: 1.8 MB

Release files / pydocformatter-1.2.1.tar.gz

Download URL pydocformatter-1.2.1.tar.gz
Size 1.0 MB
Tags Source
SHA-256 checksum
How to use checksums
fa0bc7ea4b65ec3abc1bff89877974f33b0e9a4a0502287afe773a27111cef36
BLAKE2b-256 checksum
How to use checksums
3fd3fa60fd0a99d5964a23ca8a06e9ab1ac9114319fdcb01a48f66d5f9d92a96
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via uv/0.11.3 {"installer":{"name":"uv","version":"0.11.3","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"20.04","id":"focal","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}

Release files / pydocformatter-1.2.1-py3-none-any.whl

Download URL pydocformatter-1.2.1-py3-none-any.whl
Size 785.2 kB
Tags Python 3
SHA-256 checksum
How to use checksums
896e42be62f2d4918eb3a27190b5d1f9e63078c11c3627a44b439b6ebb4f6aed
BLAKE2b-256 checksum
How to use checksums
faaa1fa5e631f1944f24c630ee7080e0d31e68394d69820470c5d4d24284cb07
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via uv/0.11.3 {"installer":{"name":"uv","version":"0.11.3","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"20.04","id":"focal","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}

Release history Release notifications | RSS feed

This release

1.2.1 This release

2 release files

1.2.0

2 release files

1.1.0

2 release files

1.0.0

2 release files

0.2.0

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page