diff --git a/src/poetry/core/semver/helpers.py b/src/poetry/core/semver/helpers.py index 0ce090d89..690bb17d9 100644 --- a/src/poetry/core/semver/helpers.py +++ b/src/poetry/core/semver/helpers.py @@ -77,10 +77,14 @@ def parse_single_constraint(constraint: str) -> VersionConstraint: m = TILDE_PEP440_CONSTRAINT.match(constraint) if m: version = Version.parse(m.group("version")) - if version.release.precision == 2: + precision = version.release.precision + + if precision == 2: high = version.stable.next_major() - else: + elif precision == 3: high = version.stable.next_minor() + else: + high = version.stable.next_patch() return VersionRange(version, high, include_min=True) @@ -97,12 +101,16 @@ def parse_single_constraint(constraint: str) -> VersionConstraint: op = m.group("op") major = int(m.group(2)) minor = m.group(3) + patch = m.group(4) - if minor is not None: - version = Version.from_parts(major, int(minor), 0) + if patch is not None: + version = Version.from_parts(major, int(minor), int(patch)) result: VersionConstraint = VersionRange( - version, version.next_minor(), include_min=True + version, version.next_patch(), include_min=True ) + elif minor is not None: + version = Version.from_parts(major, int(minor), 0) + result = VersionRange(version, version.next_minor(), include_min=True) else: if major == 0: result = VersionRange(max=Version.from_parts(1, 0, 0)) diff --git a/tests/semver/test_helpers.py b/tests/semver/test_helpers.py index d53e9e57d..7e6eba771 100644 --- a/tests/semver/test_helpers.py +++ b/tests/semver/test_helpers.py @@ -66,6 +66,12 @@ def test_parse_constraint(input: str, constraint: Version | VersionRange) -> Non Version.from_parts(20, 0, 0), Version.from_parts(21, 0, 0), True ), ), + ( + "20.*.*.*", + VersionRange( + Version.from_parts(20, 0, 0), Version.from_parts(21, 0, 0), True + ), + ), ( "2.0.*", VersionRange( @@ -90,6 +96,24 @@ def test_parse_constraint(input: str, constraint: Version | VersionRange) -> Non Version.from_parts(2, 2, 0), Version.from_parts(2, 3, 0), True ), ), + ( + "2.2.3.*", + VersionRange( + Version.from_parts(2, 2, 3), Version.from_parts(2, 2, 4), True + ), + ), + ( + "2.2.3.X", + VersionRange( + Version.from_parts(2, 2, 3), Version.from_parts(2, 2, 4), True + ), + ), + ( + "2.*.X.x", + VersionRange( + Version.from_parts(2, 0, 0), Version.from_parts(3, 0, 0), True + ), + ), ("0.*", VersionRange(max=Version.from_parts(1, 0, 0))), ("0.*.*", VersionRange(max=Version.from_parts(1, 0, 0))), ("0.x", VersionRange(max=Version.from_parts(1, 0, 0))), @@ -160,18 +184,27 @@ def test_parse_constraint_wildcard(input: str, constraint: VersionRange) -> None Version.from_parts(3, 5, 0), Version.from_parts(3, 6, 0), True ), ), + ], +) +def test_parse_constraint_tilde(input: str, constraint: VersionRange) -> None: + assert parse_constraint(input) == constraint + + +@pytest.mark.parametrize( + "input,constraint", + [ ( "~=3.5", VersionRange( Version.from_parts(3, 5, 0), Version.from_parts(4, 0, 0), True ), - ), # PEP 440 + ), ( "~=3.5.3", VersionRange( Version.from_parts(3, 5, 3), Version.from_parts(3, 6, 0), True ), - ), # PEP 440 + ), ( "~=3.5.3rc1", VersionRange( @@ -179,10 +212,16 @@ def test_parse_constraint_wildcard(input: str, constraint: VersionRange) -> None Version.from_parts(3, 6, 0), True, ), - ), # PEP 440 + ), + ( + "~=3.5.3.6", + VersionRange( + Version.from_parts(3, 5, 3, 6), Version.from_parts(3, 5, 4, 0), True + ), + ), ], ) -def test_parse_constraint_tilde(input: str, constraint: VersionRange) -> None: +def test_parse_constraint_tilde_pep440(input: str, constraint: VersionRange) -> None: assert parse_constraint(input) == constraint