Skip to main content

pypfmt

CI PyPI version codecov Python 3.11+ uv Ruff ty License: MIT

An opinionated formatter and sorter for pyproject.toml files. Produces deterministic, consistently-ordered output so you can diff configuration across many Python projects and copy settings between them without noise.

Features

  • Sort tables and keys with opinionated defaults — [project], [build-system], and [dependency-groups] always come first; common tool sections follow a predictable order
  • Format whitespace and style via taplo for consistent indentation, trailing commas, and column alignment
  • Preserve all data — no keys, values, or comments are lost or reordered when order matters (e.g. pytest.ini_options.addopts)
  • Idempotent — running the tool twice produces identical output
  • Pre-commit hook — drop-in integration with pre-commit
  • Configurable — override defaults per-project via [tool.pypfmt]

Installation

pip install pypfmt

Or using uv (recommended):

uv add pypfmt

Usage

Format files in-place

pypfmt pyproject.toml

Multiple files (useful for monorepos):

pypfmt services/*/pyproject.toml

Check mode (CI)

Exit non-zero if any file needs formatting, without modifying files:

pypfmt --check pyproject.toml

Diff mode

Print a unified diff of proposed changes without modifying files:

pypfmt --diff pyproject.toml

Combined check + diff

Print the diff and exit non-zero if changes are needed:

pypfmt --check --diff pyproject.toml

Stdin / stdout

Pipe input through pypfmt and receive formatted output on stdout:

cat pyproject.toml | pypfmt

Pre-commit hook

Add to your .pre-commit-config.yaml:

repos:
  - repo: https://github.com/bitflight-devops/pyproject-fmt
    rev: v1.0.0  # replace with the latest tag
    hooks:
      - id: pypfmt

language: python is used so pre-commit installs taplo and all other dependencies automatically.

Configuration

Add a [tool.pypfmt] section to your pyproject.toml to override defaults.

Sort order

[tool.pypfmt]
# Replace the root-level table ordering entirely
sort-first = ["project", "build-system", "dependency-groups"]

# Or append extra tables to the default ordering
extend-sort-first = ["my-custom-tool"]

# Disable alphabetical key sorting within tables
sort-table-keys = false

Per-table overrides

[tool.pypfmt]
# Extend the built-in per-table overrides
[tool.pypfmt.extend-overrides]
"tool.mypy" = { first = ["strict", "plugins"] }
"project.optional-dependencies.*" = { inline_arrays = true }

taplo formatting options

[tool.pypfmt]
# Replace all taplo options
taplo-options = ["column_width=100", "indent_string=  "]

# Or append extra options to the defaults
extend-taplo-options = ["column_width=100"]

Comment handling

[tool.pypfmt]
comments-header = true   # preserve file-level header comments (default: true)
comments-footer = true   # preserve file-level footer comments (default: true)
comments-inline = true   # preserve inline comments (default: true)
comments-block  = true   # preserve block comments (default: true)

Default opinionated behaviour

Behaviour Default
Root table order project, build-system, dependency-groups, then alphabetical
Tool section order hatch, git-cliff, uv, pytest, coverage, ty, ruff, mypy, …
Key order within [project] name, version, description, readme, dynamic, authors, maintainers, license, classifiers, keywords, requires-python, dependencies, then alphabetical
Classifiers Sorted alphabetically
Dependencies Sorted alphabetically
pytest.ini_options.addopts Preserved as-is (positional arguments)
keywords Preserved as-is (positional)
Inline comments Aligned
Indentation 4 spaces
Trailing commas in arrays Always added

Development

Prerequisites

  • Python 3.11+
  • uv for package management

Setup

git clone https://github.com/bitflight-devops/pyproject-fmt.git
cd pyproject-fmt
uv sync --all-groups

Running Tests

uv run poe test

# With coverage
uv run poe test-cov

# Across all Python versions
uv run poe test-matrix

Code Quality

# Run all checks (lint, format, type-check)
uv run poe verify

# Auto-fix lint and format issues
uv run poe fix

Pre-commit hooks (prek)

prek install
prek run --all-files

Documentation

uv run poe docs-serve

License

This project is licensed under the MIT License - see the LICENSE file for details.

Metadata

Release files for pypfmt 1.1.14

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

Source distribution (sdist)

Source distribution for pypfmt 1.1.14
File Size Uploaded
pypfmt-1.1.14.tar.gz 14.2 kB Details

Built distribution (wheel)

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

Total release size: 30.2 kB

Release files / pypfmt-1.1.14.tar.gz

Download URL pypfmt-1.1.14.tar.gz
Size 14.2 kB
Tags Source
SHA-256 checksum
How to use checksums
fad0ac1aa7d87114cd6ef944c666009e6fd7092a589a9030ae0d4c3513ddbc89
BLAKE2b-256 checksum
How to use checksums
6ac76d9086fe9f301efd401b0f501ba743e64bc87894b76a3b2ae52773586dd4
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via uv/0.12.7 {"installer":{"name":"uv","version":"0.12.7","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":true}

Release files / pypfmt-1.1.14-py3-none-any.whl

Download URL pypfmt-1.1.14-py3-none-any.whl
Size 15.9 kB
Tags Python 3
SHA-256 checksum
How to use checksums
9d3b98d6d6a167ecac552c4eba526755c49b5a19ed9c182bde0d9cc615712b51
BLAKE2b-256 checksum
How to use checksums
bafa33d90b07198b75d4d7208d25272be9ae6e05bef01e5ae1e96a0251be6788
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via uv/0.12.7 {"installer":{"name":"uv","version":"0.12.7","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":true}

Release history Release notifications | RSS feed

1.1.15

2 release files

This release

1.1.14 This release

2 release files

1.1.13

2 release files

1.1.12

2 release files

1.1.11

2 release files

1.1.10

2 release files

0.1.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