My Python setup, December 2025
9 points by carlana
9 points by carlana
I'm using uv for new things, though I'm not in a big hurry to migrate things I have that used pip-tools or poetry along with pyenv. Those are still working just fine. uv's definitely faster. I like it a lot. I find it a little less fiddly to write new pyproject.toml files for than I do poetry.
I don't think I really care about uv's speed; sure, it's uniformly faster every place I use it, but it speeds up things that I don't repeat that often, and on a certain level I kind of liked pyenv's source builds.
Once you've got pyenv/poetry or pyenv/pip-tools working, it's not hard at all
The thing that swayed me is how much easier it is to write instructions for setting things up with uv than with anything else. For new projects that I want to share with others, that's valuable. And for old projects where I'm hoping to share them with more people than I have already, it starts to look worth moving to uv in terms of saved documentation labor alone. Having an easier story for someone who wants to bootstrap my thing feels valuable, and I'm mildly surprised that I care about that a lot more than I care about the performance of the tools themselves.
I've not been using much of Python in the recent past and now that I needed to I was glad to see how much uv improved the Python development experience in the meanwhile.
That said, for me as well uv's speed, which seems to be one of the tool's most advertised features, is probably the least interesting one, more like a very welcome extra.
I think there's an important consequence of the speed: uv always syncs the dependencies on each command, so I never have to do it explicitly, so I can't forget to do it.
I really like not having to activate whatever environment and run each command explicitly in the environment. I suspect with poetry or whatever, it would be unbearable to sync dependencies on every command I run.
Otherwise, I just think uv copies the cargo/rustup playbook, which is maybe the best designed tool of this kind I've seen.
Makes sense.
To be clear, my point was personally I'd rather trade speed for any other uv cool feature, especially robustness/consistency. Luckily there's no need for any such trade off so nowadays thanks to uv I can have all the Python cake and eat it too.
What I'm saying is that the speed is an "enabler". It means every time you run uv it can check if the virtual environment is in sync.
I used Poetry for a lot of time, and the slow resolution speed hardly bothered me- I wasn't using that constantly.
However, having to run an explicit command to update dependencies is more of a pain, esp. when working with others.
But otherwise, yes, I don't care for other kinds of speed.
Otherwise, I just think uv copies the cargo/rustup playbook, which is maybe the best designed tool of this kind I've seen.
That was why I liked poetry and pyenv so much. I'd been working with rust a decent amount when I grew a need to maintain a couple of python projects which needed different python versions. pyenv felt a lot like rustup, and poetry like cargo. uv feels like those but easier to document. You're exactly right about the speed allowing syncs on each command; that hadn't occurred to me, but now that you've pointed it out, I've been very much enjoying that feature.
Question for Chris:
There is one set of tools that stays on
pipx, though: Datasette and its SQLite toolchain. Simon Willison built those to install their own plugins, usingdatasette install <plugin>orllm install <plugin>. Those usepipinternally and sometimesuvcan cause problems upgrading, so I've kept them onpipx.
The plugin mechanism is meant to work if you do this:
uv tool install llm
llm install llm-anthropic
Have you run into any problems with that?
This works too for one-offs:
uvx --with llm-anthropic llm -m claude-haiku-4.5 "hi"
My latest uv learning concerns dependency groups (here's my TIL). It turns out uv run will automatically install anything it finds in the dev dependency group in a pyproject.toml file, which means if you have all of your development/test tools in there it's super convenient for people to start hacking on a project.
I got this working recently and I really like it:
cd /tmp
git clone https://github.com/simonw/llm
cd llm
uv run pytest
Note that I didn't have to create a virtual environment manually at all - just running uv run pytest was enough to automatically create a .venv environment with the right stuff in it thanks to this section of my pyproject.toml: https://github.com/simonw/llm/blob/0.28/pyproject.toml#L44-L69
... which made me wonder if I could reduce the above to a one-liner - I tried this:
uv run --isolated \
--with https://github.com/simonw/llm/archive/refs/heads/main.zip \
pytest
But it gave me an error:
ModuleNotFoundError: No module named 'hypothesis'
Suggesting it didn't get the dev dependencies for some reason.
I think (without actually verifying right this minute) that it only installs the dev dependencies when it's in something shaped like a source tree for a project. I don't believe running from a zip file matches that filter.
One thing I found extremely confusing when trying to make use of it is that there are dependency groups and there are extras (you know, these square brackets in pip install foo[bar]) and they are not synchronised in any meaningful way in a pyproject.toml, extras are a purely packaging thing.
So if you want to make use of extras, you will likely define a dep group for it, but it is up to you then to keep the extras section in sync.
I've come to see dependency-groups as a complete replacement for extras.
I think I know what you mean. So far, all my needs have also been covered by dependency groups (actually, by only having a dev group that has all the development dependencies and is auto-installed).
Still, when it comes to packaging and distributing libraries, it seems that both may be needed (because they have different semantics).
Yeah, uv just works.
I'd like to give https://github.com/orm011/pgserver a go for the next Python project I work on that requires PostgreSQL. I've seen a couple of similar projects, but this seems the nicest so far for Python. I expect integrating it with Django will not require much effort.