Skip to main content

docfmt

Reliable docstring formatter for Python

Python versions PyPI Tests Coverage Code style: black

Motivation

Docstring formatters that rebuild the file from a token stream are prone to a particular class of bug: edits computed against one version of the token list get applied to another, so behavior depends on how much unrelated code precedes the docstring being formatted. The symptom is formatting that changes when you add or remove an unrelated class elsewhere in the file.

docfmt is built so that cannot happen:

  • Docstrings are located by AST structure, never by token heuristics or by matching line contents.
  • The file is never regenerated. Formatting produces a set of non-overlapping character-range replacements against the original source; everything outside a docstring is preserved byte-for-byte.
  • Results are verified before they are written. Every formatted file is checked for AST equivalence (nothing changed but docstring contents) and for idempotency (format(format(x)) == format(x)). A failure leaves the file untouched and reports an internal error rather than writing a bad result.

Behavior

docfmt normalizes docstring layout and never mutates author text. Adding a trailing period is the one exception, and it is opt-in (--add-summary-period).

Blank lines around docstrings are preserved by default. Normalization is opt-in per position under [tool.docfmt.blank-lines].

Structured content is copied verbatim and never rewrapped: fenced code blocks, MyST directives, doctests, reST directives and field lists, tables, and lists.

MyST directives

MyST directives nest by widening the fence, so fence length is significant:

```{note}
Test note
```

A block closes only on a fence of the same character with at least as many markers and no info string, so a narrower inner fence is content:

````{note}
```{warning}
Test warning
```
````

Inline constructs such as `False`{l=python} are treated as unbreakable atoms, so wrapping never splits an inline code span from its role attribute.

Attribute docstrings

A string statement immediately following an assignment at module or class level is an attribute docstring, including annotation-only attributes:

package: str
"""
Import name of the package.
"""

Usage

docfmt --in-place --recursive src test
docfmt --check src        # exit 1 if anything would change
docfmt --diff src

Configure via [tool.docfmt] in pyproject.toml:

[tool.docfmt]
in-place = true
recursive = true
summary-on-own-line = true
Key Default Meaning
line-length black's, else 88 wrap width; 0 disables wrapping
summary-on-own-line false put the summary below the opening quotes
blank-after-description false blank line before the closing quotes
force-reflow false refill prose that already fits
add-summary-period false append a period to summaries
exclude [] path fragments to skip when recursing

line-length is left unset by default and picked up from [tool.black] line-length when black is configured, falling back to 88.

Blank-line rules live in their own table. Each is a count, or "preserve" to leave the author's spacing alone:

[tool.docfmt.blank-lines]
before-class = "preserve"
after-module = 1
after-class = 1
after-function = "preserve"
after-attribute = 1

Exit codes

Code Meaning
0 Nothing to do, or changes written in in-place mode
1 Check mode: files would change
2 Error; no file was modified

Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

docfmt-0.1.0.tar.gz (16.0 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

docfmt-0.1.0-py3-none-any.whl (20.5 kB view details)

Uploaded Python 3

File details

Details for the file docfmt-0.1.0.tar.gz.

File metadata

  • Download URL: docfmt-0.1.0.tar.gz
  • Upload date:
  • Size: 16.0 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: uv/0.11.25 {"installer":{"name":"uv","version":"0.11.25","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}

File hashes

Hashes for docfmt-0.1.0.tar.gz
Algorithm Hash digest
SHA256 6877ada2317698f5f2f3c3738ba823820eeb804e2d873a0a40838688e950bfc0
MD5 ba202c324d69e85c194de835cf423def
BLAKE2b-256 4b7fe8c68ccb844b62c0aced64e33544f4c6a98d371091b82df2b766091c9d59

See more details on using hashes here.

File details

Details for the file docfmt-0.1.0-py3-none-any.whl.

File metadata

  • Download URL: docfmt-0.1.0-py3-none-any.whl
  • Upload date:
  • Size: 20.5 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: uv/0.11.25 {"installer":{"name":"uv","version":"0.11.25","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}

File hashes

Hashes for docfmt-0.1.0-py3-none-any.whl
Algorithm Hash digest
SHA256 aa0b085328e9208d80c559e7348ec06b581f04f2b528558bfff5b18bc56127f0
MD5 ce0e898caccc8b55e9cf2aae3e84b1a2
BLAKE2b-256 80b8473c2a2d3848dc0c0cd74103cd949ca13870471b10ac562eb4b401921383

See more details on using hashes here.

Release history Release notifications | RSS feed

0.2.0

2 files

This release

0.1.0 This release

2 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