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

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.15
File Size Uploaded
pypfmt-1.1.15.tar.gz 14.3 kB Details

Built distribution (wheel)

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

Total release size: 30.2 kB

Release files / pypfmt-1.1.15.tar.gz

Download URL pypfmt-1.1.15.tar.gz
Size 14.3 kB
Tags Source
SHA-256 checksum
How to use checksums
a0816df7148337a747ca1ad8979b6e556ec21cc38f25a5803d0f2360b36db337
BLAKE2b-256 checksum
How to use checksums
20c9ef983be12a85ccad13ada28c4db70668a0cf8f9dd609b749676c8390925a
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via uv/0.12.15 {"installer":{"name":"uv","version":"0.12.15","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.15-py3-none-any.whl

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

This release

1.1.15 This release

2 release files

1.1.14

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