Requires-Python upper limits

Just to note, there is at least one other outstanding use case that Option 1 not only doesn’t solve, but rather makes actively worse: backports of stdlib packages, which are not intended to be used on Python versions that has the stdlib package installed (as the latter will usually shadow the former…except when it doesn’t, in pathological cases) and just cause extra bandwidth, install time and user confusion.

In this case, upper-capping as it is currently implemented works if every (non-yanked, pre-release, and otherwise compatible) release of the backport package has the upper cap. However, if implemented ex-post-facto, like for typing, all it does is make pip backtrack to the previous release that doesn’t have it and install that instead—which is exactly what is happening in that case, as clients on later Python versions are just installing an earlier version of typing (witness the distribution of package versions vs. Python versions.

Right now, this means for existing packages that to solve this, we need to go with the less elegant approach of having a lower-capped sdist-only install that errors on install, warns, or warns and installs an empty package unless the package has been upper capped its whole life (which still triggers an inefficient backsearch of every release version). If I’m following right, the former is pretty close to the recommended workaround here. However, that workaround will stop working if pip moves to --only-binary by default, which seems to be under serious consideration, Furthermore, with the changes in option 1 here, even upper-capping all versions will not be officially supported and produce a warning (and Option 3 would be similar, except it won’t work at all). Under that scenario, I’m not sure how we’re supposed to handle this situation.

By contrast, Option 2 would fix all of this for this use case and be a strict improvement here; typing would be fixed as-is, and the others could be fixed similarly, with just a post-release adding the upper-cap to the metadata of the latest release. I’m not sure if that’s strong enough grounds to implement it, but I’m curious what else we’re expected to do in this use case, as with --only-binary + a warning or removal of the upper-capping behavior, we’d be basically out of options short of yanking every version of the package (which in pip < 22 would just produce a warning, but in pip >= 22 would cause huge unnecessary breakage).

2 Likes