Article illustration 1

Lock files—those unassuming documents pinning dependency versions—are the unsung heroes of reproducible builds. Yet for Python, the journey to standardize them became a grueling marathon spanning six years, two formal PEP proposals, and over 1,800 discussion threads. Brett Cannon's recent keynote at EuroPython 2025 pulled back the curtain on this saga, revealing why something seemingly simple proved astronomically hard to solve.

Why Lock Files Aren't Trivial

At their core, lock files must precisely record:
- Dependency graphs: All transitive packages required, including platform-specific variations
- Installation artifacts: Source trees, sdists (source distributions), and pre-built wheels
- Constraints: Version bounds, environment markers, and optional extras

"The 'how' is source trees, sdists, and wheels," Cannon explains. "The much trickier part is figuring what to install when." This complexity stems from Python's flexibility:

# Example dependency with environment markers in pyproject.toml
requests = { version = ">=2.26", markers = "sys_platform == 'linux'" }

Supporting multi-platform compatibility turns dependency resolution into an NP-complete problem. Add requirements like human readability, security hardening, and tooling interoperability (e.g., letting Poetry generate locks that pip installs), and the challenge compounds.

The Rocky Road to Consensus

Article illustration 2

An early 2019 tweet hinting at lock file discussions

The timeline reveals why standardization took years:
- 2019: Requirements.txt v2 discussions stall with no resolution
- 2021: PEP 665 proposes a wheel-only approach for security/speed, but is rejected over sdist compatibility concerns
- 2022: Post-PEP fallout highlights irreconcilable needs: build-backend locking vs. simplicity
- 2023: Cannon solo-develops a proof-of-concept resolver while Astral's uv enters the scene, shifting dynamics
- 2024: PEP 751 draft emerges, pivoting between set-based and graph-based designs amid heated debates
- 2025: Last-minute compromises save multi-platform support, leading to March acceptance

"I set a deadline of end-March to get things done, even if I had to drop features," Cannon admits. "My wife had grown tired of seeing me dejected after every setback."

Why pylock.toml Matters

The ratified specification delivers:
1. Multi-use locks: Single file works across platforms/install configurations
2. Source inclusivity: Supports sdists, wheels, and local source trees
3. Tool-agnostic design: Generated by one tool (e.g., PDM), installed by another (e.g., pip)
4. TOML structure: Machine-writable but human-readable

Adoption is already underway—PDM supports pylock.toml, with uv and pip following. For developers, this means fewer "works on my machine" failures and truly reproducible environments.

As Cannon steps back from packaging work ("I have a toddler now"), his persistence leaves Python with a critical missing piece. The six-year struggle underscores a truth: in ecosystems as diverse as Python's, standardization isn't a technical challenge—it's a testament to community endurance.

Source: Why It Took 4 Years to Get a Lock File Specification by Brett Cannon