-
Notifications
You must be signed in to change notification settings - Fork 15
Fix semver #6576
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Fix semver #6576
Changes from all commits
c948d73
0376554
bdf2874
203561f
085c40d
a907bf9
80baafc
ee4816d
4fde49d
5dc42a5
a2cd300
dced20d
5342231
5b62756
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -6,15 +6,75 @@ | |
| from .const import TestDeclaration | ||
|
|
||
|
|
||
| from semantic_version.base import AllOf, Never, Range, Version | ||
|
|
||
|
|
||
| # semver module offers two spec engine : | ||
| # 1. SimpleSpec : not a good fit because it does not allows OR clause | ||
| # 2. NpmSpec : not a good fit because it disallow prerelease version by default (6.0.0-pre is not in ">=5.0.0") | ||
| # So we use a custom one, based on NPM spec, allowing pre-release versions | ||
| class _CustomParser(semver.NpmSpec.Parser): | ||
| # [CHANGED] Override range() to use PRERELEASE_ALWAYS policy on all clauses. | ||
| # The library defaults to PRERELEASE_SAMEPATCH which excludes prereleases | ||
| # from non-prerelease specs (e.g. 6.0.0-pre not in ">=5.0.0"). | ||
| @classmethod | ||
| def range(cls, operator: Any, target: Any) -> semver.base.Range: # noqa: ANN401 | ||
| return semver.base.Range(operator, target, prerelease_policy=semver.base.Range.PRERELEASE_ALWAYS) | ||
|
|
||
| # [CHANGED] Override parse() to fix prerelease handling. | ||
| # The library splits prerelease clauses into separate branches that break | ||
| # alphabetical ordering (e.g. 2.7.0-rc.4 incorrectly matches "<2.7.0-dev"). | ||
| # Our version removes that split and uses clauses directly, relying on | ||
| # PRERELEASE_ALWAYS from range() for correct semver comparison. | ||
| @classmethod | ||
| def parse(cls, expression: str) -> AllOf: | ||
| result = Never() | ||
| # [IDENTICAL] Split on || for OR groups | ||
| groups = expression.split(cls.JOINER) | ||
| for raw_group in groups: | ||
| group = raw_group.strip() or ">=0.0.0" | ||
|
|
||
| subclauses = [] | ||
| # [IDENTICAL] Hyphen range handling | ||
| if cls.HYPHEN in group: | ||
| low, high = group.split(cls.HYPHEN, 2) | ||
| subclauses = cls.parse_simple(">=" + low) + cls.parse_simple("<=" + high) | ||
| else: | ||
| # [IDENTICAL] Block parsing and validation | ||
| blocks = group.split(" ") | ||
| for block in blocks: | ||
| if not cls.NPM_SPEC_BLOCK.match(block): | ||
| raise ValueError(f"Invalid NPM block in {expression!r}: {block!r}") | ||
| parsed = cls.parse_simple(block) | ||
| # [CHANGED] Caret upper bound: ^1.2.3 expands to >=1.2.3 <2.0.0. | ||
| # Replace <X.Y.Z with <X.Y.Z-0 so prereleases of the next major | ||
| # are excluded (e.g. 2.0.0-alpha not in ^1.2.3). | ||
| if block.startswith("^"): | ||
| for clause in parsed: | ||
| if clause.operator == Range.OP_LT and not clause.target.prerelease: | ||
| subclauses.append( | ||
| cls.range( | ||
| operator=Range.OP_LT, | ||
| target=Version( | ||
| major=clause.target.major, | ||
| minor=clause.target.minor, | ||
| patch=clause.target.patch, | ||
| prerelease=("0",), | ||
| ), | ||
| ) | ||
| ) | ||
| else: | ||
| subclauses.append(clause) | ||
| else: | ||
| subclauses.extend(parsed) | ||
|
|
||
| # [CHANGED] Use subclauses directly instead of the library's prerelease split. | ||
| # The library separates prerelease/non-prerelease clauses and recombines them | ||
| # with extra bounds, which breaks direct prerelease comparison. | ||
| result |= AllOf(*subclauses) | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Using Useful? React with 👍 / 👎. |
||
|
|
||
| return result | ||
|
|
||
|
|
||
| class SemverRange(semver.NpmSpec): | ||
| Parser = _CustomParser | ||
|
|
||
Uh oh!
There was an error while loading. Please reload this page.