Skip to main content

Align `pyproject.toml` dependency constraints with versions resolved by `uv`.

Project description

PyPI Rust uv CI Docs Publish Release License: MIT

uv-align

uv-align is a Rust command-line tool that keeps your Python dependency constraints in sync between pyproject.toml and uv.lock.

When you run uv lock --upgrade, uv resolves and updates uv.lock with the latest compatible versions, but leaves the version constraints in pyproject.toml untouched. This means your declared constraints can drift from what uv actually resolved - uv-align bridges that gap.

It reads the resolved versions from uv.lock and updates the version numbers in pyproject.toml accordingly, preserving your existing operators (>=, ==, etc.), upper bounds, environment markers, and formatting. It does not require a virtual environment as it does not install packages, and never modifies uv.lock directly (uv is responsible for that).

Links:

Table of Contents

Installation

As a tool (recommended)

If you use uv, you can install uv-align as a global tool:

uv tool install uv-align

If you'd like to run it without installing:

uvx uv-align

As a dev dependency

To pin uv-align to a specific project, add it to your development dependencies in pyproject.toml:

uv add uv-align --optional dev

As a pre-built binary

Pre-built binaries for Linux, macOS, and Windows are available on the GitHub Releases page.

Quick Guide

uv-align -h      # Show help message
uv-align --check # Check for out-of-sync dependencies between `pyproject.toml` and `uv.lock`
uv-align -y      # Update any out-of-sync version constraints in `pyproject.toml`
uv-align -yu     # Upgrade dependencies and update version constraints in `pyproject.toml`

Example output:

Example Usage

Usage

Align `pyproject.toml` dependency constraints with versions resolved by `uv`

Usage: uv-align [OPTIONS] [PATH]

Arguments:
  [PATH]  Path to folder containing `pyproject.toml` and `uv.lock` files [default: .]

Options:
      --check    Show a diff of dependency updates without applying them
  -y, --yes      Automatically apply all changes without prompting
  -u, --upgrade  Upgrade dependencies in `uv.lock` with `uv lock --upgrade`
  -v, --verbose  Show detailed information about dependency updates
  -h, --help     Print help

How It Works

uv-align is a file transformer - in its default mode it reads two files and writes one, with no network access or environment inspection. The optional --upgrade flag adds a uv invocation that does require network access to fetch updated package metadata.

Step 1 - Parse pyproject.toml

All dependency entries are read from three locations:

  • [project.dependencies] - main dependencies
  • [project.optional-dependencies] - extras groups (e.g. dev, docs)
  • [dependency-groups] - PEP 735 groups supported by uv

