Repository navigation
Fix ~=X.Y.Z requires-python inferring later Python versions - #5578
Open
beniamin-levin wants to merge 3 commits into
Open
beniamin-levin wants to merge 3 commits into
beniamin-levin wants to merge 3 commits into
Conversation
`~=3.11.0` means `>=3.11.0, ==3.11.*`, but strip_specifier_set turned it into `~=3.11`, which allows every later Python 3 version, so target version inference returned py311 through py315. A `~=` with a patch component is now stripped to `==X.Y.*`; the two-part form `~=3.11` is unchanged. The change was proposed by NVIDIA Nemotron through FixedYet and verified in its sandbox, then moved to the literal `==X.Y.*` form with a comment in review. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…elog Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
beniamin-levin
marked this pull request as ready for review
October 22, 2026 07:16
2 tasks done
This branch has not been deployed
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Description
Fixes #5468.
strip_specifier_setturned~=3.11.0into~=3.11. That drops the upper bound:~=3.11.0means>=3.11.0, ==3.11.*(only 3.11), while~=3.11means>=3.11, ==3.*. Sorequires-python = "~=3.11.0"inferred py311 through py315. A compatible-release specifier with a patch component (three or more release parts) is now stripped to==X.Y.*; the two-part form is unchanged.requires-pythonmain~=3.11.0,~=3.11.7,~=3.11.0rc1,~=3.11.0.1~=3.9.2,!=3.9.5~=3.11~=3.0.0Stability. The minimum inferred target version never rises. For
~=3.7.xthrough~=3.15.xthe feature set of the inferred targets is the same onmainand with this change (checked for every minor version, with and without a patch number), so stable formatting does not change. Only~=3.3.xto~=3.6.xdiffer, and there the new result is the correct one. In a sweep of 6,084 single and pairwise specifier sets, the 445 results that changed all come from a set containing a~=with three or more release parts.Known edge, not changed here.
~=3.11.4,!=3.11.0and~=3.11.0,>3.11now give None (onmainthey gave py312 and up; the right answer is py311). That comes from the existing handling of!=X.Y.0and of a two-part>(#3581), not from this change.An earlier pull request for this issue, #5469, took the same approach and was closed by its author without a review. This one was made independently, as described below.
How this was made (AI disclosure). FixedYet, a tool that reproduces bug reports in a sandbox, wrote a failing test for the issue on
main; NVIDIA Nemotron, through FixedYet, proposed the change tostrip_specifier_set, and FixedYet verified it (the test fails without it and passes with it, and the suite had no new failures). A review with Claude (Anthropic) checked it against PEP 440, moved it to the literal==X.Y.*form with a comment, and added the table cases and the changelog entry. I read the final diff myself before marking this ready for review.Checked locally with Black's CI commands, in a clean Python 3.12 container:
pytest tests --run-optional no_jupyter --numprocesses auto: 596 passed, 1 skipped (IPython is optional), the same as onmainpytest tests --run-optional jupyter -m jupyter --numprocesses auto: 83 passedCHANGES.md: cleanmainwithout the changeChecklist - did you ...
--previewstyle, following the stability policy? (not a style change; see Stability above)CHANGES.mdif necessary?