> Note the lack of an upper bound
Since uv needs a singular resolution that's entirely intentional. In npm you can install diverging resolutions for different parts of the tree but that is not an option with Python. I had to make the same decision in Rye and there is just no better solution here.
If an upper bound were to be supplied you would end up with trees that can no longer resolve in practice. Some package ecosystems in Python even went as far as publishing overrides for old packages that got published with assumed upper bounds that ended up wrong.
Don't forget that you cannot know today if your package is going to be compatible or incompatible with a not yet released package.
Arguably the other reason for a lack of a default upper bound stems from PyPI has never required semver for hosted packages, there are plenty of packages on PyPI still using calver or marver or other more bespoke version schemes. (Whereas npm has always made semver an assumption/"requirement" for hosted packages.)
As someone part of the problem with a couple ancient packages in PyPI that are calver (though arguably I'd be surprised if many depended on them), I wonder if it is too late for more of the Python ecosystem to shift more directly to semver by default/everywhere as some of the other ecosystems now are.
The lack of an upper bound in pyproject.toml isn’t the real problem. The real problem is that `uv lock —-upgrade` does a wholesale upgrade of everything without an upper bound. If there was a way to upgrade packages without updating the major version, this command would be a lot safer to run.
As much as uv has improved the situation, I have to imagine that there's plenty of stuff like this that fundamentally is impossible to address via tooling. It's incredible how much the situation seems to have improved compared to before it was around, but it seems like things might never be totally good without the ecosystem as a whole making some breaking changes, and I'm guessing after the whole 2->3 situation there's not much appetite for something like that any time soon.
What you’re saying makes sense for library authors. But when I make a website and I depend on a bunch of packages, that’s where I want to be safe when upgrading and I want that upper bound. The —-bound flag really helps, but is one more thing to type and remember.
Maybe when uv knows the project isn’t a library it could default to upper bounds?
That part of the article almost read like clickbait, because at the end he admits there is an upper bound arg:
> uv add pydantic --bounds major
So not really sure what he's complaining about
Also it doesn't even matter because the real way to use both uv and npm is to switch everything to = and only update manually, rather than trusting non-major updates not to break anything
>If an upper bound were to be supplied you would end up with trees that can no longer resolve in practice.
And then we'd have to run uv again with an argument to not have upper bounds. Oh, the humanity!
As opposed, to it nuking our dependencies with incompatible packages.
Doesn't sound like the unsafe option should be the default.
The entire purpose of semver is to give you a way to resolve that conundrum. New major version = assume it's incompatible.
I mean, it may not actually work, but that's what it's for.
isn't ~= supported by uv or the discussion is about uv not adding it when package is added by command line rather than editing pyproject file? ~= is standard practice for me, as I always rather edit the file than memorize the commands.
“It’s tough to make predictions, especially about the future.”--Yogi Berra
[dead]
Personally, I'd rather get an error from uv that packages aren't compatible when I run update, with a way to override that if needed, than get an error at runtime that may be difficult to track down to incompatible versions.