Each entry is parsed as a PEP 508 string. The package name, version operator (>=, ==, ~=, etc.), lower-bound version, and any suffix constraints (e.g. ,<1.0) are extracted separately. Git/URL dependencies (e.g. package @ git+https://...) are included in the parsed output but have no version to compare, so they are naturally skipped during the diff step. Extras (e.g. package[extra]) and environment markers (e.g. ; python_version >= '3.11') are stripped as they are not relevant to version bumping. Package names are normalised per PEP 503 (lowercase, runs of [-_.] collapsed to -) to ensure consistent matching.

Step 2 - Parse uv.lock

Every [[package]] entry in the lockfile is read to build a list of resolved package names and versions. Package names are normalised in the same way as step 1, so that my_package and my-package match correctly. Packages without a version field (git/URL sources) are skipped naturally by the parser.

Step 3 - Compute the diff

Each dependency from pyproject.toml that has a resolved version is looked up in the lockfile by its normalised name. If the resolved version differs from the declared version, a change is recorded. Version strings are compared after normalising trailing .0 components, so 0.25.0 and 0.25 are treated as equal and no spurious change is emitted.

Step 4 - Report or apply

In --check mode, the diff is printed and the tool exits with code 1 if any changes are needed (suitable for CI), or code 0 if everything is already in sync. Otherwise, the user is prompted to confirm before changes are applied (or -y skips the prompt). Changes are written back to pyproject.toml using toml_edit - a format-preserving TOML library that modifies only the version numbers, leaving all comments, whitespace, and key ordering intact. The original operator and any suffix constraints are preserved verbatim.

Step 5 - Upgrade mode (-u)

With --upgrade, uv lock --upgrade runs first to fetch and resolve the latest compatible versions, updating uv.lock accordingly. Steps 1–4 then run as normal to align pyproject.toml with the newly resolved versions. The number of updated, added, and removed packages reported by uv is printed as a summary, with full package details available via --verbose.

License

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

Project details


Download files

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

Source Distributions

No source distribution files available for this release.See tutorial on generating distribution archives.

Built Distributions

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

uv_align-0.1.2-py3-none-win_amd64.whl (566.4 kB view details)

Uploaded Python 3Windows x86-64

uv_align-0.1.2-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (763.2 kB view details)

Uploaded Python 3manylinux: glibc 2.17+ x86-64

uv_align-0.1.2-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl (745.4 kB view details)

Uploaded Python 3manylinux: glibc 2.17+ ARM64

uv_align-0.1.2-py3-none-macosx_11_0_arm64.whl (698.3 kB view details)

Uploaded Python 3macOS 11.0+ ARM64

uv_align-0.1.2-py3-none-macosx_10_12_x86_64.whl (714.8 kB view details)

Uploaded Python 3macOS 10.12+ x86-64

File details

Details for the file uv_align-0.1.2-py3-none-win_amd64.whl.

File metadata

  • Download URL: uv_align-0.1.2-py3-none-win_amd64.whl
  • Upload date:
  • Size: 566.4 kB
  • Tags: Python 3, Windows x86-64
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for uv_align-0.1.2-py3-none-win_amd64.whl
Algorithm Hash digest
SHA256 efb5971611ad8a58a6f1d402d0a19a21c6dfcb6a351f8d4e78b7ccfac3ed61b6
MD5 29cc9066188d495c6197a66fb7b669fa
BLAKE2b-256 cf640564c972364d0f02a9aadf032445b5081a87897b14651881603643f21113

See more details on using hashes here.

Provenance

The following attestation bundles were made for uv_align-0.1.2-py3-none-win_amd64.whl:

Publisher: publish.yml on javidahmed64592/uv-align

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file uv_align-0.1.2-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl.

File metadata

File hashes

Hashes for uv_align-0.1.2-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
Algorithm Hash digest
SHA256 7e94ea93b445985338a25401f3d538ecf697646c1cb44b496adb63e4a29cd10b
MD5 1dd7d500e41d58741aabf3080922f533
BLAKE2b-256 b02b489325f40cfad245c2eff14fbf69ad83e3f64d530e51ebbdc35bba2caf20

See more details on using hashes here.

Provenance

The following attestation bundles were made for uv_align-0.1.2-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl:

Publisher: publish.yml on javidahmed64592/uv-align

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file uv_align-0.1.2-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl.

File metadata

File hashes

Hashes for uv_align-0.1.2-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl
Algorithm Hash digest
SHA256 4225418b87e806e0651df3cab8fa5111575937ef7a40b9479e219281ab932dd0
MD5 aaef56ea2f7122244aabb82b696e342b
BLAKE2b-256 7020a0082f3482c9f9bc5b5a3a099b9b2c1f15604b17afde1674e90c8aa1dbec

See more details on using hashes here.

Provenance

The following attestation bundles were made for uv_align-0.1.2-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl:

Publisher: publish.yml on javidahmed64592/uv-align

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file uv_align-0.1.2-py3-none-macosx_11_0_arm64.whl.

File metadata

File hashes

Hashes for uv_align-0.1.2-py3-none-macosx_11_0_arm64.whl
Algorithm Hash digest
SHA256 10271c7a617e2a99791c8036e3900de694de058e09d3b7e9cb90983298cea537
MD5 e262683018a6b7c8769bf7b865c5a79a
BLAKE2b-256 8878b07a915b0a5aceb70155a7463c9e678630cec4f321cca8c7686a478464f3

See more details on using hashes here.

Provenance

The following attestation bundles were made for uv_align-0.1.2-py3-none-macosx_11_0_arm64.whl:

Publisher: publish.yml on javidahmed64592/uv-align

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file uv_align-0.1.2-py3-none-macosx_10_12_x86_64.whl.

File metadata

File hashes

Hashes for uv_align-0.1.2-py3-none-macosx_10_12_x86_64.whl
Algorithm Hash digest
SHA256 f9f868a7dbbd04489943c66189d4db14de0cf60a56eb6e13dbe5795f97e74caa
MD5 6c3cfe5fa072aaee78058a94f3be482e
BLAKE2b-256 d12170db0a89050f699ebf488f018203956f31b81e492218f3993bac3a582eaa

See more details on using hashes here.

Provenance

The following attestation bundles were made for uv_align-0.1.2-py3-none-macosx_10_12_x86_64.whl:

Publisher: publish.yml on javidahmed64592/uv-align

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page