Python finally has a standard lock file, pylock.toml (defined in PEP 751), and pip has been steadily learning to install from it. pip 26.3, released on 2 November 2026, fills in the gaps that made it awkward in real projects: you can now pick extras and dependency groups from a lock file, and --no-binary works with it. On 12 November, uv 0.13.8 updated its managed CPython 3.11-3.15 builds to ship pip 26.3, so many developers will get it without doing anything. This guide shows how to create a pylock.toml, install from it with pip, and use the new options safely.

Why a standard lock file matters

For years, “locking” in Python meant requirements.txt with pinned versions, or a tool-specific file like poetry.lock or uv.lock. A pylock.toml is different: it is a standardised format that records exact versions, download URLs and hashes, and different tools can read and write it. That means you can lock with one tool and install with another, for example lock with uv on a laptop and install with plain pip in a slim Docker image.

Check your pip version

python -m pip --version
python -m pip install --upgrade "pip>=26.3"

If you use uv-managed Pythons, uv python upgrade or reinstalling the interpreter picks up the newer builds that bundle pip 26.3.

Step 1: create a pylock.toml

You have two common options. With uv, export a project’s lock to the standard format:

# Inside a uv project with pyproject.toml
uv lock
uv export --format pylock.toml -o pylock.toml

Or use pip’s own (still experimental) lock command:

python -m pip lock -e . -o pylock.toml

Either way you end up with a TOML file listing every package, its version and its artifacts with hashes. Commit it next to your pyproject.toml.

Step 2: install from the lock file with pip

pip reads lock files through the familiar -r flag (this support was added as experimental in the 26.x series, per the pip changelog):

python -m venv .venv
source .venv/bin/activate      # Windows: .venv\Scripts\activate
python -m pip install -r pylock.toml

pip installs exactly what the lock file lists, using the URLs and hashes it records, instead of resolving versions again.

New in 26.3: choose extras from the lock

A lock file can describe optional extras (for example postgres or s3). Before 26.3 you could not easily ask pip for them. Now you add them in square brackets, just like a normal requirement:

python -m pip install -r "pylock.toml[postgres,s3]"

Quote the argument in shells like zsh, where square brackets are glob characters.

New in 26.3: choose dependency groups

Dependency groups (PEP 735) let you keep things like test, docs or lint out of your runtime install. pip 26.3 lets --group select non-default groups from a local lock file using the path:group form:

# Runtime packages plus the docs group
python -m pip install -r pylock.toml --group pylock.toml:docs

# Test environment in CI
python -m pip install -r pylock.toml --group pylock.toml:test

This is handy in CI: one lock file, different jobs installing different slices of it.

New in 26.3: –no-binary now respects the lock

Some teams must build certain packages from source, for example to link against a system library. Before 26.3, combining --no-binary with -r pylock.toml made pip fetch the source distribution from the index instead of the locked URL, or fail if the lock only had wheels. Now it uses the locked sdist:

python -m pip install -r pylock.toml --no-binary psycopg

For that to work, your lock file has to include the sdist for that package, so check it before relying on this in production builds.

Supply-chain safety options that work with lock files

Earlier 26.x releases added options that combine well with pylock.toml:

  • --uploaded-prior-to accepts a date or a duration such as P3D (three days ago), and works with lock files because pip reads their upload-time field. This is a simple “cooldown” so you never install something published minutes ago.
  • --only-final is honoured when reading from a lock file, so pre-releases stay out.
  • pip rejects a package path in a remote lock file that points outside the lock file’s own location.
python -m pip install -r pylock.toml --uploaded-prior-to P3D

Other pip 26.3 changes worth knowing

From the 26.3 release notes:

  • Safer installs: pip now blocks unexpected imports during installation, warns about unsafe imports afterwards, and recovers better from interrupted installs.
  • Clearer security policy: the docs now state that pip has never considered installing untrusted wheels safe, because Python’s import system is dynamic.
  • Faster console scripts: installing a wheel with console scripts no longer resolves every PATH entry.
  • Redirect hardening: pip refuses to follow an HTTP redirect to a file: URL, and wheel cache warnings no longer expose URL credentials.
  • Better errors: build-backend import failures show as pip errors instead of raw tracebacks.

A Dockerfile pattern

Here is a minimal pattern that installs only from the lock file, keeping the image reproducible:

FROM python:3.15-slim
WORKDIR /app
COPY pylock.toml .
RUN python -m pip install --upgrade "pip>=26.3" \
 && python -m pip install --no-cache-dir -r "pylock.toml[postgres]"
COPY . .
CMD ["python", "-m", "myapp"]

Copying the lock file before the source code lets Docker cache the dependency layer until the lock changes.

Things to watch

  • Lock file support in pip is still labelled experimental in places, and pip lock itself is experimental. Pin your pip version in CI.
  • A lock file is platform-aware. If you lock on macOS and install on Linux, make sure your locking tool included the Linux artifacts.
  • Keep the lock file in version control and regenerate it on purpose, not on every build.

Takeaway

With pip 26.3, pylock.toml is practical for everyday projects: one standard file, extras with -r "pylock.toml[extra]", groups with --group pylock.toml:name, and source builds that respect the lock. Upgrade pip, export a lock from uv or pip lock, and try installing from it in a fresh virtual environment before switching your CI over.