Lock File: install, update & sync
|
This content was generated with the assistance of AI and should be verified against the official documentation before being relied on in production. The reference material consulted while preparing these pages is listed in the Python Reference bibliography. |
poetry.lock is the part of a Poetry project that makes installs reproducible. This page describes its format and the four commands
that read or write it, lock, install, update and sync, for Poetry 2.5.1. The examples ran on CPython 3.14.6 on 2026-10-22 on
copies of the Poetry flavour of birdtally; hashes in quoted TOML strings are shortened with …. The comparison with pip’s lock
formats is on Lock Files & Reproducible Installs.
The format
# This file is automatically @generated by Poetry 2.5.1 and should not be changed by hand.
[[package]]
name = "click"
version = "8.5.0"
description = "Composable command line interface toolkit"
optional = false
python-versions = ">=3.10"
groups = ["docs"]
files = [
{file = "click-8.5.0-py3-none-any.whl", hash = "sha256:255bc9599cf7748b4b1a446ccc735421bd08a2ae529a8b88597d3de5664ee360"},
{file = "click-8.5.0.tar.gz", hash = "sha256:ba0d2089de75ea0310e2dde03160e6ca10009947fb95a182f9b54021bb272e34"},
]
…
[metadata]
lock-version = "2.1"
python-versions = ">=3.10"
content-hash = "e6de9ee1…c8d825f4"
-
The header names the Poetry version that wrote the file and the rule: "should not be changed by hand".
-
[[package]]entries list every package for every group, extra and platform, with the hashes of all files of the version (here the wheel and the sdist), so the same lock installs anywhere. -
groupsandmarkersper package are new inlock-version = "2.1"(Poetry 2.0). With them the installer can decide what to install by evaluating markers instead of resolving again (installer.re-resolve = false, below). -
[metadata] content-hashis the SHA-256 of the parts ofpyproject.tomlthat affect resolution. In Poetry 2.5.1’slocker.pythese arerequires-python,dependenciesandoptional-dependenciesof[project], the whole[dependency-groups]table, anddependencies,source,extras,dev-dependenciesandgroupof[tool.poetry]. Editing a description or a version number does not make the lock stale; editing a dependency does. -
Poetry 2.5.1 reads lock versions 1.x and 2.x and writes 2.1.
Since Poetry 2.3 the PEP 735 [dependency-groups] table is part of the hash. A lock written by 2.3 or later therefore looks
outdated to Poetry 2.2.x for a project that uses PEP 735 groups, and the other way round; pin the Poetry version of a team with
requires-poetry = ">=2.3".
poetry lock
poetry lock resolves and writes the lock without installing anything. Since Poetry 2.0 it keeps the versions that are already
locked and changes only what pyproject.toml requires (the old --no-update behaviour is now the default and the option was
removed). --regenerate ignores the existing lock and resolves from scratch, which normally gives the same result as
poetry update --lock.
A lock made with a 200-day cooldown pinned ruff 0.15.9. A plain poetry lock kept it; updating one package moved it:
POETRY_SOLVER_MIN_RELEASE_AGE=200 poetry lock --regenerate
grep -A1 'name = "ruff"' poetry.lock
poetry lock
grep -A1 'name = "ruff"' poetry.lock
poetry update ruff --lock
grep -A1 'name = "ruff"' poetry.lock
Writing lock file
name = "ruff"
version = "0.15.9"
Resolving dependencies...
name = "ruff"
version = "0.15.9"
Writing lock file
name = "ruff"
version = "0.17.1"
A stale lock
When the relevant parts of pyproject.toml change, the lock no longer matches. Changing the pretty extra from rich>=13 to
rich>=14:
poetry install
poetry check --lock
Installing dependencies from lock file
pyproject.toml changed significantly since poetry.lock was last generated. Run `poetry lock` to fix the lock file.
Error: pyproject.toml changed significantly since poetry.lock was last generated. Run `poetry lock` to fix the lock file.
Both commands exit with 1, and nothing is installed (since Poetry 1.8 an inconsistent lock is an error, not a warning). poetry check
--lock (1.6, replacing lock --check) is the check to run in CI; after poetry lock it prints All set!.
An incompatible lock
A lock written by a newer Poetry with a newer major lock version cannot be read. With lock-version = "3.0" edited in:
Installing dependencies from lock file
The lock file is not compatible with the current version of Poetry.
Upgrade Poetry to be able to read the lock file or, alternatively, regenerate the lock file with the `poetry lock` command.
Upgrade Poetry, as the message says, rather than regenerating and losing the pinned versions.
Source: Poetry CLI: check.
Merge conflicts
Two branches that each change dependencies conflict in poetry.lock, and the conflicted file is invalid TOML whose content-hash
matches neither side. Never merge it by hand: resolve the conflict in pyproject.toml, then take either side of the lock (for example
git checkout --theirs poetry.lock) and run poetry lock, which re-resolves only what changed.
install, update and sync
| Command | Reads the lock? | Changes the lock? |
|---|---|---|
|
Yes; installs exactly what it lists for the selected groups and extras. Resolves only when there is no lock. |
Only when there was none. |
|
No; re-resolves the named packages (or everything) to the newest allowed versions. |
Yes, then installs. |
|
Yes, like |
Only when there was none. |
|
Keeps locked versions. |
Yes; installs nothing. |
The Poetry documentation recommends poetry sync over poetry install for reproducible environments, because install never
removes anything, so packages you dropped from pyproject.toml (or installed by hand) stay. The exception is
virtualenvs.create = false or virtualenvs.options.system-site-packages = true: sync would then try to remove packages that do
not belong to the project, so use install there.
Options
| Option | install |
sync |
Meaning |
|---|---|---|---|
|
✓ |
✓ |
Group selection ( |
|
✓ |
✓ |
All groups, optional ones included. |
|
✓ |
✓ |
Extras of the project. |
|
✓ |
✓ |
Do not install the project itself. |
|
✓ |
✓ |
Only the project, no dependencies. |
|
✓ |
✓ |
Skip directory path dependencies (for Docker layers). |
|
✓ |
✓ |
Byte-compile the installed files. |
|
✓ |
✓ |
Print the operations (implies |
|
deprecated |
Use |
poetry update accepts --with, --without and --only (they choose what gets installed; the lock is always resolved for all
groups), --dry-run, --lock (update the lock, do not install) and --sync. The update --help text in 2.5.1 lists --sync without
the "(Deprecated)" label that install --sync carries, although the replacement is the same poetry sync.
Since Poetry 2.4, naming a package that is not a dependency is an error:
poetry update nosuchpkg
The following packages are not dependencies of this project: nosuchpkg
poetry update rich updates rich within its constraint; it does nothing if the newest allowed version is already locked. To go
past the constraint use poetry add rich@latest.
installer.re-resolve
With a 2.1 lock the installer can either re-resolve the locked packages for the target environment (the 1.x behaviour) or simply
evaluate the locked markers. installer.re-resolve (POETRY_INSTALLER_RE_RESOLVE) chooses; it was introduced in 2.0 with true as
the default and defaults to false since 2.3. false is faster and is required for the exclusive-extras pattern on
Dependency Specification.
Source: Poetry: installer.re-resolve.
Cooldowns
solver.min-release-age (Poetry 2.4) makes lock, add and update ignore releases younger than a number of days; the lock above
was made that way. The settings and their pitfalls are on
Supply-Chain Security.
Source: Poetry: solver.min-release-age.
pip and Poetry
| Poetry | pip |
|---|---|
|
|
|
|
|
A fresh venv plus the above; pip never removes unlisted packages |
|
|
|
No equivalent; compare the lock you generate in CI with the committed one |