You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Before merging I wanted to do another pass of finding edge cases, and I found a particularly problematic one. `<V.postN` (where V is not a pre-release) excludes pre-releases sharing V's base release via `_compare_less_than`. The interval model represents `<1.0.post1` as `(-inf, 1.0.post1.dev0)`, which is correct for non-pre-release versions but too wide for pre-releases: it includes `1.0.dev0`, `1.0a1`, `1.0.post0.dev0`, etc. that `_compare_less_than` actually rejects.
2
+
3
+
This caused my current approach to miss cases like `==1.0.dev0,<1.0.post1`. As `1.0.dev0` falls inside the interval `(-inf, 1.0.post1.dev0)` so the intersection with `==1.0.dev0` looks non-empty. But `filter()` returns nothing because `_compare_less_than` rejects `1.0.dev0` (it is a pre-release of base `1.0`, same base as `1.0.post1`).
4
+
5
+
Or another case `>=1.0.dev0,<1.0.post1,!=1.0,!=1.0.post0`. After `!=` removes the two non-pre-release versions (`1.0` and `1.0.post0`), only pre-releases remain. All of them are excluded by `<1.0.post1`, but the interval still looks non-empty.
6
+
7
+
The non-pre-release versions that `<1.0.post1` accepts (`1.0`, `1.0.post0`) are interleaved with pre-releases it rejects (`1.0.dev0`, `1.0.post0.dev0`) on the version number line:
This is correct but produces N+2 intervals for `<V.postN`, and also requires fixing `_BoundaryVersion` comparison for `AFTER_POSTS` vs `AFTER_LOCALS` with different base versions.
23
+
24
+
Instead I went with keeping the single interval `(-inf, 1.0.post1.dev0)` but tagging the upper bound with the excluded base release. During intersection, `_interval_is_empty` uses this tag to check whether any non-pre-release version of the base survives in the interval. The check derives the relevant post number from the lower bound in O(1) instead of iterating. Concretely: `_UpperBound` gets an `_excl_base` field set by `<V.postN`, `_interval_is_empty` checks if the interval contains a surviving non-pre-release version when the tag is present, and `_intersect_intervals` propagates the tag through `with_excl()`.
0 commit comments