Youngkwang Yang한국어
Contents

pylock.toml, a standard lock file for Python

Python

pip recently gained a lock command. Run it for requests and it writes a file named pylock.toml.

$ pip lock requests -o pylock.toml

Right now poetry, pipenv, uv and the rest each produce their own lock file, and since the specs differ there’s no compatibility between tools (because there’s no standard spec).

Last year PEP 751 was accepted and gave lock files a standard.1 In April, pip added experimental pylock.toml support. I’d guess other tools will gradually pick up the standard too. uv, for what it’s worth, already supports it.

Lock files differ by tool

A lock file records not just package versions but the hashes of the files that actually get installed, so the same conditions give you a consistent install.

In pip, requirements.txt has been playing that role almost as a de facto standard (pip install -r requirements.txt..), but it isn’t a format that pins versions or install files as strictly as a lock file, so depending on how you use it, the install result can vary.

The other package tools each made their own lock file spec, and since the formats differ, building a tool like Dependabot that has to parse dependencies for inspection means supporting several lock formats. That’s a chore. PEP 751 looks like it was accepted to cut the maintenance cost of lock formats that differ from tool to tool.

The pylock.toml structure

The pylock.toml created above lists requests and the packages requests depends on. Here is an excerpt.

lock-version = "1.0"
created-by = "pip"

[[packages]]
name = "certifi"
version = "2026.6.17"

[[packages.wheels]]
name = "certifi-2026.6.17-py3-none-any.whl"
url = "https://files.pythonhosted.org/packages/.../certifi-2026.6.17-py3-none-any.whl"

[packages.wheels.hashes]
sha256 = "2227dcbaafe0d2f59279d1762ddddc37783ed4354594f194ffc31d20f41fc3db"

[[packages]]
name = "requests"
version = "2.34.2"

[[packages.wheels]]
name = "requests-2.34.2-py3-none-any.whl"
url = "https://files.pythonhosted.org/packages/.../requests-2.34.2-py3-none-any.whl"

[packages.wheels.hashes]
sha256 = "2a0d60c172f83ac6ab31e4554906c0f3b3588d37b5cb939b1c061f4907e278e0"

A requirements file with pinned versions is usually package==version, but looking at the structure above, it also includes the actual files to install and their hashes on top of the version (if you want the full pylock.toml spec, see the docs).

pip’s current implementation

PEP 751 is accepted, but pip’s support for pip lock and -r pylock.toml is still experimental. How pip turns the spec into features may still change (so for now, avoid using it in production).

The limits of what’s implemented so far are being discussed in the pip lock issue and the -r pylock.toml issue, so if you try it and notice something to improve, it’d be worth filing an issue.

References

Footnotes

  1. PEP 751 isn’t the first attempt at standardizing lock files. PEP 665 was proposed earlier, got rejected for supporting wheels only, and the broader PEP 751 was accepted instead. ↩