The newly approved Python Enhancement Proposal 751 gives Python a standard lock file format for specifying the dependencies of projects. Hereβs the what, why, and when.
Python Enhancement Proposal (PEP) 751 gives Python a new file format for specifying dependencies. This file, called a lock file, promises to allow developers to reproduce the installation of their Python projects, with the exact same sets of dependencies, from system to system.
Although there are several community solutions, Python has historically lacked an official way to do file locking and conflict resolution for dependencies. The closest thing to a native solution is theΒ requirements.txtΒ file, or the output fromΒ pip freeze.Β The requirements.txtΒ file lists requirements for a project, and possible ranges of versions for each requirement. But it doesnβt address where those requirements should come from, how to validate them against a hash, or many other needs lock files commonly address today.
Individual project management tools like Poetry orΒ uvΒ do their best to resolve conflicts between dependencies and record them in lock files. The bad news: Those lock files have no common format, so theyβre not interchangeable between tools. Theyβre typically created in place by each user when installing a projectβs requirements, rather than created by the developer and redistributed.
What is a lock file and why it matters
Lock files allow the dependencies of a project to be reproduced reliably, no matter where the project may be set up. Ideally, the lock file lists each dependency, where to find it, a hash to verify it, and any other information someone might need to recreate the dependency set.
Python projects typically donβt have the massive, sprawling dependency sets that can appear in, say, JavaScript projects. But even projects with only a few dependencies can have conflicts.
Imagine you have a dependency namedΒ fixthis, which in turn depends on a package namedΒ fixerupper. However,Β fixthis depends specifically on version 1.5 ofΒ fixerupper, because later versions have behaviors thatΒ fixthisΒ hasnβt addressed yet.
That by itself isnβt a problem, because you can just installΒ fixthisΒ and have version 1.5 ofΒ fixerupperΒ installed automatically. The problem comes whenΒ otherΒ dependencies in your project might also useΒ fixerupper.
Letβs say we add another dependency to our project,Β fixthat, which also depends onΒ fixerupper. However, fixthatΒ onlyΒ works with version 2.0 or higher ofΒ fixerupper.Β That means fixthisΒ andΒ fixthatΒ canβt coexist.
On the other hand, letβs say we had an alternative package,Β fixit, that could work with version 1.5 ofΒ fixerupperΒ or higher. Then bothΒ fixthisΒ andΒ fixitΒ could work with version 1.5 ofΒ fixerupper. Our projectβs lock file could record the way this conflict was resolved, allowing other users to install the exact same dependencies and versions needed to avoid any deadlocks or conflicts.
What PEP 751 does for Python
PEP 751, finalized after much back-and-forth since July 2024, describes a common lock file format for Python projects to address many of the concerns described above.
The file, typically namedΒ pylock.toml, uses the TOML data format, just like the standard Python project description fileΒ pyproject.toml. A pylock.toml file can be written by hand, but the idea is that you should not have to do so. Existing tools will in time generateΒ pylock.tomlΒ automatically, in the same way a requirements.txt file can be generated with pip freeze from a projectβs virtual environment.
The pylock.tomlΒ file allows for a wide range of details. It can specify which version of the lock file standard to use (if it changes in the future), which version of Python to use, whatΒ environment markersΒ to respect for different Python versions, and package-level specifiers for much of this information as well. Each specified dependency can have details about its sourcing (including from version control systems), hashes, source distribution info (if any), and more.
A detailed example of the pylock.toml format is available in PEP 751. Each dependency has its own [[packages]] subsection, with details about where and when it was obtained, its hash, version requirements, and so on. The example shows how a package can have multiple platform-specific sources. In the example, numpy lists binary wheels for Microsoft Windows and generic Linux systems.
When will PEP 751 lock files arrive?
As of this writing, thereβs no official or third-party tool that supportsΒ pylock.toml today. Future revisions of tools, fromΒ pipΒ on outwards, are meant to adopt pylock.toml at the pace their providers find suitable, so you can expect the new lock file to be added to workflows and to the makeup of projects over time. You will eventually want to think about whether the set of dependencies of your project is complex enough to demand a pylock.tomlfile. Anyone creating a package hosted on PyPI, for instance, will want to gravitate towards creating a pylock.toml for the project.
The speed of adoption will be dictated by how soon existing tools make it possible to generate pylock.toml files, and whether that file format will immediately replace their own internal formats. Some third-party tools that generate their own lock files remain hesitant to useΒ pylock.tomlΒ as a full replacement.Β uv, for instance, intends to supportΒ pylock.tomlΒ as an export and import format, but not as the format for its native lock filesΒ due to some features not yet supported inΒ pylock.toml. However, itβs entirely possible that support for those features could be added to future revisions of theΒ pylock.tomlΒ spec.


