From 5fdd486dbe7dad9567e50191693549857bf66999 Mon Sep 17 00:00:00 2001 From: Arun Babu Neelicattu Date: Thu, 19 May 2022 00:37:37 +0200 Subject: [PATCH] mixology: ensure dependency cache respects source --- src/poetry/mixology/version_solver.py | 16 +++-- .../version_solver/test_dependency_cache.py | 59 +++++++++++++++++++ 2 files changed, 71 insertions(+), 4 deletions(-) create mode 100644 tests/mixology/version_solver/test_dependency_cache.py diff --git a/src/poetry/mixology/version_solver.py b/src/poetry/mixology/version_solver.py index 6fd225a4958..d39591b4b8f 100644 --- a/src/poetry/mixology/version_solver.py +++ b/src/poetry/mixology/version_solver.py @@ -41,18 +41,26 @@ class DependencyCache: def __init__(self, provider: Provider) -> None: self.provider = provider - self.cache: dict[str, list[DependencyPackage]] = {} + self.cache: dict[ + tuple[str, str | None, str | None, str | None], list[DependencyPackage] + ] = {} @functools.lru_cache(maxsize=128) def search_for(self, dependency: Dependency) -> list[DependencyPackage]: - complete_name = dependency.complete_name - packages = self.cache.get(complete_name) + key = ( + dependency.complete_name, + dependency.source_type, + dependency.source_url, + dependency.source_reference, + ) + + packages = self.cache.get(key) if packages is None: packages = self.provider.search_for(dependency) else: packages = [p for p in packages if dependency.constraint.allows(p.version)] - self.cache[complete_name] = packages + self.cache[key] = packages return packages diff --git a/tests/mixology/version_solver/test_dependency_cache.py b/tests/mixology/version_solver/test_dependency_cache.py new file mode 100644 index 00000000000..469a1e569db --- /dev/null +++ b/tests/mixology/version_solver/test_dependency_cache.py @@ -0,0 +1,59 @@ +from __future__ import annotations + +from typing import TYPE_CHECKING + +from poetry.factory import Factory +from poetry.mixology.version_solver import DependencyCache +from tests.mixology.helpers import add_to_repo + + +if TYPE_CHECKING: + from poetry.core.packages.project_package import ProjectPackage + + from poetry.repositories import Repository + from tests.mixology.version_solver.conftest import Provider + + +def test_solver_dependency_cache_respects_source_type( + root: ProjectPackage, provider: Provider, repo: Repository +): + dependency_pypi = Factory.create_dependency("demo", ">=0.1.0") + dependency_git = Factory.create_dependency( + "demo", {"git": "https://github.com/demo/demo.git"}, groups=["dev"] + ) + root.add_dependency(dependency_pypi) + root.add_dependency(dependency_git) + + add_to_repo(repo, "demo", "1.0.0") + + cache = DependencyCache(provider) + cache.search_for.cache_clear() + + # ensure cache was never hit for both calls + cache.search_for(dependency_pypi) + cache.search_for(dependency_git) + assert not cache.search_for.cache_info().hits + + packages_pypi = cache.search_for(dependency_pypi) + packages_git = cache.search_for(dependency_git) + + assert cache.search_for.cache_info().hits == 2 + assert cache.search_for.cache_info().currsize == 2 + + assert len(packages_pypi) == len(packages_git) == 1 + assert packages_pypi != packages_git + + package_pypi = packages_pypi[0] + package_git = packages_git[0] + + assert package_pypi.package.name == dependency_pypi.name + assert package_pypi.package.version.text == "1.0.0" + + assert package_git.package.name == dependency_git.name + assert package_git.package.version.text == "0.1.2" + assert package_git.package.source_type == dependency_git.source_type + assert package_git.package.source_url == dependency_git.source_url + assert ( + package_git.package.source_resolved_reference + == "9cf87a285a2d3fbb0b9fa621997b3acc3631ed24" + )