Fix target version inference for strict-greater requires-python specifiers - #5269
Fix target version inference for strict-greater requires-python specifiers#5269harisawan-bit wants to merge 3 commits into
Conversation
…fiers Per PEP 440, '>3.7' is equivalent to '>3.7.0', so any 3.7.x (e.g. 3.7.0) is included. strip_specifier_set only widened a '>' operator to '>=' when a patch component was present, so '>3.7' was left strict and dropped py37 from the inferred target versions. Now '>' becomes '>=' whenever a minor version is present, matching '>3.7.0' / '>=3.7'. Fixes psf#3581
for more information, see https://pre-commit.ci
|
Thanks @harisawan-bit! To fix the failing CI, please run Black on the codebase and change the issue number in CHANGES.md to the PR number. This PR could theoretically change formatting in very niche cases, so it should theoretically be gated behind try:
...
except (a, b):
...Black currently cannot determine a target version from Since most changes lower the detected target version, and Black does not downcompile syntax (meaning if you run Black with Adding to the complexity, this can't be gated under Looking at the related #3583, I took the advantage to also change
I can either push those changes to this PR, or make a new one, partially depending on how we decide to handle the |
|
Using ">" (as opposed to ">=") in requires-python is very questionable anyway. Does it ever get used? Has there been discussion in the packaging ecosystem of whether this option should even be supported? |
|
The use of > in requires-python is indeed valid per PEP 440, which specifies that >3.7 is equivalent to >3.7.0. This means that any version 3.7.x (e.g., 3.7.0) should be included. The fix ensures that Black's target version inference aligns with this specification, making the behavior consistent and predictable. While it may not be commonly used, supporting it ensures compliance with the PEP 440 standard and avoids potential confusion or errors in edge cases. |
Summary
Fixes #3581 — Black's target-version inference from
requires-pythondropped valid Python versions for strict-greater specifiers.Per PEP 440,
>3.7is equivalent to>3.7.0, so any3.7.x(e.g.3.7.0) is included.strip_specifier_setonly widened a>operator to the inclusive>=when a patch component was present (len(release) > 2), so>3.7was left strict andpy37was dropped from the inferred target versions.Now
>becomes>=whenever a minor version is present, making>3.7behave like>3.7.0/>=3.7.Before / after
>3.7,<3.10py38, py39py37, py38, py39>3.7,!=3.8,!=3.9py310..py315py37, py310..py315>3.10,<3.11Nonepy310>=3.7/>3.7.0These all now match the equivalent
>=3.7/>3.7.0forms, as PEP 440 requires.Test plan
test_infer_target_versionexpectations to the PEP 440-compliant results.test_infer_target_version_pep440_greater_thanregression test (covers Inference of target versions fromrequires-pythonconfig is incorrect. #3581).pytest tests/test_black.py -k infer_target_versionpasses.Checklist