diff --git a/src/poetry/core/packages/constraints/__init__.py b/src/poetry/core/packages/constraints/__init__.py index d61a2cb79..33cc902e4 100644 --- a/src/poetry/core/packages/constraints/__init__.py +++ b/src/poetry/core/packages/constraints/__init__.py @@ -51,12 +51,14 @@ def parse_single_constraint(constraint: str) -> Constraint: m = BASIC_CONSTRAINT.match(constraint) if m: op = m.group(1) + if op is None: op = "==" + version = constraint + else: + version = f"{constraint.strip()[len(op.strip()):]}" - version = m.group(2).strip() - - return Constraint(version, op) + return Constraint(version.strip(), op) raise ValueError(f"Could not parse version constraint: {constraint}") diff --git a/src/poetry/core/semver/helpers.py b/src/poetry/core/semver/helpers.py index 9022add94..40c17dcf6 100644 --- a/src/poetry/core/semver/helpers.py +++ b/src/poetry/core/semver/helpers.py @@ -125,14 +125,18 @@ def parse_single_constraint(constraint: str) -> VersionConstraint: m = BASIC_CONSTRAINT.match(constraint) if m: op = m.group(1) - version_string = m.group(2) - - # Technically invalid constraints like `>= 3.*` will appear - # here as `3.`. - # Pip currently supports these and to avoid breaking existing - # users workflows we need to support them as well. To do so, - # we just remove the inconsequential part. - version_string = version_string.rstrip(".") + version_string = ( + f"{constraint.strip()[len(op.strip()):]}" if op else constraint.strip() + ) + + if version_string.endswith(".*"): + # Technically invalid constraints like `>= 3.*` will appear + # here as `3.*`. + # + # Pip currently supports these and to avoid breaking existing + # users workflows we need to support them as well. To do so, + # we just remove the inconsequential part. + version_string = version_string[:-2] if version_string == "dev": version_string = "0.0-dev" diff --git a/tests/semver/test_parse_constraint.py b/tests/semver/test_parse_constraint.py index 5e80626af..e6d776a20 100644 --- a/tests/semver/test_parse_constraint.py +++ b/tests/semver/test_parse_constraint.py @@ -182,6 +182,28 @@ include_min=True, ), ), + ( + "^1.0.0a1.dev0", + VersionRange( + min=Version.from_parts( + 1, 0, 0, pre=ReleaseTag("a", 1), dev=ReleaseTag("dev", 0) + ), + max=Version.from_parts(2, 0, 0), + include_min=True, + ), + ), + ( + "1.0.0a1.dev0", + VersionRange( + min=Version.from_parts( + 1, 0, 0, pre=ReleaseTag("a", 1), dev=ReleaseTag("dev", 0) + ), + max=Version.from_parts( + 1, 0, 0, pre=ReleaseTag("a", 1), dev=ReleaseTag("dev", 0) + ), + include_min=True, + ), + ), ( "~1.0.0a1", VersionRange( @@ -190,6 +212,16 @@ include_min=True, ), ), + ( + "~1.0.0a1.dev0", + VersionRange( + min=Version.from_parts( + 1, 0, 0, pre=ReleaseTag("a", 1), dev=ReleaseTag("dev", 0) + ), + max=Version.from_parts(1, 1, 0), + include_min=True, + ), + ), ( "^0", VersionRange( diff --git a/tests/version/test_requirements.py b/tests/version/test_requirements.py index 556ed842d..1073aeb9c 100644 --- a/tests/version/test_requirements.py +++ b/tests/version/test_requirements.py @@ -47,6 +47,7 @@ def assert_requirement( ("name<3.*", {"name": "name", "constraint": "<3.0"}), ("name>3.5.*", {"name": "name", "constraint": ">3.5"}), ("name==1.0.post1", {"name": "name", "constraint": "==1.0.post1"}), + ("name==1.2.0b1.dev0", {"name": "name", "constraint": "==1.2.0b1.dev0"}), ( "name>=1.2.3;python_version=='2.6'", {