What’s up Python? Pip supports locking, .pth files deprecated
May 2026
Summary
pip gets lock files support.
.pthfiles get a much better alternative.And moar. In fact, it’s mostly moar.
Pip is slowly trying to catch up with uv
pip has been lacking lock file support for a long time, but thanks to PEP 751 and the tireless work of core devs like Brett Cannon, we now have the pylock.toml standard.
With 26.1 comes experimental support for this format.
You can use it in the same way you would use a traditional requirement file to install packages:
pip install -r pylock.tomlProduce wheels:
pip wheel -r pylock.tomlOr just download stuff from pypi for later use:
pip download -r pylock.tomlProducing the lock file looks like this:
pip lock .Note the dot.
This is because, unlike tools like uv, pip is not project aware, and can only lock some kind of package (you can also pass a package name), so you must explicitly tell it what you are locking.
This does come with dropping Python 3.9 support, which is going to be a theme this year.
PEP 829 – Package Startup Configuration Files
Not many people know it, but if you drop a .pth file on the PYTHON PATH, it will get read, and each line starting with the word import will be passed to exec().
This is a weird legacy feature that is used to automatically execute code when Python starts, particularly used by 3rd party packages to register plug-ins or dynamically adapt to the environment.
It’s also slow, messy and mysterious for the average user. Not to mention an attack surface.
PEP 829 is a standard to fix it by introducing a .start file format. It is a text format that doesn’t accept any Python code, but instead is just a list of entry points (in the same way pyproject.toml can provide them) using the syntax: package.module:callable.
E.G:
your_project.your_module:init_function
your_project.another_module:load_pluginsThis will do:
from your_project.your_module import init_function
from your_project.another_module import load_plugins
init_function()
load_plugins()when Python starts, provided the site.py has not been disabled by -S, which is almost always the case.
This provides many improvements over the .pth files:
The format is standard and the same as in the project files. So it can be parsed and manipulated easily. You also know at a glance what it does.
Unlike with
.pth, one error on one line doesn’t abort the entire file.No
exec(), so you can sneak in code that is not already an importable module.
Now you may wonder, why not use directly pyproject.toml entry points or PYTHONSTARTUP.
Well, because this provides the hook to any installed package, not just your code. You don’t want 3rd-party code to write your project files or override your env vars.
And moar
3.15.0 beta 2 is out and is feature complete. You can try the new unpacking in comprehension, the lazy imports, and the new
.startfiles.Maintenant releases: 3.14.5
Mypy 2.0 has been released. which drops Python 3.9 support and allows parallel type checking for extra speed. This requires
--local-partial-typeswhich is now on by default. This has been immediately followed by the 2.1 released, much more stable, so use that if you can.PyDevTools published a bunch of tutorials on uv, ruff and ty.
Google Summer of code will as usual sponsor Django, with plans for table-valued expression in the ORM and a core API framework.
If you use VSCode, you should really update the Python extension as the latest one is much faster to start, thanks to making some tooling discovery lazy, the env resolution faster, and a default workspace scanning much narrower. What’s more, they finally fixed PowerShell activation, which was de facto broken in any corporation that was blocking scripts without any filtering since most do.
