Description
Using the latest uv
:
$ uv --version
uv 0.2.21 (ebfe6d8fc 2024-07-03)
Use-case
I have a test workflow for my click-extra
project which boils down to:
$ python -m pip install uv
$ uv venv --system
$ uv pip install --all-extras --requirement pyproject.toml .
$ uv run pytest
Everything's good as it is.
But now I want to override some of the default dependencies specified in pyproject.toml
. My use-case is to test unreleased upstream dependencies, so I can anticipate upcoming breaking changes.
What I used to do with Poetry was to locally add these new dependencies as-is:
$ poetry add git+https://github.com/pallets/click.git#main
Migrating to uv
, my new workflow looks like this:
$ uv venv --system
$ uv pip install --all-extras --requirement pyproject.toml .
$ uv pip install "git+https://github.com/pallets/click.git#main"
$ uv run pytest
But this doesn't work as I expected. As soon as I call uv run pytest
, the locally installed Click is discarded, and replaced by the canonical requirement from pyproject.toml
:
$ cat pyproject.toml
[project]
name = "click-extra"
version = "4.8.4"
dependencies = [
"click ~= 8.1.4",
(...)
See how I installed the click==8.2.0.dev0
version I am looking for:
$ uv pip install --all-extras --requirement pyproject.toml .
Resolved 72 packages in 2.20s
Audited 72 packages in 0.63ms
$ uv pip tree | grep click
click-extra v4.8.4
├── click v8.1.7
│ └── click v8.1.7
$ uv pip install "git+https://github.com/pallets/click.git#main"
Updated https://github.com/pallets/click.git (14f735c)
Resolved 1 package in 1.86s
Uninstalled 1 package in 4ms
Installed 1 package in 2ms
- click==8.1.7
+ click==8.2.0.dev0 (from git+https://github.com/pallets/click.git@14f735cf59618941cf2930e633eb77651b1dc7cb)
And then have uv run pytest
re-installing back click==8.1.7
:
$ uv run pytest
warning: `uv run` is experimental and may change without warning.
Resolved 77 packages in 890ms
Built click-extra @ file:///Users/kde/click-extra
Prepared 1 package in 1.06s
Uninstalled 2 packages in 3ms
Installed 2 packages in 2ms
- click==8.2.0.dev0 (from git+https://github.com/pallets/click.git@14f735cf59618941cf2930e633eb77651b1dc7cb)
+ click==8.1.7
- click-extra==4.8.4 (from file:///Users/kde/click-extra)
+ click-extra==4.8.4 (from file:///Users/kde/click-extra)
================== test session starts ==================
platform darwin -- Python 3.12.4, pytest-8.2.2, pluggy-1.5.0
(...)
--override
workaround
Digging into uv
help, I stumble upon the --override
option, which seems to be the way to do what I want.
So I now have:
$ cat ./overrides.txt
click @ git+https://github.com/pallets/click.git#main
And using it ends up with the right dependencies:
$ uv pip install --all-extras --requirement pyproject.toml --override ./overrides.txt .
Updated https://github.com/pallets/click.git (14f735c)
Resolved 72 packages in 4.15s
Built click-extra @ file:///Users/kde/click-extra
Prepared 1 package in 765ms
Uninstalled 2 packages in 3ms
Installed 2 packages in 1ms
- click==8.1.7
+ click==8.2.0.dev0 (from git+https://github.com/pallets/click.git@14f735cf59618941cf2930e633eb77651b1dc7cb)
- click-extra==4.8.4 (from file:///Users/kde/click-extra)
+ click-extra==4.8.4 (from file:///Users/kde/click-extra)
$ uv pip tree | grep click
click-extra v4.8.4
├── click v8.2.0.dev0
│ └── click v8.2.0.dev0
Which seems to do the trick. But again, uv run
is reverting my override:
$ uv run pytest
warning: `uv run` is experimental and may change without warning.
Resolved 77 packages in 1.00s
Built click-extra @ file:///Users/kde/click-extra
Prepared 1 package in 558ms
Uninstalled 2 packages in 1ms
Installed 2 packages in 2ms
- click==8.2.0.dev0 (from git+https://github.com/pallets/click.git@14f735cf59618941cf2930e633eb77651b1dc7cb)
+ click==8.1.7
- click-extra==4.8.4 (from file:///Users/kde/click-extra)
+ click-extra==4.8.4 (from file:///Users/kde/click-extra)
================== test session starts ==================
platform darwin -- Python 3.12.4, pytest-8.2.2, pluggy-1.5.0
(...)
--override
not supported by uv run
So maybe I need to use --override
on uv run
. But it is not supported:
$ uv run --override ./overrides.txt pytest
error: unexpected argument '--override' found
tip: a similar argument exists: '--preview'
Usage: uv run [OPTIONS] <COMMAND>
For more information, try '--help'.
$ uv --override ./overrides.txt run pytest
error: unexpected argument '--override' found
tip: a similar argument exists: '--preview'
Usage: uv <--quiet|--verbose...|--no-color|--color <COLOR_CHOICE>|--native-tls|--no-native-tls|--offline|--no-offline|--toolchain-preference <TOOLCHAIN_PREFERENCE>|--toolchain-fetch <TOOLCHAIN_FETCH>|--preview|--no-preview|--isolated|--show-settings> <COMMAND>
For more information, try '--help'.
Should we requalify this ticket into a feature request to have --override
supported by the run
subcommand?
New --no-upgrade
option for uv run
?
Another alternative is maybe to have a --no-upgrade
option on uv run
to tell it to not make any changes to the currently installed dependencies.
That might be the opposite of the existing -U/--upgrade
parameter:
-U, --upgrade
Allow package upgrades, ignoring pinned versions in any existing output file