Remix.run Logo
quotemstr 2 hours ago

Well, now my opinion of uv has been damaged. It...

> Ignoring requires-python upper bounds. When a package says it requires python<4.0, uv ignores the upper bound and only checks the lower. This reduces resolver backtracking dramatically since upper bounds are almost always wrong. Packages declare python<4.0 because they haven’t tested on Python 4, not because they’ll actually break. The constraint is defensive, not predictive

Man, it's easy to be fast when you're wrong. But of course it is fast because Rust not because it just skips the hard parts of dependency constraint solving and hopes people don't notice.

> When multiple package indexes are configured, pip checks all of them. uv picks from the first index that has the package, stopping there. This prevents dependency confusion attacks and avoids extra network requests.

Ambiguity detection is important.

> uv ignores pip’s configuration files entirely. No parsing, no environment variable lookups, no inheritance from system-wide and per-user locations.

Stuff like this sense unlikely to contribute to overall runtime, but it does decrease flexibility.

> No bytecode compilation by default. pip compiles .py files to .pyc during installation. uv skips this step, shaving time off every install.

... thus shifting the bytecode compilation burden to first startup after install. You're still paying for the bytecode compilation (and it's serialized, so you're actually spending more time), but you don't associate the time with your package manager.

I mean, sure, avoiding tons of Python subprocesses helps, but in our bold new free threaded world, we don't have to spawn so many subprocesses.

pc486 2 hours ago | parent | next [-]

>> Ignoring requires-python upper bounds. When a package says it requires python<4.0, uv ignores the upper bound and only checks the lower. This reduces resolver backtracking dramatically since upper bounds are almost always wrong. Packages declare python<4.0 because they haven’t tested on Python 4, not because they’ll actually break. The constraint is defensive, not predictive > > Man, it's easy to be fast when you're wrong. But of course it is fast because Rust not because it just skips the hard parts of dependency constraint solving and hopes people don't notice.

Version bound checking is NP complete but becomes tractable by dropping the upper bound constraint. Russ Cox researched version selection in 2016 and described the problem in his "Version SAT" blog post (https://research.swtch.com/version-sat). This research is what informed Go's Minimal Version Selection (https://research.swtch.com/vgo-mvs) for modules.

It appears to me that uv is walking the same path. If most developers don't care about upper bounds and we can avoid expensive algorithms that may never converge, then dropping upper bound support is reasonable. And if uv becomes popular, then it'll be a sign that perhaps Python's ecosystem as a whole will drop package version upper bounds.

quotemstr an hour ago | parent [-]

Perhaps so, although I'm more algorithmically optimistic. If ignoring upper bounds makes the problem more tractable, you can

1. solve dependency constraints as if upper bounds were absent,

2. check that your solution actually satisfies constraints (O(N), quick and passes almost all the time), and then

3. only if the upper bound constraint check fails, fall back to the slower and reliable parser.

This approach would be clever, efficient, and correct. What you don't get to do is just ignore the fucking rules to which another system studiously adheres then claim you're faster than that system.

That's called cheating.

chuckadams an hour ago | parent | next [-]

If ignoring the rules makes it faster, then it's still faster. uv has never claimed to be 100% compatible. How often is it actually incorrect?

quotemstr an hour ago | parent [-]

My groceries are cheaper if I walk out of the store without paying for them too. Who's going to stop me?

While I agree that an optimistic optimization for the upper-bound-pass case makes sense, just ignoring the bounds just isn't correct either.

Common pattern in insurgent software is to violate a specification, demonstrate speedups, and then compare yourself favorably to older software that implements the spec (however stupid) faithfully.

an hour ago | parent [-]
[deleted]
tyre an hour ago | parent | prev [-]

It’s not cheating if it works

asa400 an hour ago | parent | prev | next [-]

> Man, it's easy to be fast when you're wrong. But of course it is fast because Rust not because it just skips the hard parts of dependency constraint solving and hopes people don't notice.

What's underhanded about this? What are the observable effects of this choice that make it wrong? They reformulated the a problem into a different problem that they could solve faster, and then solved that, and got away with it. Sounds like creative problem solving to me.

naedish 2 hours ago | parent | prev | next [-]

> uv ignores pip’s configuration files entirely. No parsing, no environment variable lookups, no inheritance from system-wide and per-user locations.

Stuff like this sense unlikely to contribute to overall runtime, but it does decrease flexibility.

Astral have been very clear that they have no intention of replicating all of pip. uv pip install was a way to smooth the transition from using pip to using uv. The point of uv wasn't to rewrite pip in rust - and thankfully so. For all of the good that pip did it has shortcomings which only a new package manager turned out capable of solving.

> No bytecode compilation by default. pip compiles .py files to .pyc during installation. uv skips this step, shaving time off every install.

... thus shifting the bytecode compilation burden to first startup after install. You're still paying for the bytecode compilation (and it's serialized, so you're actually spending more time), but you don't associate the time with your package manager.

In most cases this will have no noticeable impact (so a sane default) - but when it does count you simply turn on --compile-bytecode.

quotemstr an hour ago | parent [-]

I agree that bytecode compilation (and caching to pyc files) seldom has a meaningful impact, but it's nevertheless unfair to tout it as an advantage of uv over pip, because by doing so you've constructed an apples to oranges comparison.

You could argue that uv has a better default behavior than pip, but that's not an engineering advantage: it's just a different choice of default setting. If you turned off eager bytecode compilation in pip you'd get the same result.

oblio an hour ago | parent [-]

> You could argue that uv has a better default behavior than pip, but that's not an engineering advantage: it's just a different choice of default setting. If you turned off eager bytecode compilation in pip you'd get the same result.

Until pip does make the change, this is an engineering advantage for uv. Engineers working on code are part of the product. If I build a car with square wheels and don't change them when I notice the issue, my car still has a bumpy ride, that's a fact.

IshKebab 2 hours ago | parent | prev [-]

> Man, it's easy to be fast when you're wrong.

There's never going to be a Python 4 so I don't think they are wrong. Even if lighting strikes thrice there's no way they could migrate people to Python 4 before uv could be updated to "fix" that.

> Ambiguity detection is important.

I'm not sure what you mean here. Pip doesn't detect any ambiguities. In fact Pip's behaviour is a gaping security hole that they've refused to fix, and as far as I know the only way to avoid it is to use `uv` (or register all of your internal company package names on PyPI which nobody wants to do).

> thus shifting the bytecode compilation burden to first startup after install

Which is a much better option.

jjgreen 2 hours ago | parent | next [-]

There's never going to be a Python 4

There will, but called Pyku ...

quotemstr an hour ago | parent | prev [-]

> Pip doesn't detect any ambiguities. In fact Pip's behaviour is a gaping security hole that they've refused to fix, and as far as I know the only way to avoid it is to use `uv`

Agreed the current behavior is stupid, FWIW. I hope PEPs 708 and 752 get implemented soon. I'm just pointing out that there's an important qualitative difference between

1. we do the same job, but much faster; and

2. we decided your job is stupid and so don't do it, realizing speedups.

uv presents itself as #1 but is actually #2, and that's a shame.

stouset 7 minutes ago | parent [-]

If it turns out nobody is actually relying on, using, or benefiting from those behaviors #1 and #2 are the same thing.