From b3b6d96b48c5d23ad9fb18c333085319284af5b0 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Randy=20D=C3=B6ring?=
<30527984+radoering@users.noreply.github.com>
Date: Sun, 2 Oct 2022 15:00:51 +0200
Subject: [PATCH] provider: do not merge dependencies from different sources
---
src/poetry/puzzle/provider.py | 33 +++++++++++++++++++++------------
tests/puzzle/test_provider.py | 23 +++++++++++++++++++++++
tests/puzzle/test_solver.py | 16 ++++++++++++----
3 files changed, 56 insertions(+), 16 deletions(-)
diff --git a/src/poetry/puzzle/provider.py b/src/poetry/puzzle/provider.py
index 4d9ebf47562..4923521be96 100644
--- a/src/poetry/puzzle/provider.py
+++ b/src/poetry/puzzle/provider.py
@@ -670,19 +670,12 @@ def complete_package(
self.debug(f"Duplicate dependencies for {dep_name}")
- non_direct_origin_deps: list[Dependency] = []
- direct_origin_deps: list[Dependency] = []
- for dep in deps:
- if dep.is_direct_origin():
- direct_origin_deps.append(dep)
- else:
- non_direct_origin_deps.append(dep)
- deps = (
- self._merge_dependencies_by_constraint(
- self._merge_dependencies_by_marker(non_direct_origin_deps)
+ dep_groups = self._group_by_source(deps)
+ deps = []
+ for group in dep_groups:
+ deps += self._merge_dependencies_by_constraint(
+ self._merge_dependencies_by_marker(group)
)
- + direct_origin_deps
- )
if len(deps) == 1:
self.debug(f"Merging requirements for {deps[0]!s}")
dependencies.append(deps[0])
@@ -947,6 +940,22 @@ def debug(self, message: str, depth: int = 0) -> None:
self._io.write(debug_info)
+ def _group_by_source(
+ self, dependencies: Iterable[Dependency]
+ ) -> list[list[Dependency]]:
+ groups: list[list[Dependency]] = []
+ for dep in dependencies:
+ for group in groups:
+ if (
+ dep.is_same_source_as(group[0])
+ and dep.source_name == group[0].source_name
+ ):
+ group.append(dep)
+ break
+ else:
+ groups.append([dep])
+ return groups
+
def _merge_dependencies_by_constraint(
self, dependencies: Iterable[Dependency]
) -> list[Dependency]:
diff --git a/tests/puzzle/test_provider.py b/tests/puzzle/test_provider.py
index 9775cc9f70c..375c4e10da7 100644
--- a/tests/puzzle/test_provider.py
+++ b/tests/puzzle/test_provider.py
@@ -622,6 +622,29 @@ def test_search_for_file_wheel_with_extras(provider: Provider):
}
+def test_complete_package_does_not_merge_different_source_names(
+ provider: Provider, root: ProjectPackage
+) -> None:
+ foo_source_1 = get_dependency("foo")
+ foo_source_1.source_name = "source_1"
+ foo_source_2 = get_dependency("foo")
+ foo_source_2.source_name = "source_2"
+
+ root.add_dependency(foo_source_1)
+ root.add_dependency(foo_source_2)
+
+ complete_package = provider.complete_package(
+ DependencyPackage(root.to_dependency(), root)
+ )
+
+ requires = complete_package.package.all_requires
+ assert len(requires) == 2
+ assert {requires[0].source_name, requires[1].source_name} == {
+ "source_1",
+ "source_2",
+ }
+
+
def test_complete_package_preserves_source_type(
provider: Provider, root: ProjectPackage
) -> None:
diff --git a/tests/puzzle/test_solver.py b/tests/puzzle/test_solver.py
index 4a670c93df7..601151eab16 100644
--- a/tests/puzzle/test_solver.py
+++ b/tests/puzzle/test_solver.py
@@ -1368,8 +1368,9 @@ def test_solver_duplicate_dependencies_different_constraints_merge_by_marker(
)
+@pytest.mark.parametrize("git_first", [False, True])
def test_solver_duplicate_dependencies_different_sources_types_are_preserved(
- solver: Solver, repo: Repository, package: ProjectPackage
+ solver: Solver, repo: Repository, package: ProjectPackage, git_first: bool
):
pendulum = get_package("pendulum", "2.0.3")
repo.add_package(pendulum)
@@ -1380,8 +1381,12 @@ def test_solver_duplicate_dependencies_different_sources_types_are_preserved(
dependency_git = Factory.create_dependency(
"demo", {"git": "https://github.com/demo/demo.git"}, groups=["dev"]
)
- package.add_dependency(dependency_git)
- package.add_dependency(dependency_pypi)
+ if git_first:
+ package.add_dependency(dependency_git)
+ package.add_dependency(dependency_pypi)
+ else:
+ package.add_dependency(dependency_pypi)
+ package.add_dependency(dependency_git)
demo = Package(
"demo",
@@ -1413,7 +1418,10 @@ def test_solver_duplicate_dependencies_different_sources_types_are_preserved(
assert len(complete_package.package.all_requires) == 2
- pypi, git = complete_package.package.all_requires
+ if git_first:
+ git, pypi = complete_package.package.all_requires
+ else:
+ pypi, git = complete_package.package.all_requires
assert isinstance(pypi, Dependency)
assert pypi == dependency_pypi