Skip to main content

Upgrade versions of dependencies in pyproject.toml files in uv-managed projects.

Project description

Uv upgrade

Upgrade dependencies in pyproject.toml files with uv.


Install

For end-users.

Note: For developers, see the dev section.

Uv install or update

You need this for both usage and development.

https://docs.astral.sh/uv/getting-started/installation/

On Windows it can be better to use Git Bash terminal.

if ! command -v uv &> /dev/null; then
    curl -LsSf https://astral.sh/uv/install.sh | sh;
else
    uv self update;
fi

uv --version

Install or update a project for system-wide usage

Run it from any directory, except the project directory.

This will install or upgrade the tool.

if ! command -v uv-upx &> /dev/null; then
    uv tool install uv-upx
else
    uv tool upgrade uv-upx
fi

uv-upgrade --version

Or run advanced version with uvx:

uvx uv-upx

Dev installation: see here

Check that project in the list

uv tool list --show-python

Remove the project with all data

If you need to remove the project with all data, run this command from the project directory:

uv tool uninstall uv-upx

Usage

Run the tool in the folder with the pyproject.toml

After installation, you can run the tool from any directory.

uv-upgrade

or

uv-upx upgrade run

It is the same. But uv-upx provides more features.

Get help

You can run commands with the --help flag with more details.

Exported versions:

Install CLI completion (Optional)

This will install completion for the current shell. Available after restarting the shell.

for uv-upgrade:

uv-upgrade --install-completion

for uv-upx:

uv-upx --install-completion

Note: relatively safe to run multiple times. It just adds extra newlines to your shell config when run multiple times.

Notes

Uv as a source of truth

Run uv sync --all-groups --all-extras --all-packages --upgrade.

Get dependencies versions from uv.lock.

Put them in pyproject.toml files in related groups.

So, the main responsibility for dependencies resolution is on uv.

Workspace support

It works with workspaces. At least for some basic cases.

Respects:

  • both members and exclude sections.
  • glob-based patterns.

Normalize dependencies names

For example:

  • TOMLKit -> tomlkit
  • Pydantic -> pydantic
  • pyTEST_BenchMark -> pytest-benchmark

Updates simple dependencies

Updates >= dependencies. Like bla>=2.0.0.

Because, in this case, we can simply put the new version instead of the old one.

Update the similar part of the constraint in the multi-constraint.

Skip pinned versions and upper bounds

It doesn't touch pinned versions. Like bla==2.0.0.

It doesn't touch lower bounds. Like:

  • bla<=2.0.0
  • bla~=2.0.0

Respect simple ranges and some combined constraints

It respects simple dependency ranges. Like bla>=1.0.0,<2.0.0.

It moves the lower bound to the new version.

In fact, it handles any part of the constraint with a supported operator.

Respect extras

It respects extras. Like bla[dev]>=1.0.0;python_version>="3.14".

Fix undefined constraints with lower bound to the new version

It sets undefined lower bounds to the new version.

For example, before:

dependencies = [
    "foo>=1.0.0",
    "bla",
]

After:

dependencies = [
    "foo>=1.0.0",
    "bla>=2.0.0",
]

Skip unhandled constraints

It skips unhandled and complex constraints. Like:

  • bla<1.0.0

Style preservation

It preserves comments in the pyproject.toml file. Like here:

dependencies = [
    # Better classes and data validation
    "pydantic>=2.12.5",
    # TOML parser and writer with preserved formatting
    "tomlkit>=0.13.3",
    # CLI app framework
    "typer>=0.20.0",
]

Rollback

If something goes wrong, it rolls back the changes to the pyproject.toml and uv.lock files.

Rollback on no-changes

If nothing from pyproject.toml was changed, it rolls back the changes to the uv.lock file.

So, only top-level dependencies changes trigger a uv.lock update.

Upgrade equal/pinned dependencies

Honestly, I think it's insecure to upgrade pinned dependencies automatically. Because they must be pinned for a reason.

For applications that require strict control of dependencies, maybe better to use frozen mode of uv sync.

But for someone it can be useful to upgrade pinned dependencies automatically.

And we can do it.

uv-upgrade --profile with_pinned

It handles only equal (==) and NOT strictly equal (===) operators.

So, even in this mode, it won't change bla===2.0.0.

Under the hood it:

  • collect all top-level dependencies information
  • changes == version constraints to >=
  • runs the standard upgrade process by uv
  • upgrade pyproject.toml files accordingly with returning == constraints back

Note: more upgrade profiles can be added later. Or/and custom verbose features options.

Note: Can be combined with --interactive mode.

Interactive mode

You can run the tool in interactive mode.

You must Accept or Reject each proposed change.

uv-upgrade --interactive

Demo example:

demo_interactive.png

Get special cases

This allows you to see all the top-level dependencies that have some special constraints. Like:

  • ranges (bla>=1.0.0,<2.0.0)
  • not defined bounds (bla)
  • equal/pinned dependencies (bla==2.0.0)
  • unhandled constraints (bla<1.0.0)
uv-upx helpers collect-top-level-dependencies-from-project --only-special-cases

Why?

I needed this for my own projects.

I know these issues:

But I didn't see enough progress.

So, I implemented this tool for my own usage.

Maybe it will be useful for someone else.

Why not in Rust?

Because it's a temporary Proof-of-Concept.

Maybe it will be replaced by Rust in the future.

It uses type annotations anyway. For simpler migration.


Dev

Dev


Other similar tools comparison

Other similar tools comparison

Project details


Download files

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

Source Distribution

uv_upx-0.4.3.tar.gz (20.8 kB view details)

Uploaded Source

Built Distribution

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

uv_upx-0.4.3-py3-none-any.whl (44.1 kB view details)

Uploaded Python 3

File details

Details for the file uv_upx-0.4.3.tar.gz.

File metadata

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

File hashes

Hashes for uv_upx-0.4.3.tar.gz
Algorithm Hash digest
SHA256 9768e8472f577ca5c6c40da05137bb3df253cf1af12b1a0b28d7068f6e7322fa
MD5 c9f19c055c7ec35f7b507d878614c2cc
BLAKE2b-256 ef798fe5ba7b9a1331e398dcb7cb6ccac3b845415ec9f0e202849bdad323ce39

See more details on using hashes here.

File details

Details for the file uv_upx-0.4.3-py3-none-any.whl.

File metadata

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

File hashes

Hashes for uv_upx-0.4.3-py3-none-any.whl
Algorithm Hash digest
SHA256 03aaf37cd889f704dabed35b678578a02aba85afa8d866545b2a53c0ec6ce239
MD5 dceb3b4cd2690a9d6f3f31ad940936c9
BLAKE2b-256 915375de2c6c8feb599e11f4053c3cb3f140ef33f688632e5c51b9d42d50e492

See more details on using hashes here.

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