Skip to content

Commit

Permalink
provider: do not merge dependencies from different sources
Browse files Browse the repository at this point in the history
  • Loading branch information
radoering committed Oct 2, 2022
1 parent ca74472 commit b3b6d96
Show file tree
Hide file tree
Showing 3 changed files with 56 additions and 16 deletions.
33 changes: 21 additions & 12 deletions src/poetry/puzzle/provider.py
Expand Up @@ -670,19 +670,12 @@ def complete_package(

self.debug(f"<debug>Duplicate dependencies for {dep_name}</debug>")

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"<debug>Merging requirements for {deps[0]!s}</debug>")
dependencies.append(deps[0])
Expand Down Expand Up @@ -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]:
Expand Down
23 changes: 23 additions & 0 deletions tests/puzzle/test_provider.py
Expand Up @@ -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:
Expand Down
16 changes: 12 additions & 4 deletions tests/puzzle/test_solver.py
Expand Up @@ -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)
Expand All @@ -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",
Expand Down Expand Up @@ -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
Expand Down

0 comments on commit b3b6d96

Please sign in to comment.