Because uploads to PyPI are not atomic. They’re now capped within a 14 day window, but it would be extremely confusing to users to have the “release” hash of their dependencies change repeatedly.
(Also: we’d need to determine what it even means to hash a set of files. Do we order by canonicalized filename, by upload time, etc. Each of these has surprising implications!)
Edit: to be clear, it’s not ideal or fully intentional that uploads to PyPI are not atomic. But it’s the status quo and any change will take years.
> Because uploads to PyPI are not atomic. They’re now capped within a 14 day window, but it would be extremely confusing to users to have the “release” hash of their dependencies change repeatedly.
Aren’t releases versioned, using semantic versioning?
If not, why shouldn’t a change in dependencies not trigger a new release version?
If it is versioned and if there’s a corresponding hash to the release, why wouldn’t I also expect that to change when the version and dependencies change?
I can understand that there may be historical reasons that this scheme will break how PyPI releases are built and distributed, but I also hope you understand that it violates the principle of least surprise.
Python uses PEP 440 versioning, which isn’t semver. Semver is de facto common, however, and can be expressed as a subset of PEP 440.
I’m not sure what you mean by “change in dependencies”: every release has zero or more distributions (“files”), and each distribution in a release can specify its own dependencies. For example, a macOS-specific wheel might depend on something that Linux-specific wheels don’t need or vice versa.
> but I also hope you understand that it violates the principle of least surprise.
I think it’s fair to say that virtually everything about Python packaging violates POLA :-)
These things you’re posing as design questions are already solved 1 million times over. If you don’t want to design something new, just use Git semantics. These are not excuses for inaction. Python package management has been a horrifying embarrassment for 15 years and there’s no excuse for the amount it’s been neglected as every other ecosystem has shown better ways.
If it weren’t for AI, Python would have died as a language ecosystem due to their perpetual neglect of this area. The python community clearly had no ability to solve this problem themselves. I got sick and left and started using better tools.
It’s only now that they’re the cornerstone of the world economy that other people are coming in and cleaning up their messes for them. It’s pitiful. Python failed and needed to be saved from itself.
The semantics are important. A release is composed of multiple distributions (sets of files). Each distribution does have a one-way hash value. This is what you lock to. Adding files does change the value of that hash. Files cannot be removed or changed.
You lock to the distribution instead of the release so your build doesn't have to download distributions for platforms you're not using.
Which is the entire problem. "Release" should be a signed hash of a manifest file that contains hashes of all the other files (in case of Git that's what commit does).
PyPi just decided to do what VCSes already did, worse
It’s not. Steel manning the OP (which at face value seems to be the most reasonable interpretation) they’re wondering why an entire release isn’t hash pinned.
The response is that there is hash pinning but only at the constituent levels. Which clearly isn’t what the OP meant.
(Also: we’d need to determine what it even means to hash a set of files. Do we order by canonicalized filename, by upload time, etc. Each of these has surprising implications!)
Edit: to be clear, it’s not ideal or fully intentional that uploads to PyPI are not atomic. But it’s the status quo and any change will take years.