Fail on `uv pip install` in case of conflicting versions
Summary
Initially I install a package with uv pip install pkg<2. When there is another invocation uv pip install tool>2, uv silently reinstalls this version, even if it conflicts with the previous requirement.
This also shows up in real-world usage: in Zephyr projects, the install flow does uv pip install $(west packages pip), and a second uv pip install <more-packages> run later against the same venv can silently change package versions pinned by the first invocation — because uv pip install only treats the currently-installed version as a soft preference for the current resolve, with no memory of what was explicitly required in a previous call. This isn't caught at install time; it only surfaces later, at runtime, when the mismatched version breaks something, by which point it's hard to trace back to which install call caused it.
Expected behavior: a later uv pip install invocation whose requirement directly contradicts an earlier invocation's requirement should fail fast with a resolution conflict, the same way it would if both specifiers had been passed to a single uv pip install call — not silently succeed and leave the environment in a state that contradicts an earlier, still-relevant requirement.
uv's current default behavior (treating the installed version as a soft preference, not a hard constraint) shouldn't change, since plenty of workflows rely on being able to freely change versions across separate install calls. This is why an opt-in flag — analogous to git commit --amend — could make sense: --amend could consider previous invocations' explicit requirements as constraints, while plain uv pip install keeps behaving exactly as it does today. Alternative naming could be --safe
Example
uv pip install "tool>=1.0,<2" # resolves to e.g. tool==1.8.0
uv pip install "tool<=1.7" # correctly downgrades to tool==1.7 (matches this call's own spec)
uv pip install "tool>=2" # silently installs tool==2.5 — no error, even though this
# directly contradicts the very first invocation's <2 constraint
uv pip install --amend "tool<2" # fails, as this directly contradicts the >=2 constraint
Real Life example:
user@machine:~/work/Temp/uv-example$ uv pip install west==1.5.0
Resolved 9 packages in 549ms
Installed 9 packages in 19ms
+ colorama==0.4.6
+ docopt==0.6.2
+ packaging==26.3
+ pykwalify==1.8.0
+ python-dateutil==2.9.0.post0
+ pyyaml==6.0.3
+ ruamel-yaml==0.19.1
+ six==1.17.0
+ west==1.5.0
user@machine:~/work/Temp/uv-example$ uv pip install pyyaml==3.10
Resolved 1 package in 1.19s
Built pyyaml==3.10
Prepared 1 package in 137ms
Uninstalled 1 package in 0.62ms
Installed 1 package in 0.69ms
- pyyaml==6.0.3
+ pyyaml==3.10
As a result west will fail during runtime, as it calls functions from incompatible version pyyaml 3.10.
I'd love to have a flag like --amend or --safe so I can be sure that the installation does not break anything as all previous constrains are still considered.
Source: astral-sh/uv