How Poetry's Lock File Guarantees Reproducible Python Builds
Learn how Poetry's lock file pins every transitive dependency, ensuring identical installs across machines and CI pipelines, and see a concrete workflow for adding a package and verifying reproducibility.
03 Oct 2026, 22:10 UTC

The problem: drifting dependencies break CI
When you develop a Python project locally, you might run pip install -r requirements.txt and see everything work. Later, a teammate runs the same command on a different machine or in a CI pipeline and gets a different set of package versions. Tests fail, and you spend time tracing the difference back to a transitive dependency that was updated since the last install.
Thesis: Poetry’s lock file records the exact dependency tree
Poetry solves this by generating a poetry.lock file that pins every transitive dependency to a specific version. Committing this file to version control ensures that poetry install reproduces the same environment everywhere, as long as the lock file is present.
What the lock file contains
The pyproject.toml file holds your version constraints (e.g., requests^2.28). The lock file translates those constraints into concrete versions and records the full dependency graph, including hashes for source distributions when available. This makes the lock file the single source of truth for what gets installed.
How the lock file is created and updated
Poetry updates the lock file automatically when you run commands that change dependencies:
poetry add <package>– adds a new dependency and resolves its tree.poetry remove <package>– removes a dependency and recomputes the lock.poetry lock– forces a regeneration of the lock file based on the currentpyproject.tomlconstraints.
Run these commands in the root of your Poetry project. No special permissions are required; you only need Poetry installed and access to the package indexes configured in your environment.
Worked example: adding a dependency
- Start with a clean directory and initialize a Poetry project:
poetry init -n - Add a package, for example
requests:poetry add requestsPoetry will update
pyproject.tomlwith a constraint likerequests^2.28and create or updatepoetry.lockwith the exact version that satisfies that constraint (e.g.,2.31.0) and all of its transitive dependencies. - Inspect the lock file to see the pinned versions:
cat poetry.lockYou will notice sections for each package that include a
versionfield with an exact number, confirming that the resolver has produced a deterministic set. - Commit both files to Git:
git add pyproject.toml poetry.lock git commit -m "Add requests and lock dependencies" - In another environment (a fresh clone or CI job), run:
poetry installPoetry will read the lock file and install the exact versions recorded there, ignoring any newer releases that might satisfy the constraints in
pyproject.toml. - Verify that the installed versions match the lock:
poetry show --treeThe output should list the same versions you saw in
poetry.lock. If they differ, something has gone wrong with the lock file or the environment.
Trade‑offs and limitations
Loose constraints can still drift
If you specify very permissive constraints (e.g., requests without any operator), Poetry will still pick a concrete version for the lock file, but when you later run poetry lock after a major upstream release, the lock may jump to a version that introduces breaking changes. Regularly reviewing the lock file or using poetry lock --no-update to detect changes helps mitigate this risk.
Platform‑specific dependencies
When a dependency includes environment markers (e.g., ; sys_platform == 'win32'), the lock file may contain different entries for different operating systems. Committing a lock file generated on one OS can cause spurious diffs when teammates on another OS run poetry lock. The practical check is to run poetry lock in your target CI environment and compare the resulting lock file to the committed version; if they differ only in platform‑specific sections, you can accept the difference or generate separate lock files for each platform.
Optional dependency extras
Poetry does not automatically install optional extras defined in pyproject.toml. You must declare them explicitly, for example poetry install --extras dev. Forgetting to do so leads to missing packages in your environment, even though the lock file contains them.
Actionable closing
To reap the reproducibility benefits of Poetry’s lock file:
- Always commit both
pyproject.tomlandpoetry.lockto your repository. - Run
poetry add,poetry remove, orpoetry lockafter any dependency change. - In CI, execute
poetry install(no--syncflag needed) and verify withpoetry show --treethat the installed tree matches the lock. - Periodically run
poetry lock --no-updateto see if the lock file would change; if it does, decide whether to update the lock after testing.
By treating the lock file as the authoritative record of your dependency tree, you eliminate the "works on my machine" problem and make your builds predictable across development, testing, and production.
0 replies
A thoughtful contribution can make all the difference. Be the first to share one.