Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Make < exclusive for non-prerelease markers #1878

Merged
merged 7 commits into from
Feb 24, 2024
Merged

Conversation

charliermarsh
Copy link
Member

@charliermarsh charliermarsh commented Feb 22, 2024

Summary

Even when pre-releases are "allowed", per PEP 440, pydantic<2.0.0 should not include pre-releases. This PR modifies the specifier translation to treat pydantic<2.0.0 as pydantic<2.0.0.min0, where min is an internal-only version segment that's invisible to users.

Closes #1641.

@charliermarsh
Copy link
Member Author

I think (1) and (2) could be "solved" by only applying this logic when pre-releases are already enabled for a given package.

@mitsuhiko
Copy link
Collaborator

What if there is a PreRelease { kind: PreReleaseKind::PreReleaseHack, number: 0}`` (find a better name) that behaves as a perfect match to a0but is special cased in rendering. It would show up as2.0.0rather than2.0.0.a0` maybe with an additional indicator about how it considers prerelease versions.

          attrs>20.3.0,<21.2.0 (including pre) cannot be used.
          And because you require attrs>20.3.0,<21.2.0 (including pre), we can conclude that the

@charliermarsh charliermarsh force-pushed the charlie/pre-pydantic branch 3 times, most recently from 2be8dfe to 170a2a6 Compare February 22, 2024 17:32
@charliermarsh charliermarsh marked this pull request as ready for review February 22, 2024 17:32
@charliermarsh
Copy link
Member Author

@mitsuhiko - That's also interesting, it could work, though I still wonder if including the pre-release info is useful in cases in which pre-releases are entirely omitted.

@charliermarsh charliermarsh added the bug Something isn't working label Feb 22, 2024
@charliermarsh
Copy link
Member Author

\cc @Czaki who brought up the idea on GitHub.

@Czaki
Copy link
Contributor

Czaki commented Feb 22, 2024

Hm. Why is pre-release even triggered by upper constraint? All time when I would like to test pre-release of some package or see such case, the lower bound is used. But my experience may be not so big.

I wil ltry to check code later.

@dimbleby
Copy link

dimbleby commented Feb 22, 2024

.dev0 comes before .a0 anyway

Within a numeric release (1.0, 2.7.3), the following suffixes are permitted and MUST be ordered as shown:

.devN, aN, bN, rcN, <no suffix>, .postN

@Czaki
Copy link
Contributor

Czaki commented Feb 22, 2024

.dev0 comes before .a0 anyway

Within a numeric release (1.0, 2.7.3), the following suffixes are permitted and MUST be ordered as shown:

.devN, aN, bN, rcN, <no suffix>, .postN

And cannot by uploaded to pypi.

@dimbleby
Copy link

And cannot by uploaded to pypi.

alas the world is complicated: pypi is not the only source of distributions

either way, if the intention is to make <2 exclude pre-releases, might just as well exclude .dev releases too.

another way might be to represent this as something like <=1.infinity, which might work better as being something that you could easily recognise when writing it back: no-one could actually write that down, whereas if what you have is <2.0.0.dev0 you cannot be certain that this was not the original constraint all along

@charliermarsh
Copy link
Member Author

This makes sense, I'll likely change to dev.

@mitsuhiko
Copy link
Collaborator

I would just honestly really represent it as something that is not parsable. The PreReleaseHack can basically act as the .infinity proposal. It can only be expressed by the resolver internally and is otherwise never valid input.

@konstin
Copy link
Member

konstin commented Feb 22, 2024

Have you checked that this also applies to 2.0.0.a0.dev0?

@charliermarsh
Copy link
Member Author

I honestly don't mind representing this (even to users) as <2.0.0.dev. If they see this, then they opted-in to pre-release handling (it doesn't get included otherwise).

@charliermarsh
Copy link
Member Author

Okay, now using @mitsuhiko's suggested approach which I will begrudgingly admit is a better solution :)

Now handles all cases correctly, even:

apache-airflow[otel]
opentelemetry-exporter-prometheus<0.44

From the brilliant @notatallshaw (thank you for that).

Copy link
Member

@BurntSushi BurntSushi left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This LGTM, but you'll definitely need to bump the simple cache version in order to invalidate extant caches due to the change in representation of Version. (Apologies if you did that and I missed it.)

Copy link
Member

@BurntSushi BurntSushi left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sweet

@charliermarsh charliermarsh merged commit 8d706b0 into main Feb 24, 2024
7 checks passed
@charliermarsh charliermarsh deleted the charlie/pre-pydantic branch February 24, 2024 23:02
yasufumy pushed a commit to yasufumy/uv that referenced this pull request Feb 25, 2024
## Summary

Even when pre-releases are "allowed", per PEP 440, `pydantic<2.0.0`
should _not_ include pre-releases. This PR modifies the specifier
translation to treat `pydantic<2.0.0` as `pydantic<2.0.0.min0`, where
`min` is an internal-only version segment that's invisible to users.

Closes astral-sh#1641.
charliermarsh added a commit that referenced this pull request Mar 15, 2024
## Summary

This PR attempts to use a similar trick to that we added in
#1878, but for post-releases.

In #1878, we added a fake "minimum"
version to enable us to treat `< 1.0.0` as _excluding_ pre-releases of
1.0.0.

Today, on `main`, we accept post-releases and local versions in `>
1.0.0`. But per PEP 440, that should _exclude_ post-releases and local
versions, unless the specifier is itself a pre-release, in which case,
pre-releases are allowed (e.g., `> 1.0.0.post0` should allow `>
1.0.0.post1`).

To support this, we add a fake "maximum" version that's greater than all
the post and local releases for a given version. This leverages our last
remaining free bit in the compact representation.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Projects
None yet
Development

Successfully merging this pull request may close these issues.

pydantic<2.0.0 installs pydantic=2.0b3 when prereleases are allowed
8 participants