From e64eb9e2e88a6c6f3f898ad461b5b9d808064aa2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Randy=20D=C3=B6ring?= <30527984+radoering@users.noreply.github.com> Date: Sat, 24 Sep 2022 13:22:43 +0200 Subject: [PATCH] provider: fetch optional vcs dependency only if required Co-authored-by: Maxim Koltsov --- src/poetry/puzzle/provider.py | 24 ++++++++++++------------ tests/puzzle/test_provider.py | 22 ++++++++++++++++++++++ 2 files changed, 34 insertions(+), 12 deletions(-) diff --git a/src/poetry/puzzle/provider.py b/src/poetry/puzzle/provider.py index f0ba16e5669..4d9ebf47562 100644 --- a/src/poetry/puzzle/provider.py +++ b/src/poetry/puzzle/provider.py @@ -572,18 +572,6 @@ def complete_package( dependency = dependency_package.dependency requires = package.requires - if self._load_deferred: - # Retrieving constraints for deferred dependencies - for r in requires: - if r.is_direct_origin(): - locked = self.get_locked(r) - # If lock file contains exactly the same URL and reference - # (commit hash) of dependency as is requested, - # do not analyze it again: nothing could have changed. - if locked is not None and locked.package.is_same_package_as(r): - continue - self.search_for_direct_origin_dependency(r) - optional_dependencies = [] _dependencies = [] @@ -636,6 +624,18 @@ def complete_package( _dependencies.append(dep) + if self._load_deferred: + # Retrieving constraints for deferred dependencies + for dep in _dependencies: + if dep.is_direct_origin(): + locked = self.get_locked(dep) + # If lock file contains exactly the same URL and reference + # (commit hash) of dependency as is requested, + # do not analyze it again: nothing could have changed. + if locked is not None and locked.package.is_same_package_as(dep): + continue + self.search_for_direct_origin_dependency(dep) + dependencies = self._get_dependencies_with_overrides( _dependencies, dependency_package ) diff --git a/tests/puzzle/test_provider.py b/tests/puzzle/test_provider.py index a6c1575681a..9775cc9f70c 100644 --- a/tests/puzzle/test_provider.py +++ b/tests/puzzle/test_provider.py @@ -716,3 +716,25 @@ def test_complete_package_with_extras_preserves_source_name( assert requires[0].source_name == source_name assert requires[1].name == "b" assert requires[1].source_name is None + + +@pytest.mark.parametrize("with_extra", [False, True]) +def test_complete_package_fetches_optional_vcs_dependency_only_if_requested( + provider: Provider, repository: Repository, mocker: MockerFixture, with_extra: bool +): + optional_vcs_dependency = Factory.create_dependency( + "demo", {"git": "https://github.com/demo/demo.git", "optional": True} + ) + package = Package("A", "1.0", features=["foo"] if with_extra else []) + package.add_dependency(optional_vcs_dependency) + package.extras["foo"] = [optional_vcs_dependency] + repository.add_package(package) + + spy = mocker.spy(provider, "_search_for_vcs") + + provider.complete_package(DependencyPackage(package.to_dependency(), package)) + + if with_extra: + spy.assert_called() + else: + spy.assert_not_called()