Skip to content

Add pypa/packaging conformance tests for PEP 440 specifier parsing - #1776

Merged
Stella Huang (StellaHuang95) merged 1 commit into
microsoft:mainfrom
StellaHuang95:stellahuang/pep440-packaging-conformance-tests
Sep 11, 2026
Merged

Add pypa/packaging conformance tests for PEP 440 specifier parsing#1776
Stella Huang (StellaHuang95) merged 1 commit into
microsoft:mainfrom
StellaHuang95:stellahuang/pep440-packaging-conformance-tests

Conversation

@StellaHuang95

Copy link
Copy Markdown
Contributor

What

Adds a data-driven conformance suite that validates PythonVersionSpecifier /
PythonVersion against pypa/packaging, the reference PEP 440 implementation.

requires-python in a PEP 723 inline-script block is a PEP 440 version specifier, and
we evaluate it ourselves (in matchesPythonVersion) to choose a base interpreter and to
decide which Python version to ask uv to install. This pins that behaviour to the
reference implementation so edge cases can't drift.

118 cases ported from tests/test_specifiers.py:

Suite Cases Asserts
rejects specifiers packaging rejects 31 tryParse returns undefined
matches packaging semantics 85 matches() equals packaging's result
diverges from packaging by design 2 our intentional behaviour

How expected values were produced

They were generated by calling packaging 24.1 directly, not hand-transcribed.

Two things to know when re-generating:

  1. Prerelease semantics. Upstream's harness constructs Specifier(spec, prereleases=True),
    which is not packaging's default. Expected values here use the default, which is the
    correct model for requires-python. Against the default we match packaging on all 85 cases.
  2. Scope. Cases using epochs (2!1.0), local labels (2.0+deadbeef), post/dev releases,
    or more than three release segments are omitted. A Python interpreter version never has
    them, and PythonVersion deliberately does not model them (see its class doc).

The two intentional divergences

packaging's Specifier.prereleases auto-enables prereleases only for ==, >=, <=, ~=
and ===< and > are excluded. So under packaging's default:

  • >3.0.0a7 matches only final releases (3.0.0, 3.0.1); it rejects 3.0.0a8, 3.0.0b1, 3.0.0rc1
  • <3.0.0a8 rejects every 3.x prerelease

Our rule is uniform: any clause naming a prerelease enables prereleases. That is what the
class docs describe and what pythonVersionSpecifier.unit.test.ts already asserts for
<3.14.0rc2. These two cases are isolated in their own suite with the reason recorded, so
they're an explicit decision rather than an accidental mismatch.

Testing

  • 118/118 new tests pass
  • npm run lint clean on the new file
  • Full unit suite: 2220 passing, 0 failing

Licensing

pypa/packaging is dual-licensed Apache-2.0 / BSD-2-Clause. The ported test data is used
under BSD-2-Clause, with source, copyright and licence recorded in the file header.
No production code is affected — this PR adds a test file only.

Ports 118 cases from pypa/packaging's tests/test_specifiers.py to validate
PythonVersionSpecifier against the reference PEP 440 implementation:

- 31 invalid specifiers that must be rejected (test_specifiers_invalid)
- 85 version/specifier match cases (test_specifiers)
- 2 cases that intentionally differ from packaging, kept in their own suite

Expected values were generated by calling packaging with its DEFAULT prerelease
semantics, not the prereleases=True that the upstream harness forces.

Cases using epochs, local version labels, post/dev releases, or more than three
release segments are omitted: a Python interpreter version never has them, and
PythonVersion deliberately does not model them.

The two divergences are strict-inequality bounds naming a prerelease
(>3.0.0a7 and <3.0.0a8). packaging enables prereleases only for ==, >=, <=, ~=
and ===, so it filters them out; we enable prereleases for any clause naming
one, which pythonVersionSpecifier.unit.test.ts already asserts for <3.14.0rc2.

Test data is used under BSD-2-Clause; attribution is in the file header.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
@StellaHuang95
Stella Huang (StellaHuang95) merged commit c8009aa into microsoft:main Sep 11, 2026
45 of 46 checks passed
@StellaHuang95
Stella Huang (StellaHuang95) deleted the stellahuang/pep440-packaging-conformance-tests branch September 11, 2026 00:14
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants