pip lock & pylock.toml
|
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. |
pip lock writes the result of a resolution to a standard PEP 751 lock file, and pip install -r pylock.toml installs one. Both
are experimental in pip 26.2.2: each prints a warning to that effect, and the documentation says they "may be removed/changed in
a future release without prior warning". This page was written against pip 26.2.2 and run on CPython 3.14.6 on 2026-10-22 for the
pip flavour of birdtally-report. The file format and how it compares with the other lock formats are on
Lock Files & Reproducible Installs.
pip lock
python -m pip lock [options] <requirement specifier> ...
python -m pip lock [options] -r <requirements file> ...
python -m pip lock [options] [-e] <vcs project url> ...
python -m pip lock [options] [-e] <local project path> ...
It takes the same requirement forms as pip install and most of its resolution options (-r, -c, --build-constraint,
--requirements-from-script, --only-deps, -e, --group, the index, binary and pre-release options, --uploaded-prior-to).
-o/--output <path> names the output, pylock.toml by default, or - for standard output. pip resolves exactly as for an
install and writes what it would install instead of installing it. The documentation’s key limitation: "The generated lock file
is only guaranteed to be valid for the current python version and platform."
Locking birdtally-report
report-req.txt:
--index-url http://localhost:8080/simple
birdtally[pretty]==0.1.0
python -m pip lock -r report-req.txt
WARNING: pip lock is currently an experimental command. It may be removed/changed in a future release without prior warning.
Collecting birdtally==0.1.0 (from birdtally[pretty]==0.1.0->-r report-req.txt (line 2))
Downloading birdtally-0.1.0-py3-none-any.whl (3.7 kB)
Collecting rich>=13 (from birdtally[pretty]==0.1.0->-r report-req.txt (line 2))
Collecting markdown-it-py>=2.2.0 (from rich>=13->birdtally[pretty]==0.1.0->-r report-req.txt (line 2))
Collecting pygments<3.0.0,>=2.13.0 (from rich>=13->birdtally[pretty]==0.1.0->-r report-req.txt (line 2))
Collecting mdurl~=0.1 (from markdown-it-py>=2.2.0->rich>=13->birdtally[pretty]==0.1.0->-r report-req.txt (line 2))
The resulting pylock.toml, with the hash values shortened and the three packages in the middle left out (they have the same
shape):
lock-version = "1.0"
created-by = "pip"
[[packages]]
name = "birdtally"
version = "0.1.0"
[[packages.wheels]]
name = "birdtally-0.1.0-py3-none-any.whl"
url = "http://localhost:8080/packages/birdtally-0.1.0-py3-none-any.whl"
[packages.wheels.hashes]
sha256 = "35a50693…9984a56b5a"
[[packages]]
name = "markdown-it-py"
version = "4.2.0"
[[packages.wheels]]
name = "markdown_it_py-4.2.0-py3-none-any.whl"
url = "https://files.pythonhosted.org/packages/b3/81/4da04ced5a082363ecfa159c010d200ecbd959ae410c10c0264a38cac0f5/markdown_it_py-4.2.0-py3-none-any.whl"
[packages.wheels.hashes]
sha256 = "9f7ebbcd…2641c4a"
…
[[packages]]
name = "rich"
version = "15.0.0"
[[packages.wheels]]
name = "rich-15.0.0-py3-none-any.whl"
url = "https://files.pythonhosted.org/packages/82/3b/64d4899d73f91ba49a8c18a8ff3f0ea8f1c1d75481760df8c68ef5235bf5/rich-15.0.0-py3-none-any.whl"
[packages.wheels.hashes]
sha256 = "33bd4ef7…e27de0bb"
Line by line:
-
lock-version = "1.0"is the version of the PEP 751 format; installers must refuse a version they do not support. -
created-by = "pip"names the tool that wrote it. -
There is no
environmentsand norequires-pythonkey: pip records nothing about the platform the lock is valid for, although it is valid only for this one. Record the Python version and platform yourself, for example in the file name (pylock.linux-py314.tomlmatches thepylock.<name>.tomlrule, which allows no further dots). -
Each
[[packages]]entry has anameandversionand exactly one source: here[[packages.wheels]]with the file name, theurland itshashes. Only the file pip chose is listed, not the other wheels or the sdist, so the lock cannot fall back to another file. -
The private birdtally wheel is recorded by its full URL on the local index; the installer will fetch from that URL, whatever your index configuration says at install time.
-
pip 26.2.2 did not write the optional
index,sizeorupload-timekeys for these packages, which the Poetry export does write (compare the export on the lock-files page).
Installing from pylock.toml
Since pip 26.1, -r accepts a pylock.toml (or pylock.<name>.toml) as well as a requirements file. In a fresh venv:
python -m pip install -r pylock.toml
WARNING: Using pylock.toml as a requirements source is an experimental feature. It may be removed/changed in a future release without prior warning.
Collecting birdtally==0.1.0 (from pylock.toml)
Downloading birdtally-0.1.0-py3-none-any.whl (3.7 kB)
Collecting markdown-it-py==4.2.0 (from pylock.toml)
Collecting mdurl==0.1.2 (from pylock.toml)
Collecting pygments==2.21.0 (from pylock.toml)
Collecting rich==15.0.0 (from pylock.toml)
Installing collected packages: pygments, mdurl, birdtally, markdown-it-py, rich
Successfully installed birdtally-0.1.0 markdown-it-py-4.2.0 mdurl-0.1.2 pygments-2.21.0 rich-15.0.0
As the specification requires, pip installs what the lock lists instead of resolving: a requirement that contradicts it is an error (the message was improved in 26.2):
python -m pip install --dry-run -r pylock.toml rich==14.3.4
WARNING: Using pylock.toml as a requirements source is an experimental feature. It may be removed/changed in a future release without prior warning.
ERROR: The requirement rich==14.3.4 is not compatible with version 15.0.0 specified in a provided lock file
ERROR: No matching distribution found for rich==14.3.4
pip 26.2 also made --only-final apply to packages from a lock, made --uploaded-prior-to use the lock’s upload-time field, and
rejects path entries in a lock fetched from a URL when they point outside the lock file’s own location (so a remote lock cannot
point at your file system or another host).
Limits, and the alternatives
pip lock 26.2.2 |
poetry.lock (Poetry 2.5.1) |
uv.lock (uv 0.13, third party) |
|
|---|---|---|---|
Status |
Experimental |
Stable |
Stable |
Format |
PEP 751 |
Poetry’s own |
uv’s own (can export PEP 751) |
Platforms |
The current one only |
All, with markers |
All, with markers |
Files per package |
The chosen one |
All files of the version |
All files of the version |
Groups and extras |
Resolved at lock time |
All, selected at install |
All, selected at install |
Installed by |
pip 26.1+ (experimental), uv, PDM |
Poetry; pip after |
uv; pip after export |
pip lock is a good fit for one deployment target (a container image on one Python) and as a way to produce a standard file without
a workflow tool. When a project must install on several platforms from one lock, use Poetry (and export to pylock.toml for pip
consumers) or another cross-platform locker.