5.1 KiB
title | description | date | image | math | license | hidden | draft | image | categories | tags | ||
---|---|---|---|---|---|---|---|---|---|---|---|---|
uv - One rust tool to rule all pythons | 2025-02-17T23:02:47+01:00 | false | false | img/uv.png |
|
|
Long story short: I'm now using uv, and so should you. It is a great replacement for pip, pip-tools, pipx, poetry, pyenv, twine, virtualenv, and more.
Context
For years, my strategy to manage python projects has been a mix of a custom setup.py
, several hand-crafted requirements.txt
files (through pip freeze
), a custom virtualenv per project, and multiple tools to upload to PyPI.
Although this works, this setup has many drawbacks:
- It requires user intervention (creating a venv, sourcing it, handling new deps). This isn't ideal if you want new (probably inexperienced) users to use your projects.
- On a similar note, the whole process needs to be well documented if you want other users to contribute or maintain the code.
- Pinning dependency versions is finicky, and I've run into problems beause of that.
- Creating a new project involves a template, or copying files from an older project.
Of course, this is nothing new. There is a whole site dedicated to packaging your Python project. A plethora of different projects have come and go, with varying degrees of success.
Alternatives (poetry)
About a year before trying uv
, I tried to catch up with the ecosystem and get to know the blessed new way
.
However, the task proved to be a little more difficult, as the landscape is filled with a myriad of alternatives, each with their own set of drawbacks and detractors.
Packaging has historically been a weak spot, in ironical contradiction to the Zen of Python's "There should be one-- and preferably only one --obvious way to do it",
I eventually settled on poetry. Mostly because it seemed like the most popular alternative.
There are many things I liked about it.
First of all, having a convention for dependencies (pyproject.toml
) and a tool that properly handles them was nice.
It also removed the need to remember specific incantations to build and publish my Python projects.
Lastly, I mixed it poetry2nix
to create reproducible python environments using nix.
This makes for a very powerful experience.
However, there were multiple hiccups.
First of all, it took me some time to figure out which specific fields to use (each tool can define ad-hoc properties in a the pyproject.toml
file), and some of them seemed redundant with the more generic ones.
Full disclosure, this specific point might be a mistake on my side, and I do not remember the details.
The second one is speed.
(Re-)creating an environment took a non-negligible amount of time.
Enter ~light~ uv
According to its repository, uv
can replace pip, pip-tools, pipx, poetry, pyenv, twine, virtualenv, and more.
Not only that, but it also claims to do that 10-100 times faster than pip.
I must admit that it being written in rust was a another selling point for me, as I'm looking for excuses to collaborate in a decently-sized rust projejct.
Installing it is dead simple: simply download the binary (e.g., with curl) or run pip install uv
.
You won't need much more: uv
seems to just do the right thing out of the box.
And it does it really, really fast.
The rest of the time it gets out of the way.
My only gripe so far is that I don't seem to find a built-in command to drop into a shell, but that is nothing that uv run $SHELL
cannot fix.
Common operations
Initialize a repository
uv init
Adding dependencies
uv add senpy
Running commands inside the environment
uv run <COMMAND>
# e.g., run a shell using your python version and dependencies
uv run $SHELL
Dependency tree
uv shell
Resolved 44 packages in 1ms
my-project v0.1.0
├── fastapi[standard] v0.115.8
│ ├── pydantic v2.10.6
│ │ ├── annotated-types v0.7.0
│ │ ├── pydantic-core v2.27.2
│ │ │ └── typing-extensions v4.12.2
│ │ └── typing-extensions v4.12.2
│ ├── starlette v0.45.3
│ │ └── anyio v4.8.0
│ │ ├── exceptiongroup v1.2.2
│ │ ├── idna v3.10
│ │ ├── sniffio v1.3.1
│ │ └── typing-extensions v4.12.2
│ ├── typing-extensions v4.12.2
│ ├── email-validator v2.2.0 (extra: standard)
│ │ ├── dnspython v2.7.0
...