Script 'mail_helper' called by obssrc Hello community, here is the log from the commit of package python-poetry-core for openSUSE:Factory checked in at 2026-03-31 15:46:30 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Comparing /work/SRC/openSUSE:Factory/python-poetry-core (Old) and /work/SRC/openSUSE:Factory/.python-poetry-core.new.1999 (New) ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "python-poetry-core" Tue Mar 31 15:46:30 2026 rev:30 rq:1343766 version:2.3.2 Changes: -------- --- /work/SRC/openSUSE:Factory/python-poetry-core/python-poetry-core.changes 2026-02-12 17:26:37.249391180 +0100 +++ /work/SRC/openSUSE:Factory/.python-poetry-core.new.1999/python-poetry-core.changes 2026-03-31 15:46:32.285047181 +0200 @@ -1,0 +2,34 @@ +Mon Mar 30 20:38:25 UTC 2026 - Dirk Müller <[email protected]> + +- update to 2.3.2: + * Update list of supported licenses (#917). + * Fix an issue where `platform_release` could not be parsed on + Debian Trixie (#930). + * Fix an issue where using `project.readme.text` in the + `pyproject.toml` file resulted in broken metadata (#914). + * Fix an issue where dependency groups were considered equal + when their resolved dependencies were equal, even if the + groups themselves were not (#919). + * Fix an issue where removing a dependency from a group that + included another group resulted in other dependencies being + added to the included group (#922). + * Fix an issue where PEP 735 `include-group` entries were lost + when `[tool.poetry.group]` also defined `include-groups` for + the same group (#924). + * Fix an issue where the union of `<value> not in <marker>` + constraints was wrongly treated as always satisfied (#925). + * Fix an issue where a post release with a local version + identifier was wrongly allowed by a `>` version constraint + (#921). + * Fix an issue where a version with the local version + identifier `0` was treated as equal to the corresponding + public version (#920). + * Fix an issue where a `!= <version>` constraint wrongly + disallowed pre releases and post releases of the specified + version (#929). + * Fix an issue where `in` and `not in` constraints were wrongly + not allowed by specific compound constraints (#927). + * Fix an issue where data entries in generated `setup.py` files + were duplicated (#923). + +------------------------------------------------------------------- Old: ---- poetry-core-2.3.1-gh.tar.gz New: ---- poetry-core-2.3.2-gh.tar.gz ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Other differences: ------------------ ++++++ python-poetry-core.spec ++++++ --- /var/tmp/diff_new_pack.17wkCX/_old 2026-03-31 15:46:32.857071104 +0200 +++ /var/tmp/diff_new_pack.17wkCX/_new 2026-03-31 15:46:32.861071272 +0200 @@ -18,7 +18,7 @@ %{?sle15_python_module_pythons} Name: python-poetry-core -Version: 2.3.1 +Version: 2.3.2 Release: 0 Summary: Poetry PEP 517 Build Backend License: Apache-2.0 AND BSD-2-Clause AND MIT AND Python-2.0 @@ -35,6 +35,7 @@ BuildRequires: %{python_module build >= 0.10.0} BuildRequires: %{python_module pytest >= 7.1.2} BuildRequires: %{python_module pytest-mock >= 3.10} +BuildRequires: %{python_module setuptools >= 60} BuildRequires: %{python_module tomli-w >= 1.0.0} BuildRequires: %{python_module trove-classifiers >= 2022.5.19} BuildRequires: %{python_module virtualenv >= 20.21} ++++++ poetry-core-2.3.1-gh.tar.gz -> poetry-core-2.3.2-gh.tar.gz ++++++ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/poetry-core-2.3.1/CHANGELOG.md new/poetry-core-2.3.2/CHANGELOG.md --- old/poetry-core-2.3.1/CHANGELOG.md 2026-02-01 14:48:13.000000000 +0100 +++ new/poetry-core-2.3.2/CHANGELOG.md 2026-03-29 09:38:03.000000000 +0200 @@ -1,6 +1,27 @@ # Change Log +## [2.3.2] - 2026-03-29 + +### Changed + +- Update list of supported licenses ([#917](https://github.com/python-poetry/poetry-core/pull/917)). + +### Fixed + +- Fix an issue where `platform_release` could not be parsed on Debian Trixie ([#930](https://github.com/python-poetry/poetry-core/pull/930)). +- Fix an issue where using `project.readme.text` in the `pyproject.toml` file resulted in broken metadata ([#914](https://github.com/python-poetry/poetry-core/pull/914)). +- Fix an issue where dependency groups were considered equal when their resolved dependencies were equal, even if the groups themselves were not ([#919](https://github.com/python-poetry/poetry-core/pull/919)). +- Fix an issue where removing a dependency from a group that included another group resulted in other dependencies being added to the included group ([#922](https://github.com/python-poetry/poetry-core/pull/922)). +- Fix an issue where PEP 735 `include-group` entries were lost when `[tool.poetry.group]` also defined `include-groups` for the same group ([#924](https://github.com/python-poetry/poetry-core/pull/924)). +- Fix an issue where the union of `<value> not in <marker>` constraints was wrongly treated as always satisfied ([#925](https://github.com/python-poetry/poetry-core/pull/925)). +- Fix an issue where a post release with a local version identifier was wrongly allowed by a `>` version constraint ([#921](https://github.com/python-poetry/poetry-core/pull/921)). +- Fix an issue where a version with the local version identifier `0` was treated as equal to the corresponding public version ([#920](https://github.com/python-poetry/poetry-core/pull/920)). +- Fix an issue where a `!= <version>` constraint wrongly disallowed pre releases and post releases of the specified version ([#929](https://github.com/python-poetry/poetry-core/pull/929)). +- Fix an issue where `in` and `not in` constraints were wrongly not allowed by specific compound constraints ([#927](https://github.com/python-poetry/poetry-core/pull/927)). +- Fix an issue where data entries in generated `setup.py` files were duplicated ([#923](https://github.com/python-poetry/poetry-core/pull/923)). + + ## [2.3.1] - 2026-02-01 ### Changed @@ -843,7 +864,8 @@ - Fixed support for stub-only packages ([#28](https://github.com/python-poetry/core/pull/28)). -[Unreleased]: https://github.com/python-poetry/poetry-core/compare/2.3.1...main +[Unreleased]: https://github.com/python-poetry/poetry-core/compare/2.3.2...main +[2.3.2]: https://github.com/python-poetry/poetry-core/releases/tag/2.3.2 [2.3.1]: https://github.com/python-poetry/poetry-core/releases/tag/2.3.1 [2.3.0]: https://github.com/python-poetry/poetry-core/releases/tag/2.3.0 [2.2.1]: https://github.com/python-poetry/poetry-core/releases/tag/2.2.1 diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/poetry-core-2.3.1/pyproject.toml new/poetry-core-2.3.2/pyproject.toml --- old/poetry-core-2.3.1/pyproject.toml 2026-02-01 14:48:13.000000000 +0100 +++ new/poetry-core-2.3.2/pyproject.toml 2026-03-29 09:38:03.000000000 +0200 @@ -1,6 +1,6 @@ [project] name = "poetry-core" -version = "2.3.1" +version = "2.3.2" description = "Poetry PEP 517 Build Backend" authors = [ { name = "Sébastien Eustace", email = "[email protected]" } diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/poetry-core-2.3.1/src/poetry/core/__init__.py new/poetry-core-2.3.2/src/poetry/core/__init__.py --- old/poetry-core-2.3.1/src/poetry/core/__init__.py 2026-02-01 14:48:13.000000000 +0100 +++ new/poetry-core-2.3.2/src/poetry/core/__init__.py 2026-03-29 09:38:03.000000000 +0200 @@ -7,7 +7,7 @@ # this cannot presently be replaced with importlib.metadata.version as when building # itself, poetry-core is not available as an installed distribution. -__version__ = "2.3.1" +__version__ = "2.3.2" __vendor_site__ = (Path(__file__).parent / "_vendor").as_posix() diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/poetry-core-2.3.1/src/poetry/core/constraints/generic/constraint.py new/poetry-core-2.3.2/src/poetry/core/constraints/generic/constraint.py --- old/poetry-core-2.3.1/src/poetry/core/constraints/generic/constraint.py 2026-02-01 14:48:13.000000000 +0100 +++ new/poetry-core-2.3.2/src/poetry/core/constraints/generic/constraint.py 2026-03-29 09:38:03.000000000 +0200 @@ -115,9 +115,6 @@ if other.operator == "==": return self.allows(other) - if other.operator == "!=" and self._operator == "==": - return self._value != other.value - if other.operator == "not in" and self._operator == "in": return other.value not in self.value @@ -126,13 +123,11 @@ return True - elif isinstance(other, MultiConstraint): - return self._operator == "!=" + if isinstance(other, MultiConstraint): + return all(self.allows_any(c) for c in other.constraints) - elif isinstance(other, UnionConstraint): - return self._operator == "!=" and any( - self.allows_any(c) for c in other.constraints - ) + if isinstance(other, UnionConstraint): + return any(self.allows_any(c) for c in other.constraints) return other.is_any() @@ -180,7 +175,7 @@ ops = {self.operator, other.operator} if ( - (ops in ({"!="}, {"not in"})) + ops == {"!="} or ( ( ops in ({"in", "!="}, {"in", "not in"}) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/poetry-core-2.3.1/src/poetry/core/constraints/version/patterns.py new/poetry-core-2.3.2/src/poetry/core/constraints/version/patterns.py --- old/poetry-core-2.3.1/src/poetry/core/constraints/version/patterns.py 2026-02-01 14:48:13.000000000 +0100 +++ new/poetry-core-2.3.2/src/poetry/core/constraints/version/patterns.py 2026-03-29 09:38:03.000000000 +0200 @@ -27,11 +27,12 @@ re.VERBOSE | re.IGNORECASE, ) +# pattern for non Python versions such as OS versions in `platform_release` RELEASE_PATTERN = r""" (?P<release>[0-9]+(?:\.[0-9]+)*) (?:(\+|-)?(?P<build> - [0-9a-zA-Z-]+ - (?:\.[0-9a-zA-Z-]+)* + [0-9a-zA-Z+-]+ + (?:\.[0-9a-zA-Z+-]+)* ))? """ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/poetry-core-2.3.1/src/poetry/core/constraints/version/version_range.py new/poetry-core-2.3.2/src/poetry/core/constraints/version/version_range.py --- old/poetry-core-2.3.1/src/poetry/core/constraints/version/version_range.py 2026-02-01 14:48:13.000000000 +0100 +++ new/poetry-core-2.3.2/src/poetry/core/constraints/version/version_range.py 2026-03-29 09:38:03.000000000 +0200 @@ -80,7 +80,7 @@ # a local version of the specified version. # https://peps.python.org/pep-0440/#exclusive-ordered-comparison # e.g. "2.0+local.version" does not match ">2" - _other = other.without_local() + _other = _other.without_local() if _other < _this: return False diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/poetry-core-2.3.1/src/poetry/core/constraints/version/version_union.py new/poetry-core-2.3.2/src/poetry/core/constraints/version/version_union.py --- old/poetry-core-2.3.1/src/poetry/core/constraints/version/version_union.py 2026-02-01 14:48:13.000000000 +0100 +++ new/poetry-core-2.3.2/src/poetry/core/constraints/version/version_union.py 2026-03-29 09:38:03.000000000 +0200 @@ -100,14 +100,7 @@ def allows(self, version: Version) -> bool: if self.excludes_single_version: - # when excluded version is local, special handling is required - # to ensure that a constraint (!=2.0+deadbeef) will allow the - # provided version (2.0) - - excluded = self._excluded_single_version - - if excluded.is_local(): - return excluded != version + return not self._excluded_single_version.allows(version) return any(constraint.allows(version) for constraint in self._ranges) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/poetry-core-2.3.1/src/poetry/core/factory.py new/poetry-core-2.3.2/src/poetry/core/factory.py --- old/poetry-core-2.3.1/src/poetry/core/factory.py 2026-02-01 14:48:13.000000000 +0100 +++ new/poetry-core-2.3.2/src/poetry/core/factory.py 2026-03-29 09:38:03.000000000 +0200 @@ -312,7 +312,7 @@ package.readmes = (root / readme["file"],) package.readme_content_type = readme["content-type"] elif "text" in readme: - package.readme_content = root / readme["text"] + package.readme_content = readme["text"] package.readme_content_type = readme["content-type"] elif custom_readme := tool_poetry.get("readme"): custom_readmes = ( @@ -804,9 +804,9 @@ normalized_group_name = canonicalize_name(group_name) original_names[normalized_group_name].add(group_name) if include_groups := group_config.get("include-groups", []): - group_includes[normalized_group_name] = [ + group_includes.setdefault(normalized_group_name, []).extend( canonicalize_name(name) for name in include_groups - ] + ) for normed_name, names in original_names.items(): if len(names) > 1: diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/poetry-core-2.3.1/src/poetry/core/masonry/builders/sdist.py new/poetry-core-2.3.2/src/poetry/core/masonry/builders/sdist.py --- old/poetry-core-2.3.1/src/poetry/core/masonry/builders/sdist.py 2026-02-01 14:48:13.000000000 +0100 +++ new/poetry-core-2.3.2/src/poetry/core/masonry/builders/sdist.py 2026-03-29 09:38:03.000000000 +0200 @@ -273,7 +273,7 @@ # This is just a shortcut. It will be ignored later anyway. continue - from_top_level = os.path.relpath(path, base) + from_top_level = Path(os.path.relpath(path, base)).as_posix() if from_top_level == ".": continue @@ -304,11 +304,7 @@ if len(data) == len(data_elements): pkg_data[pkg].append(pjoin(from_nearest_pkg, "*")) else: - for d in data: - if d.is_dir(): - continue - - pkg_data[pkg] += [pjoin(from_nearest_pkg, d.name) for d in data] + pkg_data[pkg] += [pjoin(from_nearest_pkg, d.name) for d in data] # Sort values in pkg_data pkg_data = {k: sorted(v) for (k, v) in pkg_data.items() if v} diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/poetry-core-2.3.1/src/poetry/core/packages/dependency_group.py new/poetry-core-2.3.2/src/poetry/core/packages/dependency_group.py --- old/poetry-core-2.3.1/src/poetry/core/packages/dependency_group.py 2026-02-01 14:48:13.000000000 +0100 +++ new/poetry-core-2.3.2/src/poetry/core/packages/dependency_group.py 2026-03-29 09:38:03.000000000 +0200 @@ -140,7 +140,7 @@ name = canonicalize_name(name) dependencies = [] - for dependency in self.dependencies: + for dependency in self._dependencies: if dependency.name == name: continue dependencies.append(dependency) @@ -169,8 +169,9 @@ return ( self._name == other.name - and set(self._dependencies) == set(other.dependencies) + and set(self._dependencies) == set(other._dependencies) and set(self._poetry_dependencies) == set(other._poetry_dependencies) + and self._included_dependency_groups == other._included_dependency_groups ) def __repr__(self) -> str: diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/poetry-core-2.3.1/src/poetry/core/spdx/data/licenses.json new/poetry-core-2.3.2/src/poetry/core/spdx/data/licenses.json --- old/poetry-core-2.3.1/src/poetry/core/spdx/data/licenses.json 2026-02-01 14:48:13.000000000 +0100 +++ new/poetry-core-2.3.2/src/poetry/core/spdx/data/licenses.json 2026-03-29 09:38:03.000000000 +0200 @@ -254,6 +254,11 @@ false, false ], + "BOLA-1.1": [ + "Buena Onda License Agreement v1.1", + false, + false + ], "BSD-1-Clause": [ "BSD 1-Clause License", true, @@ -2569,6 +2574,11 @@ false, false ], + "OSC-1.0": [ + "OSC License 1.0", + true, + false + ], "OSET-PL-2.1": [ "OSET Public License version 2.1", true, diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/poetry-core-2.3.1/src/poetry/core/vcs/git.py new/poetry-core-2.3.2/src/poetry/core/vcs/git.py --- old/poetry-core-2.3.1/src/poetry/core/vcs/git.py 2026-02-01 14:48:13.000000000 +0100 +++ new/poetry-core-2.3.2/src/poetry/core/vcs/git.py 2026-03-29 09:38:03.000000000 +0200 @@ -271,9 +271,9 @@ ] args += ["ls-files", "--others", "-i", "--exclude-standard"] - output = self.run(*args) + output = self.run(*args).strip() - return output.strip().split("\n") + return output.split("\n") if output else [] def run(self, *args: Any, **kwargs: Any) -> str: folder = kwargs.pop("folder", None) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/poetry-core-2.3.1/src/poetry/core/version/pep440/version.py new/poetry-core-2.3.2/src/poetry/core/version/pep440/version.py --- old/poetry-core-2.3.1/src/poetry/core/version/pep440/version.py 2026-02-01 14:48:13.000000000 +0100 +++ new/poetry-core-2.3.2/src/poetry/core/version/pep440/version.py 2026-03-29 09:38:03.000000000 +0200 @@ -26,12 +26,24 @@ def __lt__(self, other: object) -> bool: return True + def __eq__(self, other: object) -> bool: + return isinstance(other, AlwaysSmaller) + + def __hash__(self) -> int: + return id(AlwaysSmaller) + @functools.total_ordering class AlwaysGreater: def __gt__(self, other: object) -> bool: return True + def __eq__(self, other: object) -> bool: + return isinstance(other, AlwaysGreater) + + def __hash__(self) -> int: + return id(AlwaysGreater) + class Infinity(AlwaysGreater, int): pass diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/poetry-core-2.3.1/tests/constraints/generic/test_constraint.py new/poetry-core-2.3.2/tests/constraints/generic/test_constraint.py --- old/poetry-core-2.3.1/tests/constraints/generic/test_constraint.py 2026-02-01 14:48:13.000000000 +0100 +++ new/poetry-core-2.3.2/tests/constraints/generic/test_constraint.py 2026-03-29 09:38:03.000000000 +0200 @@ -265,6 +265,31 @@ False, False, ), + # "in" / "not in" with MultiConstraint and UnionConstraint + ( + Constraint("tegra", "in"), + MultiConstraint(Constraint("win32", "!="), Constraint("linux", "!=")), + True, # "1.2-tegra" contains "tegra" and is neither "win32" nor "linux" + False, + ), + ( + Constraint("tegra", "not in"), + MultiConstraint(Constraint("win32", "!="), Constraint("linux", "!=")), + True, # "darwin" has no "tegra" and is neither "win32" nor "linux" + False, + ), + ( + Constraint("tegra", "in"), + UnionConstraint(Constraint("1.2-tegra"), Constraint("plain")), + True, # "tegra" is in "1.2-tegra" + False, + ), + ( + Constraint("tegra", "in"), + UnionConstraint(Constraint("plain"), Constraint("other")), + False, # "tegra" is not in "plain" or "other" + False, + ), ], ) def test_allows_any_and_allows_all( @@ -1203,7 +1228,15 @@ ( Constraint("tegra", "not in"), Constraint("rpi", "not in"), - AnyConstraint(), + # NB not AnyConstraint - eg "tegra-rpi" does not satisfy either constraint + ( + UnionConstraint( + Constraint("tegra", "not in"), Constraint("rpi", "not in") + ), + UnionConstraint( + Constraint("rpi", "not in"), Constraint("tegra", "not in") + ), + ), ), ( Constraint("tegra", "in"), diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/poetry-core-2.3.1/tests/constraints/version/test_parse_constraint.py new/poetry-core-2.3.2/tests/constraints/version/test_parse_constraint.py --- old/poetry-core-2.3.1/tests/constraints/version/test_parse_constraint.py 2026-02-01 14:48:13.000000000 +0100 +++ new/poetry-core-2.3.2/tests/constraints/version/test_parse_constraint.py 2026-03-29 09:38:03.000000000 +0200 @@ -584,7 +584,9 @@ assert parse_constraint(constraint) == expected [email protected]("constraint", ["4.9.253-tegra", "2022Server"]) [email protected]( + "constraint", ["4.9.253-tegra", "2022Server", "6.12.74+deb13+1-amd64"] +) def test_parse_marker_constraint_does_not_allow_invalid_version( constraint: str, ) -> None: @@ -597,6 +599,7 @@ [ ("4.9.253-tegra", Version.from_parts(4, 9, 253, local="tegra")), ("2022Server", Version.from_parts(2022, local="Server")), + ("6.12.74+deb13+1-amd64", Version.from_parts(6, 12, 74, local="deb13+1-amd64")), ], ) def test_parse_marker_constraint_does_allow_invalid_version_if_requested( diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/poetry-core-2.3.1/tests/constraints/version/test_version_range.py new/poetry-core-2.3.2/tests/constraints/version/test_version_range.py --- old/poetry-core-2.3.1/tests/constraints/version/test_version_range.py 2026-02-01 14:48:13.000000000 +0100 +++ new/poetry-core-2.3.2/tests/constraints/version/test_version_range.py 2026-03-29 09:38:03.000000000 +0200 @@ -137,6 +137,7 @@ (">1.7.post2", "1.7.1", True), (">1.7.post2", "1.7.0.post2", False), (">1.7.post2", "1.7.0.post3", True), + (">1.7", "1.7.0.post1+local.1", False), ## >V MUST NOT match a local version of the specified version (">1.7.0", "1.7.0+local.1", False), ("<1.7.0", "1.7.0+local.1", False), # spec does not clarify this @@ -429,6 +430,14 @@ ("2.0.1", "!=2.0"), ("2.0.1", "!=2.0.0"), ("2.0", "!=2.0+deadbeef"), + # != must not inherit exclusive ordered comparison rules from < and > + # (pre-releases, post-releases, dev-releases of the specified + # version are not equal to it) + ("2.0.dev1", "!=2"), + ("2.0a1", "!=2"), + ("2.0b1", "!=2"), + ("2.0rc1", "!=2"), + ("2.0.post1", "!=2"), # Test the in-equality operation with a prefix ("2.0", "!=3.*"), ("2.1", "!=2.0.*"), @@ -580,25 +589,10 @@ https://github.com/pypa/packaging/blob/8b86d85797b9f26d98ecfbe0271ce4dc9495d98c/tests/test_specifiers.py#L469 """ constraint = parse_constraint(spec) - v = Version.parse(version) - if expected: - # Test that the plain string form works - # assert version in spec - assert constraint.allows(v) - - # Test that the version instance form works - # assert version in spec - assert constraint.allows(v) - else: - # Test that the plain string form works - # assert version not in spec - assert not constraint.allows(v) - - # Test that the version instance form works - # assert version not in spec - assert not constraint.allows(v) + allowed = constraint.allows(v) + assert allowed is expected @pytest.mark.parametrize( diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/poetry-core-2.3.1/tests/masonry/builders/test_sdist.py new/poetry-core-2.3.2/tests/masonry/builders/test_sdist.py --- old/poetry-core-2.3.1/tests/masonry/builders/test_sdist.py 2026-02-01 14:48:13.000000000 +0100 +++ new/poetry-core-2.3.2/tests/masonry/builders/test_sdist.py 2026-03-29 09:38:03.000000000 +0200 @@ -284,6 +284,89 @@ assert pkg_data == {"": ["*"]} +def test_find_packages_no_duplicate_data_entries(tmp_path: Path) -> None: + """Test that find_packages does not produce duplicate package_data entries.""" + # Create a minimal project with a data directory where one file is excluded + pkg = tmp_path / "my_package" + pkg.mkdir() + (pkg / "__init__.py").touch() + + data_dir = pkg / "data" + data_dir.mkdir() + (data_dir / "keep1.txt").touch() + (data_dir / "keep2.txt").touch() + (data_dir / "excluded.dat").touch() + + (tmp_path / "pyproject.toml").write_text( + "[tool.poetry]\n" + 'name = "my-package"\n' + 'version = "0.1.0"\n' + 'description = "test"\n' + 'authors = ["Test <[email protected]>"]\n' + 'exclude = ["**/*.dat"]\n' + "\n" + "[tool.poetry.dependencies]\n" + 'python = "^3.8"\n' + ) + + poetry = Factory().create_poetry(tmp_path) + builder = SdistBuilder(poetry) + include = PackageInclude(tmp_path, "my_package", formats=["sdist"]) + + _, _, pkg_data = builder.find_packages(include) + + data_entries = pkg_data.get("my_package", []) + assert sorted(data_entries) == ["data/keep1.txt", "data/keep2.txt"] + + +def test_find_packages_nested_subpackage_data(tmp_path: Path) -> None: + """Data in a nested subpackage must be attributed to that subpackage. + + On Windows os.path.relpath returns backslash-separated paths, but + find_nearest_pkg reconstructs ancestors with forward slashes. If the + two are not normalised the lookup in subpkg_paths misses and data + files get attributed to the wrong (higher-level) package. + """ + pkg = tmp_path / "my_package" + pkg.mkdir() + (pkg / "__init__.py").touch() + + sub = pkg / "sub" + sub.mkdir() + (sub / "__init__.py").touch() + + nested = sub / "nested" + nested.mkdir() + (nested / "__init__.py").touch() + + data_dir = nested / "data" + data_dir.mkdir() + (data_dir / "file.txt").touch() + + (tmp_path / "pyproject.toml").write_text( + "[tool.poetry]\n" + 'name = "my-package"\n' + 'version = "0.1.0"\n' + 'description = "test"\n' + 'authors = ["Test <[email protected]>"]\n' + "\n" + "[tool.poetry.dependencies]\n" + 'python = "^3.8"\n' + ) + + poetry = Factory().create_poetry(tmp_path) + builder = SdistBuilder(poetry) + include = PackageInclude(tmp_path, "my_package", formats=["sdist"]) + + _, packages, pkg_data = builder.find_packages(include) + + assert "my_package.sub.nested" in packages + # Data must be attributed to the nearest subpackage (my_package.sub.nested), + # not to a higher-level package like my_package.sub or my_package. + assert "my_package.sub.nested" in pkg_data + assert pkg_data["my_package.sub.nested"] == ["data/*"] + + @pytest.mark.parametrize( "project_name", ["complete", "complete_new", "complete_dynamic"] ) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/poetry-core-2.3.1/tests/packages/test_dependency_group.py new/poetry-core-2.3.2/tests/packages/test_dependency_group.py --- old/poetry-core-2.3.1/tests/packages/test_dependency_group.py 2026-02-01 14:48:13.000000000 +0100 +++ new/poetry-core-2.3.2/tests/packages/test_dependency_group.py 2026-03-29 09:38:03.000000000 +0200 @@ -153,6 +153,31 @@ assert {d.name for d in group._poetry_dependencies} == {"baz"} +def test_remove_dependency_does_not_leak_included_group_deps() -> None: + """Removing a dep must not copy included-group deps into _dependencies.""" + main = DependencyGroup(name="main") + main.add_dependency(Dependency(name="flask", constraint="*")) + + extras = DependencyGroup(name="extras") + extras.add_dependency(Dependency(name="requests", constraint="*")) + main.include_dependency_group(extras) + + # Before removal: flask from _dependencies, requests from included group + assert [d.name for d in main.dependencies] == ["flask", "requests"] + + # Remove a dep that doesn't exist — should be a no-op + main.remove_dependency("nonexistent") + + # Nothing changed. + assert [d.name for d in main.dependencies] == ["flask", "requests"] + assert [d.name for d in main._dependencies] == ["flask"] + + # Also verify removing an actual dep still works correctly + main.remove_dependency("flask") + assert [d.name for d in main.dependencies] == ["requests"] + assert main._dependencies == [] + + @pytest.mark.parametrize("mixed_dynamic", [False, True]) @pytest.mark.parametrize( ( @@ -644,3 +669,17 @@ ValueError, match=f"Dependency group {group_name} is already included" ): group.include_dependency_group(group_3) + + +def test_dependency_group_inequality() -> None: + a = DependencyGroup(name="test") + a.add_dependency(Dependency(name="dep1", constraint="*")) + + b = DependencyGroup(name="test") + b.add_dependency(Dependency(name="dep1", constraint="*")) + extras = DependencyGroup(name="extras") + extras.add_dependency(Dependency(name="dep2", constraint="*")) + b.include_dependency_group(extras) + + assert a != b + assert b != a diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/poetry-core-2.3.1/tests/test_factory.py new/poetry-core-2.3.2/tests/test_factory.py --- old/poetry-core-2.3.1/tests/test_factory.py 2026-02-01 14:48:13.000000000 +0100 +++ new/poetry-core-2.3.2/tests/test_factory.py 2026-03-29 09:38:03.000000000 +0200 @@ -696,6 +696,19 @@ assert poetry.package.all_classifiers == expected +def test_create_poetry_inline_readme_text(tmp_path: Path) -> None: + pyproject = tmp_path / "pyproject.toml" + pyproject.write_text( + '[project]\nname="foo"\nversion="1"\ndescription = ""\n' + 'readme = { text = "some text", content-type = "text/markdown" }\n', + encoding="utf-8", + ) + poetry = Factory().create_poetry(tmp_path) + + assert poetry.package.readme_content == "some text" + assert poetry.package.readme_content_type == "text/markdown" + + def test_create_poetry_no_readme(tmp_path: Path) -> None: pyproject = tmp_path / "pyproject.toml" pyproject.write_text( @@ -2044,3 +2057,52 @@ assert len(poetry.package.all_requires) == 1 assert poetry.package.has_dependency_group("dev") assert poetry.package.dependency_group("dev").is_optional() is optional + + +def test_pep735_includes_not_overwritten_by_poetry_includes( + temporary_directory: Path, +) -> None: + """PEP 735 include-group entries must not be lost when [tool.poetry.group] + also defines include-groups for the same group. + + Setup: + [dependency-groups] dev includes testing (PEP 735) + [tool.poetry.group.dev] includes utils (poetry) + [dependency-groups] testing includes dev (PEP 735) + The poetry-side include (dev -> utils) must not erase the PEP 735 one. + """ + content = """\ +[project] +name = "my-package" +version = "1.2.3" + +[dependency-groups] +dev = [ + {include-group = "testing"}, + "black", +] +testing = [ + {include-group = "dev"}, + "pytest", +] +utils = [ + "mypy", +] + +[tool.poetry.group.dev] +include-groups = [ + "utils", +] +""" + + expected = """\ +The Poetry configuration is invalid: + - Cyclic dependency group include in dev: testing -> dev + - Cyclic dependency group include in testing: dev -> testing +""" + assert_invalid_group_including( + toml_data=content, + expected_error=expected, + error_type=RuntimeError, + temporary_directory=temporary_directory, + ) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/poetry-core-2.3.1/tests/vcs/test_vcs.py new/poetry-core-2.3.2/tests/vcs/test_vcs.py --- old/poetry-core-2.3.1/tests/vcs/test_vcs.py 2026-02-01 14:48:13.000000000 +0100 +++ new/poetry-core-2.3.2/tests/vcs/test_vcs.py 2026-03-29 09:38:03.000000000 +0200 @@ -562,3 +562,14 @@ vcs = get_vcs(subdir) assert vcs is None + + +def test_get_ignored_files_empty_repo(tmp_path: Path) -> None: + """get_ignored_files must return [] when no files are ignored.""" + repo_path = tmp_path / "repo" + repo_path.mkdir() + assert subprocess.check_call([executable(), "init"], cwd=repo_path) == 0 + + git = Git() + result = git.get_ignored_files(folder=repo_path) + assert result == [] diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/poetry-core-2.3.1/tests/version/pep440/test_version.py new/poetry-core-2.3.2/tests/version/pep440/test_version.py --- old/poetry-core-2.3.1/tests/version/pep440/test_version.py 2026-02-01 14:48:13.000000000 +0100 +++ new/poetry-core-2.3.2/tests/version/pep440/test_version.py 2026-03-29 09:38:03.000000000 +0200 @@ -528,3 +528,16 @@ def test_without_devrelease(version: str, expected: str) -> None: v = PEP440Version.parse(version) assert v.without_devrelease().text == expected + + +def test_local_version_ordering_and_equality() -> None: + """PEP 440: versions with a local segment must sort after the same + version without one, and they must not compare equal. + """ + v_plain = PEP440Version.parse("1.0") + v_local = PEP440Version.parse("1.0+0") + + # 1.0+0 must be greater than 1.0 (local versions sort after) + assert v_local > v_plain + # They must not be equal + assert v_plain != v_local
