Live data from Hacker News

A year of uv: pros, cons, and should you migrate

bitecode.dev

231–240 of 401 posts

Re: A year of uv: pros, cons, and should you migrate

#231
post #43

A very well written article! I admire the analysis done by the author regarding the difficulties of Python packaging. With the advent of uv, I'm finally feeling like Python packaging is solved. As mentioned in the article, being able to have inline dependencies in a single-file Python script and running it naturally is just beautiful. #!/usr/bin/env -S uv run # /// script # dependencies = ['requests', 'beautifulsoup4…

My feeling sadly is because uv is the new thing, it hasn't had to handle anything but the common cases. This kinda gets a mention in the article, but is very much glossed over. There are still some sharp edges, and assumptions which aren't true in general (but are for the easy cases), and this only going to make things worse, because now there's a new set of issues people run into.

As an example of an edge case - you have Python dependencies that wrap C libs that come in x86-64 flavour and arm-64.

Pipenv, when you create a lockfile, will only specify the architecture specific lib that your machine runs on.

So if you're developing on an ARM Macbook, but deploying on an Ubuntu x86-64 box, the Pipenv lockfile will break.

Whereas a Poetry lockfile will work fine.

And I've not found any documentation about how uv handles this, is it the Pipenv way or the Poetry way?

Re: A year of uv: pros, cons, and should you migrate

#232
post #43

A very well written article! I admire the analysis done by the author regarding the difficulties of Python packaging. With the advent of uv, I'm finally feeling like Python packaging is solved. As mentioned in the article, being able to have inline dependencies in a single-file Python script and running it naturally is just beautiful. #!/usr/bin/env -S uv run # /// script # dependencies = ['requests', 'beautifulsoup4…

This is a nice feature, but I've not found it to be useful, because my IDE wont recognize these dependencies. Or is it a skill issue?

No, it's the fact that it's a rather new PEP, and our IDEs don't yet support it, because, rather new.

Re: A year of uv: pros, cons, and should you migrate

#233
post #43

A very well written article! I admire the analysis done by the author regarding the difficulties of Python packaging. With the advent of uv, I'm finally feeling like Python packaging is solved. As mentioned in the article, being able to have inline dependencies in a single-file Python script and running it naturally is just beautiful. #!/usr/bin/env -S uv run # /// script # dependencies = ['requests', 'beautifulsoup4…

> As mentioned in the article, being able to have inline dependencies in a single-file Python script and running it naturally is just beautiful.

