/flags/uv/uv-lock-upgrade-package
uv lock --upgrade-package PKG: update one dependency in uv.lock
- tool
- uv
- command
- uv lock, uv sync, uv add
- flag
- -P, --upgrade-package PKG[==VER], -U, --upgrade
- default
- keep the versions already in uv.lock
uv lock --upgrade-package idna (short -P) re-resolves only idna, moving it to the newest version allowed by pyproject.toml, and keeps every other entry in uv.lock where it was. Without the flag, uv lock deliberately keeps locked versions that still satisfy the requirements, so relaxing a bound in pyproject.toml does not by itself upgrade anything. --upgrade (-U) is the "upgrade everything" counterpart. The same flags work for uv sync and uv run.
Locked version, relaxed bound, upgrade
cat > pyproject.toml <<'EOF'
[project]
name = "demo"
version = "0.1.0"
requires-python = ">=3.9"
dependencies = ["idna>=3,<3.8"]
EOF
uv lock -q
grep -A1 'name = "idna"' uv.lock | tail -1
sed -i 's/<3.8/<3.9/' pyproject.toml
echo "--- uv lock (bound relaxed)"
uv lock -q
grep -A1 'name = "idna"' uv.lock | tail -1
echo "--- uv lock --upgrade-package idna"
uv lock --upgrade-package idna 2>&1 | grep -vE "^(Resolved|Using CPython)"
grep -A1 'name = "idna"' uv.lock | tail -1Output
version = "3.7" --- uv lock (bound relaxed) version = "3.7" --- uv lock --upgrade-package idna Updated idna v3.7 -> v3.8 version = "3.8"
After the bound was relaxed, uv lock kept 3.7 because it still satisfies <3.9. Only --upgrade-package moved it, and uv prints the change it made.
Upgrade options
| Command | Effect |
|---|---|
| uv lock | Resolve only what changed in pyproject.toml; keep other versions |
| uv lock -P idna | Upgrade idna (and what it needs) to the newest allowed version |
| uv lock -P 'idna==3.8' | Move idna to a specific version |
| uv lock -P idna -P httpx | Several packages (repeat the flag) |
| uv lock -U | Upgrade every package |
| uv sync -P idna | Upgrade in uv.lock and install into .venv |
| uv lock --dry-run -U | Show what an upgrade would change without writing uv.lock |
Typical workflow
uv lock --upgrade-package requests # update one dependency
uv sync # install it
uv run pytest # test
git add uv.lock && git commit -m "Upgrade requests"pyproject.toml is not edited: the declared range stays the same, only the locked version changes. To raise the minimum version in pyproject.toml as well, use uv add 'requests>=2.33'; see uv add.
Pitfalls
- An upgrade that conflicts with other constraints fails with No solution found when resolving dependencies, naming the package that holds it back.
- After upgrading, CI with
uv sync --lockedpasses only if the newuv.lockis committed; otherwise it fails with The lockfile needs to be updated. uv pip compile --upgrade-packageexists too, for requirements.txt workflows, with the same semantics.
FAQ
Why does uv lock not upgrade my packages?
uv lock prefers the versions already in uv.lock as long as they still satisfy pyproject.toml, so the lock stays stable. Ask for an upgrade explicitly with --upgrade-package NAME, or --upgrade for everything.
Can I upgrade a package to a specific version?
Yes: uv lock --upgrade-package 'idna==3.8' (any specifier works). It must also satisfy the constraints in pyproject.toml; otherwise uv reports that no solution was found.
Does --upgrade-package also update the virtual environment?
Not with uv lock, which only writes uv.lock. uv sync --upgrade-package NAME updates the lock and installs the result in one step.