diff --git a/src/poetry/core/constraints/version/parser.py b/src/poetry/core/constraints/version/parser.py index 3e39d9968..3deae0f9a 100644 --- a/src/poetry/core/constraints/version/parser.py +++ b/src/poetry/core/constraints/version/parser.py @@ -180,6 +180,8 @@ def parse_single_constraint( if op == ">": return VersionRange(min=version) if op == ">=": + if is_marker_constraint: + version = version.stable return VersionRange(min=version, include_min=True) if m.group("wildcard") is not None: diff --git a/src/poetry/core/packages/utils/utils.py b/src/poetry/core/packages/utils/utils.py index 708746d08..c9d5bea2d 100644 --- a/src/poetry/core/packages/utils/utils.py +++ b/src/poetry/core/packages/utils/utils.py @@ -336,12 +336,15 @@ def normalize_python_version_markers( # NOSONAR for op, version in or_: # Expand python version if op == "==" and "*" not in version and version.count(".") < 2: - version = "~" + version + version += ".*" op = "" elif op == "!=" and "*" not in version and version.count(".") < 2: version += ".*" + elif op == ">=" and version.count(".") < 2: + version += ".dev0" + elif op in ("<=", ">"): # Make adjustments on encountering versions with less than full # precision. diff --git a/tests/constraints/version/test_parse_constraint.py b/tests/constraints/version/test_parse_constraint.py index a5af742e3..95c53f501 100644 --- a/tests/constraints/version/test_parse_constraint.py +++ b/tests/constraints/version/test_parse_constraint.py @@ -22,6 +22,26 @@ ("<1.2.3", VersionRange(max=Version.from_parts(1, 2, 3))), ("<=1.2.3", VersionRange(max=Version.from_parts(1, 2, 3), include_max=True)), (">=1.2.3", VersionRange(min=Version.from_parts(1, 2, 3), include_min=True)), + ( + ">1.2.dev0", + VersionRange(min=Version.from_parts(1, 2, dev=ReleaseTag("dev", 0))), + ), + ( + "<1.2.dev0", + VersionRange(max=Version.from_parts(1, 2, dev=ReleaseTag("dev", 0))), + ), + ( + ">=1.2.dev0", + VersionRange( + min=Version.from_parts(1, 2, dev=ReleaseTag("dev", 0)), include_min=True + ), + ), + ( + "<=1.2.dev0", + VersionRange( + max=Version.from_parts(1, 2, dev=ReleaseTag("dev", 0)), include_max=True + ), + ), ("=1.2.3", Version.from_parts(1, 2, 3)), ("1.2.3", Version.from_parts(1, 2, 3)), ("1!2.3.4", Version.from_parts(2, 3, 4, epoch=1)), @@ -584,6 +604,25 @@ def test_parse_constraint_with_white_space_padding( assert parse_constraint(constraint) == expected +@pytest.mark.parametrize( + ("constraint", "expected"), + [ + (">=3.14.dev0", VersionRange(min=Version.from_parts(3, 14), include_min=True)), + ( + "3.14.*", + VersionRange( + Version.from_parts(3, 14), Version.from_parts(3, 15), include_min=True + ), + ), + ], +) +def test_parse_marker_constraint_special_cases( + constraint: str, expected: Version | VersionRange +) -> None: + assert parse_marker_version_constraint(constraint) == expected + assert parse_constraint(constraint) != expected + + def test_parse_marker_constraint_does_not_allow_invalid_version() -> None: with pytest.raises(ParseConstraintError): parse_marker_version_constraint("4.9.253-tegra") diff --git a/tests/packages/test_dependency.py b/tests/packages/test_dependency.py index 768e614eb..1442a4d12 100644 --- a/tests/packages/test_dependency.py +++ b/tests/packages/test_dependency.py @@ -363,10 +363,10 @@ def test_with_groups() -> None: @pytest.mark.parametrize( "marker, expected", [ - ('python_version >= "3.6" and python_version < "4.0"', ">=3.6,<4.0"), + ('python_version >= "3.6" and python_version < "4.0"', ">=3.6.dev0,<4.0"), ('sys_platform == "linux"', "*"), ('python_version >= "3.9" or sys_platform == "linux"', "*"), - ('python_version >= "3.9" and sys_platform == "linux"', ">=3.9"), + ('python_version >= "3.9" and sys_platform == "linux"', ">=3.9.dev0"), ], ) def test_marker_properly_sets_python_constraint(marker: str, expected: str) -> None: @@ -386,7 +386,7 @@ def test_marker_properly_unsets_python_constraint() -> None: dependency = Dependency("foo", "^1.2.3") dependency.marker = 'python_version >= "3.6"' - assert str(dependency.python_constraint) == ">=3.6" + assert str(dependency.python_constraint) == ">=3.6.dev0" dependency.marker = "*" assert str(dependency.python_constraint) == "*" diff --git a/tests/packages/test_main.py b/tests/packages/test_main.py index b9ae56d31..13e2cabc6 100644 --- a/tests/packages/test_main.py +++ b/tests/packages/test_main.py @@ -73,7 +73,7 @@ def test_dependency_from_pep_508_with_python_version() -> None: assert dep.name == "requests" assert str(dep.constraint) == "2.18.0" assert dep.extras == frozenset() - assert dep.python_versions == ">=2.6 <2.8" + assert dep.python_versions == ">=2.6.dev0 <2.8" assert str(dep.marker) == 'python_version >= "2.6" and python_version < "2.8"' @@ -84,7 +84,7 @@ def test_dependency_from_pep_508_with_single_python_version() -> None: assert dep.name == "requests" assert str(dep.constraint) == "2.18.0" assert dep.extras == frozenset() - assert dep.python_versions == "~2.7" + assert dep.python_versions == "2.7.*" assert str(dep.marker) == 'python_version == "2.7"' @@ -111,7 +111,7 @@ def test_dependency_from_pep_508_complex() -> None: assert dep.name == "requests" assert str(dep.constraint) == "2.18.0" assert dep.in_extras == ["foo"] - assert dep.python_versions == ">=2.7 !=3.2.*" + assert dep.python_versions == ">=2.7.dev0 !=3.2.*" assert ( str(dep.marker) == 'python_version >= "2.7" and python_version != "3.2" ' 'and (sys_platform == "win32" or sys_platform == "darwin") ' @@ -176,7 +176,7 @@ def test_dependency_from_pep_508_with_python_version_union_of_multi() -> None: assert dep.name == "requests" assert str(dep.constraint) == "2.18.0" assert dep.extras == frozenset() - assert dep.python_versions == "~2.7 || ~3.4" + assert dep.python_versions == "2.7.* || 3.4.*" assert str(dep.marker) == 'python_version == "2.7" or python_version == "3.4"' @@ -291,7 +291,7 @@ def test_dependency_from_pep_508_with_python_full_version() -> None: assert dep.name == "requests" assert str(dep.constraint) == "2.18.0" assert dep.extras == frozenset() - assert dep.python_versions == "~2.7 || >=3.4.0 <3.5.4" + assert dep.python_versions == "2.7.* || >=3.4.0 <3.5.4" assert ( str(dep.marker) == 'python_version == "2.7" ' 'or python_full_version >= "3.4.0" and python_full_version < "3.5.4"' diff --git a/tests/packages/utils/test_utils.py b/tests/packages/utils/test_utils.py index f1cbd2317..20cda2fea 100644 --- a/tests/packages/utils/test_utils.py +++ b/tests/packages/utils/test_utils.py @@ -172,7 +172,7 @@ def test_create_nested_marker_version_constraint( ["marker", "constraint"], [ # == - ('python_version == "3.6"', "~3.6"), + ('python_version == "3.6"', "3.6.*"), ('python_version == "3.6.*"', "==3.6.*"), ('python_version == "3.6.* "', "==3.6.*"), # != @@ -183,32 +183,32 @@ def test_create_nested_marker_version_constraint( ('python_version < "3"', "<3"), ('python_version <= "3"', "<3"), ('python_version > "3"', ">=3"), - ('python_version >= "3"', ">=3"), + ('python_version >= "3"', ">=3.dev0"), # <, <=, >, >= precision 2 ('python_version < "3.6"', "<3.6"), ('python_version <= "3.6"', "<3.7"), ('python_version > "3.6"', ">=3.7"), - ('python_version >= "3.6"', ">=3.6"), + ('python_version >= "3.6"', ">=3.6.dev0"), # in, not in ('python_version in "2.7, 3.6"', ">=2.7.0,<2.8.0 || >=3.6.0,<3.7.0"), ('python_version in "2.7, 3.6.2"', ">=2.7.0,<2.8.0 || 3.6.2"), ('python_version not in "2.7, 3.6"', "<2.7.0 || >=2.8.0,<3.6.0 || >=3.7.0"), ('python_version not in "2.7, 3.6.2"', "<2.7.0 || >=2.8.0,<3.6.2 || >3.6.2"), # and - ('python_version >= "3.6" and python_full_version < "4.0"', ">=3.6, <4.0"), + ('python_version >= "3.6" and python_full_version < "4.0"', ">=3.6.dev0, <4.0"), ( 'python_full_version >= "3.6.1" and python_full_version < "4.0.0"', ">=3.6.1, <4.0.0", ), # or - ('python_version < "3.6" or python_version >= "3.9"', "<3.6 || >=3.9"), + ('python_version < "3.6" or python_version >= "3.9"', "<3.6 || >=3.9.dev0"), # and or ( ( 'python_version >= "3.7" and python_version < "3.8" or python_version' ' >= "3.9" and python_version < "3.10"' ), - ">=3.7,<3.8 || >=3.9,<3.10", + "==3.7.* || ==3.9.*", ), ( ( @@ -224,17 +224,17 @@ def test_create_nested_marker_version_constraint( # no relevant python_version ('python_version >= "3.9" or sys_platform == "linux"', "*"), # relevant python_version - ('python_version >= "3.9" and sys_platform == "linux"', ">=3.9"), + ('python_version >= "3.9" and sys_platform == "linux"', ">=3.9.dev0"), # exclude specific version ( 'python_version >= "3.5" and python_full_version != "3.7.6"', - ">=3.5,<3.7.6 || >3.7.6", + ">=3.5.dev0,<3.7.6 || >3.7.6", ), # Full exact version - ( - 'python_full_version == "3.6.1"', - "3.6.1", - ), + ('python_full_version == "3.6.0"', "3.6.0"), + ('python_full_version == "3.6.1"', "3.6.1"), + ('python_full_version >= "3.6.0"', ">=3.6.0"), + ('python_full_version >= "3.6.1"', ">=3.6.1"), ], ) def test_get_python_constraint_from_marker(marker: str, constraint: str) -> None: diff --git a/tests/test_factory.py b/tests/test_factory.py index af1c94aae..4ceedfbf9 100644 --- a/tests/test_factory.py +++ b/tests/test_factory.py @@ -239,7 +239,7 @@ def test_create_poetry(project: str) -> None: pathlib2 = dependencies["pathlib2"] assert pathlib2.pretty_constraint == (">=2.2,<3.0" if new_format else "^2.2") - assert pathlib2.python_versions in {"~2.7", ">=2.7 <2.8"} + assert pathlib2.python_versions == "2.7.*" assert not pathlib2.is_optional() demo = dependencies["demo"] @@ -1091,9 +1091,9 @@ def test_create_poetry_with_markers_and_extras() -> None: @pytest.mark.parametrize( "constraint, exp_python, exp_marker", [ - ({"python": "3.7"}, "~3.7", 'python_version == "3.7"'), + ({"python": "3.7"}, "3.7.*", 'python_version == "3.7"'), ({"platform": "linux"}, "*", 'sys_platform == "linux"'), - ({"markers": 'python_version == "3.7"'}, "~3.7", 'python_version == "3.7"'), + ({"markers": 'python_version == "3.7"'}, "3.7.*", 'python_version == "3.7"'), ( {"markers": 'platform_machine == "x86_64"'}, "*", @@ -1101,7 +1101,7 @@ def test_create_poetry_with_markers_and_extras() -> None: ), ( {"python": "3.7", "markers": 'platform_machine == "x86_64"'}, - "~3.7", + "3.7.*", 'platform_machine == "x86_64" and python_version == "3.7"', ), ( @@ -1115,7 +1115,7 @@ def test_create_poetry_with_markers_and_extras() -> None: "platform": "linux", "markers": 'platform_machine == "x86_64"', }, - "~3.7", + "3.7.*", ( 'platform_machine == "x86_64" and python_version == "3.7" and' ' sys_platform == "linux"' @@ -1123,7 +1123,7 @@ def test_create_poetry_with_markers_and_extras() -> None: ), ( {"python": ">=3.7", "markers": 'python_version < "4.0"'}, - "<4.0 >=3.7", + "<4.0 >=3.7.dev0", 'python_version < "4.0" and python_version >= "3.7"', ), (