From 070fb7342b2a2b133ef90931b892e54940f9d40b Mon Sep 17 00:00:00 2001 From: David Hotham Date: Sun, 26 Oct 2025 10:26:14 +0000 Subject: [PATCH 1/2] fix poetry #10599 --- src/poetry/core/packages/utils/utils.py | 23 +++++++++-- src/poetry/core/version/pep440/parser.py | 1 - src/poetry/core/version/pep440/version.py | 5 +-- .../version/test_parse_constraint.py | 10 ++--- tests/constraints/version/test_version.py | 38 +++++++++---------- tests/packages/utils/test_utils.py | 2 + 6 files changed, 47 insertions(+), 32 deletions(-) diff --git a/src/poetry/core/packages/utils/utils.py b/src/poetry/core/packages/utils/utils.py index 9312fb4b9..78cf9f70a 100644 --- a/src/poetry/core/packages/utils/utils.py +++ b/src/poetry/core/packages/utils/utils.py @@ -1,5 +1,6 @@ from __future__ import annotations +import dataclasses import functools import re import sys @@ -288,8 +289,15 @@ def create_nested_marker( and not constraint.include_min and version.precision < 3 ): - padding = ".0" * (3 - version.precision) - part = f'python_full_version > "{version}{padding}"' + release = version.release + release = dataclasses.replace( + release, + major=release.major or 0, + minor=release.minor or 0, + patch=release.patch or 0, + ) + version = dataclasses.replace(version, release=release) + part = f'python_full_version > "{version}"' else: part = f'{min_name} {op} "{version.stable}"' @@ -306,8 +314,15 @@ def create_nested_marker( and constraint.include_max and version.precision < 3 ): - padding = ".0" * (3 - version.precision) - part = f'python_full_version <= "{version}{padding}"' + release = version.release + release = dataclasses.replace( + release, + major=release.major or 0, + minor=release.minor or 0, + patch=release.patch or 0, + ) + version = dataclasses.replace(version, release=release) + part = f'python_full_version <= "{version}"' else: part = f'{max_name} {op} "{version.stable}"' diff --git a/src/poetry/core/version/pep440/parser.py b/src/poetry/core/version/pep440/parser.py index f9efeb7b3..2aeed237a 100644 --- a/src/poetry/core/version/pep440/parser.py +++ b/src/poetry/core/version/pep440/parser.py @@ -76,7 +76,6 @@ def parse(cls, value: str, version_class: type[T]) -> T: post=cls._get_postrelease(match), dev=cls._get_devrelease(match), local=cls._get_local(match), - text=value, ) diff --git a/src/poetry/core/version/pep440/version.py b/src/poetry/core/version/pep440/version.py index 653f99e5b..ebee9a7a8 100644 --- a/src/poetry/core/version/pep440/version.py +++ b/src/poetry/core/version/pep440/version.py @@ -57,7 +57,7 @@ class PEP440Version: post: ReleaseTag | None = dataclasses.field(default=None, compare=False) dev: ReleaseTag | None = dataclasses.field(default=None, compare=False) local: LocalSegmentType = dataclasses.field(default=None, compare=False) - text: str = dataclasses.field(default="", compare=False) + text: str = dataclasses.field(init=False, compare=False) _compare_key: tuple[ int, Release, ReleaseTag, ReleaseTag, ReleaseTag, tuple[int | str, ...] ] = dataclasses.field(init=False, compare=True) @@ -69,9 +69,8 @@ def __post_init__(self) -> None: if isinstance(self.release, tuple): object.__setattr__(self, "release", Release(*self.release)) - # we do this here to handle both None and tomlkit string values object.__setattr__( - self, "text", self.to_string() if not self.text else str(self.text) + self, "text", self.to_string() ) object.__setattr__(self, "_compare_key", self._make_compare_key()) diff --git a/tests/constraints/version/test_parse_constraint.py b/tests/constraints/version/test_parse_constraint.py index a5af742e3..c3a9ffc22 100644 --- a/tests/constraints/version/test_parse_constraint.py +++ b/tests/constraints/version/test_parse_constraint.py @@ -445,15 +445,15 @@ def test_parse_constraints_with_trailing_comma( ("^1", ">=1,<2"), ("^1.0", ">=1.0,<2.0"), ("^1.0.0", ">=1.0.0,<2.0.0"), - ("^1.0.0-alpha.1", ">=1.0.0-alpha.1,<2.0.0"), + ("^1.0.0-alpha.1", ">=1.0.0a1,<2.0.0"), ("^0", ">=0,<1"), ("^0.1", ">=0.1,<0.2"), ("^0.0.2", ">=0.0.2,<0.0.3"), ("^0.1.2", ">=0.1.2,<0.2.0"), - ("^0-alpha.1", ">=0-alpha.1,<1"), - ("^0.1-alpha.1", ">=0.1-alpha.1,<0.2"), - ("^0.0.2-alpha.1", ">=0.0.2-alpha.1,<0.0.3"), - ("^0.1.2-alpha.1", ">=0.1.2-alpha.1,<0.2.0"), + ("^0-alpha.1", ">=0a1,<1"), + ("^0.1-alpha.1", ">=0.1a1,<0.2"), + ("^0.0.2-alpha.1", ">=0.0.2a1,<0.0.3"), + ("^0.1.2-alpha.1", ">=0.1.2a1,<0.2.0"), ("~1", ">=1,<2"), ("~1.0", ">=1.0,<1.1"), ("~1.0.0", ">=1.0.0,<1.1.0"), diff --git a/tests/constraints/version/test_version.py b/tests/constraints/version/test_version.py index 69b8c373c..bd2e14f3e 100644 --- a/tests/constraints/version/test_version.py +++ b/tests/constraints/version/test_version.py @@ -16,31 +16,31 @@ @pytest.mark.parametrize( - "text,version", + "text,version,normalized", [ - ("1.0.0", Version.from_parts(1, 0, 0)), - ("1", Version.from_parts(1, 0, 0)), - ("1.0", Version.from_parts(1, 0, 0)), - ("1b1", Version.from_parts(1, 0, 0, pre=ReleaseTag("beta", 1))), - ("1.0b1", Version.from_parts(1, 0, 0, pre=ReleaseTag("beta", 1))), - ("1.0.0b1", Version.from_parts(1, 0, 0, pre=ReleaseTag("beta", 1))), - ("1.0.0-b1", Version.from_parts(1, 0, 0, pre=ReleaseTag("beta", 1))), - ("1.0.0-beta.1", Version.from_parts(1, 0, 0, pre=ReleaseTag("beta", 1))), - ("1.0.0+1", Version.from_parts(1, 0, 0, local=1)), - ("1.0.0-1", Version.from_parts(1, 0, 0, post=ReleaseTag("post", 1))), - ("1.0.0.0", Version.from_parts(1, 0, 0, extra=0)), - ("1.0.0-post", Version.from_parts(1, 0, 0, post=ReleaseTag("post"))), - ("1.0.0-post1", Version.from_parts(1, 0, 0, post=ReleaseTag("post", 1))), - ("0.6c", Version.from_parts(0, 6, 0, pre=ReleaseTag("rc", 0))), - ("0.6pre", Version.from_parts(0, 6, 0, pre=ReleaseTag("preview", 0))), - ("1!2.3.4", Version.from_parts(2, 3, 4, epoch=1)), + ("1.0.0", Version.from_parts(1, 0, 0), "1.0.0"), + ("1", Version.from_parts(1, 0, 0), "1"), + ("1.0", Version.from_parts(1, 0, 0), "1.0"), + ("1b1", Version.from_parts(1, 0, 0, pre=ReleaseTag("beta", 1)), "1b1"), + ("1.0b1", Version.from_parts(1, 0, 0, pre=ReleaseTag("beta", 1)), "1.0b1"), + ("1.0.0b1", Version.from_parts(1, 0, 0, pre=ReleaseTag("beta", 1)), "1.0.0b1"), + ("1.0.0-b1", Version.from_parts(1, 0, 0, pre=ReleaseTag("beta", 1)), "1.0.0b1"), + ("1.0.0-beta.1", Version.from_parts(1, 0, 0, pre=ReleaseTag("beta", 1)), "1.0.0b1"), + ("1.0.0+1", Version.from_parts(1, 0, 0, local=1), "1.0.0+1"), + ("1.0.0-1", Version.from_parts(1, 0, 0, post=ReleaseTag("post", 1)), "1.0.0.post1"), + ("1.0.0.0", Version.from_parts(1, 0, 0, extra=0), "1.0.0.0"), + ("1.0.0-post", Version.from_parts(1, 0, 0, post=ReleaseTag("post")), "1.0.0.post0"), + ("1.0.0-post1", Version.from_parts(1, 0, 0, post=ReleaseTag("post", 1)), "1.0.0.post1"), + ("0.6c", Version.from_parts(0, 6, 0, pre=ReleaseTag("rc", 0)), "0.6rc0"), + ("0.6pre", Version.from_parts(0, 6, 0, pre=ReleaseTag("preview", 0)), "0.6rc0"), + ("1!2.3.4", Version.from_parts(2, 3, 4, epoch=1), "1!2.3.4"), ], ) -def test_parse_valid(text: str, version: Version) -> None: +def test_parse_valid(text: str, version: Version, normalized: str) -> None: parsed = Version.parse(text) assert parsed == version - assert parsed.text == text + assert parsed.text == normalized @pytest.mark.parametrize("value", [None, "example"]) diff --git a/tests/packages/utils/test_utils.py b/tests/packages/utils/test_utils.py index f1cbd2317..0215a5473 100644 --- a/tests/packages/utils/test_utils.py +++ b/tests/packages/utils/test_utils.py @@ -124,6 +124,7 @@ def test_create_nested_marker_base_constraint(constraint: str, expected: str) -> (">3.9", 'python_full_version > "3.9.0"'), (">3.9.0", 'python_full_version > "3.9.0"'), (">3.9.1", 'python_full_version > "3.9.1"'), + (">3.14rc1", 'python_full_version > "3.14.0rc1"'), # max ("<3", 'python_version < "3"'), ("<3.9", 'python_version < "3.9"'), @@ -133,6 +134,7 @@ def test_create_nested_marker_base_constraint(constraint: str, expected: str) -> ("<=3.9", 'python_full_version <= "3.9.0"'), ("<=3.9.0", 'python_full_version <= "3.9.0"'), ("<=3.9.1", 'python_full_version <= "3.9.1"'), + ("<=3.14rc1", 'python_full_version <= "3.14.0rc1"'), # min and max (">=3.7, <3.9", 'python_version >= "3.7" and python_version < "3.9"'), (">=3.7, <=3.9", 'python_version >= "3.7" and python_full_version <= "3.9.0"'), From 3df12eaf8b04e20de55711acb25f4e48cd3004dc Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Sun, 26 Oct 2025 10:49:38 +0000 Subject: [PATCH 2/2] [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci --- src/poetry/core/version/pep440/version.py | 4 +--- tests/constraints/version/test_version.py | 24 +++++++++++++++++++---- 2 files changed, 21 insertions(+), 7 deletions(-) diff --git a/src/poetry/core/version/pep440/version.py b/src/poetry/core/version/pep440/version.py index ebee9a7a8..3c4b2ae06 100644 --- a/src/poetry/core/version/pep440/version.py +++ b/src/poetry/core/version/pep440/version.py @@ -69,9 +69,7 @@ def __post_init__(self) -> None: if isinstance(self.release, tuple): object.__setattr__(self, "release", Release(*self.release)) - object.__setattr__( - self, "text", self.to_string() - ) + object.__setattr__(self, "text", self.to_string()) object.__setattr__(self, "_compare_key", self._make_compare_key()) diff --git a/tests/constraints/version/test_version.py b/tests/constraints/version/test_version.py index bd2e14f3e..c11eff12f 100644 --- a/tests/constraints/version/test_version.py +++ b/tests/constraints/version/test_version.py @@ -25,12 +25,28 @@ ("1.0b1", Version.from_parts(1, 0, 0, pre=ReleaseTag("beta", 1)), "1.0b1"), ("1.0.0b1", Version.from_parts(1, 0, 0, pre=ReleaseTag("beta", 1)), "1.0.0b1"), ("1.0.0-b1", Version.from_parts(1, 0, 0, pre=ReleaseTag("beta", 1)), "1.0.0b1"), - ("1.0.0-beta.1", Version.from_parts(1, 0, 0, pre=ReleaseTag("beta", 1)), "1.0.0b1"), + ( + "1.0.0-beta.1", + Version.from_parts(1, 0, 0, pre=ReleaseTag("beta", 1)), + "1.0.0b1", + ), ("1.0.0+1", Version.from_parts(1, 0, 0, local=1), "1.0.0+1"), - ("1.0.0-1", Version.from_parts(1, 0, 0, post=ReleaseTag("post", 1)), "1.0.0.post1"), + ( + "1.0.0-1", + Version.from_parts(1, 0, 0, post=ReleaseTag("post", 1)), + "1.0.0.post1", + ), ("1.0.0.0", Version.from_parts(1, 0, 0, extra=0), "1.0.0.0"), - ("1.0.0-post", Version.from_parts(1, 0, 0, post=ReleaseTag("post")), "1.0.0.post0"), - ("1.0.0-post1", Version.from_parts(1, 0, 0, post=ReleaseTag("post", 1)), "1.0.0.post1"), + ( + "1.0.0-post", + Version.from_parts(1, 0, 0, post=ReleaseTag("post")), + "1.0.0.post0", + ), + ( + "1.0.0-post1", + Version.from_parts(1, 0, 0, post=ReleaseTag("post", 1)), + "1.0.0.post1", + ), ("0.6c", Version.from_parts(0, 6, 0, pre=ReleaseTag("rc", 0)), "0.6rc0"), ("0.6pre", Version.from_parts(0, 6, 0, pre=ReleaseTag("preview", 0)), "0.6rc0"), ("1!2.3.4", Version.from_parts(2, 3, 4, epoch=1), "1!2.3.4"),