Fix Version.difference with a local variant of the same version - #953
Fix Version.difference with a local variant of the same version#953apoorvdarshan wants to merge 2 commits into
Conversation
Version("2.12.1").difference(Version("2.12.1+cpu")) returned self
unchanged, which still allows 2.12.1+cpu — the subtraction made no
progress, sending poetry's solver into an infinite loop when the same
release was available from multiple sources with different local tags.
Delegate to the equivalent single-point VersionRange, whose difference
arithmetic can represent the split, yielding >=2.12.1,<2.12.1+cpu.
Resolves python-poetry/poetry#10965
There was a problem hiding this comment.
Hey - I've left some high level feedback:
- In the new
differencebranch, consider explicitly checkingnot self.is_local()andother.is_local()(rather than relying solely onself.allows(other)) so the special-case delegation toVersionRange.differenceis clearly limited to the non-local vs local-variant scenario and remains robust ifallows()semantics evolve.
Prompt for AI Agents
Please address the comments from this code review:
## Overall Comments
- In the new `difference` branch, consider explicitly checking `not self.is_local()` and `other.is_local()` (rather than relying solely on `self.allows(other)`) so the special-case delegation to `VersionRange.difference` is clearly limited to the non-local vs local-variant scenario and remains robust if `allows()` semantics evolve.Help me be more useful! Please click 👍 or 👎 on each comment and I'll use the feedback to improve your reviews.
|
Re the Sourcery suggestion: at that point in the method |
|
When I try to reproduce the example from python-poetry/poetry#10965 with this fix, I get a |
|
Thanks — I reproduced the full scenario and confirmed the distinction. The original change prevents the non-progressing subtraction, but the lock then fails separately in Poetry's compatibility-result aggregation with I pushed a follow-up that also fixes the constraint representation: subtracting one local variant now preserves local variants ordered on both sides instead of truncating everything above it. The constraints suite passes (1001 tests). I also changed the PR from “Resolves” to “Related” and documented that it does not by itself solve the remaining Poetry-side aggregation failure. |
Related: python-poetry/poetry#10965
Problem
A public
Versionuses PEP 440 weak equality and therefore allows all local variants of the same public version:Previously
differencereturnedpublicunchanged, so it still allowed the version that had just been subtracted. Constraint solving could therefore make no progress.Fix
Represent the public version and all its local variants as a half-open range ending at the next post release (or next development release for dev versions), then subtract the requested local version. This preserves local variants on both sides of the removed value while excluding post/dev successors.
Verification
tests/constraints/version/test_version.py: 206 passed.tests/constraints/: 1001 passed.Scope
This corrects the non-progressing
Version.difference()operation identified while investigating python-poetry/poetry#10965. Re-running that issue's full Poetry reproduction now proceeds past the infinite loop but exposes a separateKeyError: Package('triton', '3.7.1')in Poetry's compatibility-result aggregation. This PR no longer claims to fully resolve that Poetry-side failure.Disclosure
This fix was developed with the assistance of AI tooling; I manually reviewed the constraint semantics, reproduced the original Poetry scenario, and ran the tests above.