Skip to main content

PyPI Rust uv CI Docs Integration 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)

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`
uv-align -y numpy matplotlib       # Update only the specified packages
uv-align -yu numpy matplotlib      # Upgrade and update only the specified packages

Example output:

Example Usage

Usage

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

Usage: uv-align [OPTIONS] [PACKAGES]...

Arguments:
  [PACKAGES]...  Specific packages to check or sync (if none specified, all packages are checked)

Options:
      --path <PATH>  Path to folder containing `pyproject.toml` and `uv.lock` files [default: .]
      --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, extras, 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. 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. Without this flag, 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. If specific packages are provided (e.g. uv-align -u numpy), uv lock --upgrade-package numpy is run instead, restricting the upgrade to only those packages. 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.

Issues

If you encounter any issues, please report them on the GitHub Issues page. Please provide a brief description of how you tried to run the tool, the command you ran, and the output in the terminal. Also, provide the contents of your pyproject.toml, the expected updated pyproject.toml, and your uv.lock file if possible.

See the integration tests which use these test fixtures to understand how these three files will help reproduce the issue and aid in fixing it.

License

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

Metadata

Release files for uv-align 0.2.0

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

Built distributions (wheels)

Table of built distributions (wheels) for uv-align 0.2.0
File
uv_align-0.2.0-py3-none-win_amd64.whl Python 3 none Windows x86-64 Details
uv_align-0.2.0-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl Python 3 none Linux glibc 2.17+ x86-64 Details
uv_align-0.2.0-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl Python 3 none Linux glibc 2.17+ ARM64 Details
uv_align-0.2.0-py3-none-macosx_11_0_arm64.whl Python 3 none macOS 11.0+ ARM64 Details
uv_align-0.2.0-py3-none-macosx_10_12_x86_64.whl Python 3 none macOS 10.12+ x86-64 Details

Total release size: 3.5 MB

Release files / uv_align-0.2.0-py3-none-win_amd64.whl

Download URL uv_align-0.2.0-py3-none-win_amd64.whl
Size 585.6 kB
Tags Python 3 Windows x86-64
SHA-256 checksum
How to use checksums
8555f42876ea44c914967e5459b57c8e2cf164e055130e109972161f4942d3b7
BLAKE2b-256 checksum
How to use checksums
00fee6f7664d97b8fc61532e57b4046b948dca61f2c6219e9fe78d126fe74d80
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Oct 4, 2026.

Transparency log

Release files / uv_align-0.2.0-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl

Download URL uv_align-0.2.0-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
Size 771.6 kB
Tags Linux glibc 2.17+ x86-64 Python 3
SHA-256 checksum
How to use checksums
8252545449f2be3dd4e4a851535494ef867b8fadb49ac6c2a11e9c2b43f3f577
BLAKE2b-256 checksum
How to use checksums
edb5e57efdddc9ade1fb52d629c43b030081e31ccaa3f3951d69af71994149f8
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Oct 4, 2026.

Transparency log

Release files / uv_align-0.2.0-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl

Download URL uv_align-0.2.0-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl
Size 753.6 kB
Tags Linux glibc 2.17+ ARM64 Python 3
SHA-256 checksum
How to use checksums
2d9815a481d1eaac2f16fa444e3ab96fd824fc327f1c24ac830ef5cf2f7b76b0
BLAKE2b-256 checksum
How to use checksums
f049277fcb39e3395edcda69a967b9b954b88ce7774118746d37efc547726fb4
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Oct 4, 2026.

Transparency log

Release files / uv_align-0.2.0-py3-none-macosx_11_0_arm64.whl

Download URL uv_align-0.2.0-py3-none-macosx_11_0_arm64.whl
Size 704.6 kB
Tags Python 3 macOS 11.0+ ARM64
SHA-256 checksum
How to use checksums
af55cfb9c7805c7530d659129bd84257812ed74429266ae06ed8ff2f1025de50
BLAKE2b-256 checksum
How to use checksums
98fa091bfcbc10ecd6b2d8286a6628dcb6128082f89b09b986fbdd4d5bdd4d2d
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Oct 4, 2026.

Transparency log

Release files / uv_align-0.2.0-py3-none-macosx_10_12_x86_64.whl

Download URL uv_align-0.2.0-py3-none-macosx_10_12_x86_64.whl
Size 719.4 kB
Tags Python 3 macOS 10.12+ x86-64
SHA-256 checksum
How to use checksums
66bbe9da4eb5b29304ab231914711bb2527b302bb8c82c82d3f1b5de1e7b8b3a
BLAKE2b-256 checksum
How to use checksums
588a0638aec984213d012bd79316097288f245803bb3932203583ce067699e37
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Oct 4, 2026.

Transparency log

Release history Release notifications | RSS feed

0.2.1

5 release files

This release

0.2.0 This release

5 release files

0.1.4

5 release files

0.1.3

5 release files

0.1.2

5 release files

0.1.1

5 release files

0.1.0

5 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