The syntax for this (https://peps.python.org/pep-0723/) isn't uv's work, nor are they first to implement it (https://iscinumpy.dev/post/pep723/). A shebang line like this requires the tool to be installed first, of course; I've repeatedly heard about how people want tooling to be able to bootstrap the Python version, but somehow it's not any more of a problem for users to bootstrap the tooling themselves.

And some pessimism: packaging is still not seen as the core team's responsibility, and uv realistically won't enjoy even the level of special support that Pip has any time soon. As such, tutorials will continue to recommend Pip (along with inferior use patterns for it) for quite some time.

> I have been thinking that a dedicated syntax for inline dependencies would be great, similar to JavaScript's `import ObjectName from 'module-name';` syntax. Python promoted type hints from comment-based to syntax-based, so a similar approach seems feasible.

First off, Python did no such thing. Type annotations are one possible use for an annotation system that was added all the way back in 3.0 (https://peps.python.org/pep-3107/); the original design explicitly contemplated other uses for annotations besides type-checking. When it worked out that people were really only using them for type-checking, standard library support was added (https://peps.python.org/pep-0484/) and expanded upon (https://peps.python.org/pep-0526/ etc.); but this had nothing to do with any specific prior comment-based syntax (which individual tools had up until then had to devise for themselves).

Python doesn't have existing syntax to annotate import statements; it would have to be designed specifically for the purpose. It's not possible in general (as your example shows) to infer a PyPI name from the `import` name; but not only that, dependency names don't map one-to-one to imports (anything that you install from PyPI may validly define zero or more importable top-level names, and of course the code might directly use a sub-package or an attribute of some module (which doesn't even have to be a class). So there wouldn't be a clear place to put such names except in a separate block by themselves, which the existing comment syntax already does.

Finally, promoting the syntax to an actual part of the language doesn't seem to solve a problem. Using annotations instead of comments for types allows the type information to be discovered at runtime (e.g. through the `__annotations__` attribute of functions). What problem would it solve for packaging? It's already possible for tools to use a PEP 723 comment, and it's also possible (through the standard library - https://docs.python.org/3/library/importlib.metadata.html) to introspect the metadata of installed packages at runtime.

Re: A year of uv: pros, cons, and should you migrate

#234

Like so many other articles that make some offhand remarks about conda, this article raves about a bunch of "new" features that conda has had for years. > Being independent from Python bootstrapping Yep, conda. > Being capable of installing and running Python in one unified congruent way across all situations and platforms. Yep, conda. > Having a very strong dependency resolver. Yep, conda (or mamba). The main thing…

I come from the viewpoint that I don't want my build tool to install my Python for me.

In the same vein, I don't want Gradle or Maven to install my JVM for me.

In JVM land I use SDKMAN! (Yes, that's what the amazingly awesome (in the original sense of awe: "an emotion variously combining dread, veneration, and wonder") concretion of Bash scripts is called).

In Python land I use pyenv.

And I expect my build tool to respect the JVM/Python versions I've set (looking at you Poetry...) and fail if they can't find them (You know what you did, Poetry. But you're still so much better than Pipenv)

Re: A year of uv: pros, cons, and should you migrate

#235

Now we should just figure out why to stop here. Why not write everything in Rust? Recently I have moved all my projects to Rust from Python and never looked back. Of course we need projects like Torch and we are not yet there, but those simpler projects that do not require GPU libraries Rust is great.

Yeah, if Python sucks at managing its own packages and you need Rust, why use Python at all?

Re: A year of uv: pros, cons, and should you migrate

#236

Earlier quoted context omitted.

One other key part of this is freezing a timestamp with your dependency list, because Python packages are absolutely terrible at maintaining compatibility a year or three or five later as PyPI populates with newer and newer versions. The special toml incantation is [tool.uv] exclude-newer: # /// script # dependencies = [ # "requests", # ] # [tool.uv] # exclude-newer = "2023-10-16T00:00:00Z" # /// https://docs.astral.…

Why didn't you create a lock file with the versions and of course hashsums in it? No version hunting needed.

A major part of the point of PEP 723 (and the original competing design in PEP 722) is that the information a) is contained in the same physical file and b) can be produced by less sophisticated users.

Re: A year of uv: pros, cons, and should you migrate

#237
post #12

Well, big fan of uv. But... the 86GB python dependency download cache on my primary SSD, most of which can be attributed to the 50 different versions of torch, is testament to the fact that even uv cannot salvage the mess that is pip. Never felt this much rage at the state of a language/build system in the 25 years that I have been programming. And I had to deal with Scala's SBT ("Simple Build Tool") in another life.

> And I had to deal with Scala's SBT ("Simple Build Tool") in another life.

I feel you.

Re: A year of uv: pros, cons, and should you migrate

#238

Earlier quoted context omitted.

One other key part of this is freezing a timestamp with your dependency list, because Python packages are absolutely terrible at maintaining compatibility a year or three or five later as PyPI populates with newer and newer versions. The special toml incantation is [tool.uv] exclude-newer: # /// script # dependencies = [ # "requests", # ] # [tool.uv] # exclude-newer = "2023-10-16T00:00:00Z" # /// https://docs.astral.…

Oooh! Do you end up doing a binary search by hand and/or does uv provide tools for that?

Where would binary search come into it? In the example, the version solver just sees the world as though no versions released after `2023-10-16T00:00:00Z` existed.

Re: A year of uv: pros, cons, and should you migrate

#239

Earlier quoted context omitted.

My feeling sadly is because uv is the new thing, it hasn't had to handle anything but the common cases. This kinda gets a mention in the article, but is very much glossed over. There are still some sharp edges, and assumptions which aren't true in general (but are for the easy cases), and this only going to make things worse, because now there's a new set of issues people run into.

As an example of an edge case - you have Python dependencies that wrap C libs that come in x86-64 flavour and arm-64. Pipenv, when you create a lockfile, will only specify the architecture specific lib that your machine runs on. So if you're developing on an ARM Macbook, but deploying on an Ubuntu x86-64 box, the Pipenv lockfile will break. Whereas a Poetry lockfile will work fine. And I've not found any documentatio…

PEP 751 is defining a new lockfile standard for the ecosystem, and tools including uv look committed to collaborating on the design and implementing whatever results. From what I've been able to tell of the surrounding discussion, the standard is intended to address this use case - rather, to be powerful enough that tools can express the necessary per-architecture locking.

The point of the PEP 723 comment style in the OP is that it's human-writable with relatively little thought. Cases like yours are always going to require actually doing the package resolution ahead of time, which isn't feasible by hand. So a separate lock file is necessary if you want resolved dependencies.

If you use this kind of inline script metadata and just specify the Python dependency version, the resolution process is deferred. So you won't have the same kind of control as the script author, but instead the user's tooling can automatically do what's needed for the user's machine. There's inherently a trade-off there.

Re: A year of uv: pros, cons, and should you migrate

#240

Since this seems to be a love fest let me offer a contrarian view. I use conda for environment management and pip for package management. This neatly separates the concerns into two tools that are good at what they do. I'm afraid that uv is another round of "Let's fix everything" just to create another soon to be dead set of patterns. I find nothing innovative or pleasing in its design, nor do I feel that it is parti…

Yeah, I don't want my build tool to manage my Python, and I don't want my tool that installs Pythons to manage my builds.

In JVM land I used Sdkman to manage JVMs, and I used Maven or Gradle to manage builds.

I don't want them both tied to one tool, because that's inflexible.

Post reply on HN