Skip to content

fix(ranges): require matching pre-release policy in difference#1306

Open
notatallshaw wants to merge 1 commit into
pypa:mainfrom
notatallshaw:ranges-difference-check-policy
Open

fix(ranges): require matching pre-release policy in difference#1306
notatallshaw wants to merge 1 commit into
pypa:mainfrom
notatallshaw:ranges-difference-check-policy

Conversation

@notatallshaw

Copy link
Copy Markdown
Member

intersection and union raise on operands with different configured pre-release policies; difference did not, so a - b succeeded where the equivalent a & ~b raises, and dropped a pre-release the subtrahend's policy excludes (e.g. >=1.0 minus >=2.0b1 with prereleases=False drops 2.0b1, which is in a and not in b).

intersection and union raise on operands with different configured
pre-release policies; difference did not, so a - b silently succeeded
where a & ~b raised, dropping a pre-release the subtrahend's policy
excludes. Add the same _check_policy_compat guard.
@henryiii

henryiii commented Jul 2, 2026

Copy link
Copy Markdown
Contributor

Codex likes to check ===. I don't think this is something to worry about for this PR, but might be useful for later.

🤖 AI text below 🤖

The new set-relation API can report incorrect subset/superset results for ranges with arbitrary-equality literal admissions. This is a user-visible semantic bug in the added functionality.

Review comment:

  • [P2] Account for literal admissions in subset checks — /Users/henryfs/git/pypa/packaging/src/packaging/ranges.py:810-810
    When self has an === literal that other does not, this fallback can return True incorrectly because other.complement() is one-way for literals and does not admit every non-matching literal. For example, (SpecifierSet('===a').to_range() | SpecifierSet('===b').to_range()).is_subset(SpecifierSet('===a').to_range()) returns True even though 'b' is contained only in the left side; is_superset() inherits the same false positive.

Comment thread src/packaging/ranges.py

On the version set this matches ``self & ~other``, but the result keeps
On the version set this matches ``self & ~other``, and the result keeps
only ``self``'s admissions and pre-release policy: a non-version string

@henryiii henryiii Jul 2, 2026

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Does keeping only self's pre-release policy matter if you now throw an error if they don't match? (in the description)

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

Yes, the error is thrown on the configured policy being different (prerelease=None, True, False), not on the implied policy (prerelease=None and <1 vs. <1.0dev0).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants