From 9f8ed5577e19762da1445a106633b304c0c04567 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Randy=20D=C3=B6ring?= <30527984+radoering@users.noreply.github.com> Date: Sat, 20 Aug 2022 17:47:05 +0200 Subject: [PATCH] refactor(solver/provider/version_solver): move get_locked() from VersionSolver to Provider --- src/poetry/installation/installer.py | 3 +- src/poetry/mixology/__init__.py | 10 +- src/poetry/mixology/version_solver.py | 41 +-- src/poetry/puzzle/provider.py | 60 +++- src/poetry/puzzle/solver.py | 38 +-- tests/mixology/helpers.py | 50 ++- .../mixology/version_solver/test_with_lock.py | 70 +++-- tests/puzzle/test_solver.py | 284 +++++++----------- 8 files changed, 243 insertions(+), 313 deletions(-) diff --git a/src/poetry/installation/installer.py b/src/poetry/installation/installer.py index b590483bbc5..4203f0fe48a 100644 --- a/src/poetry/installation/installer.py +++ b/src/poetry/installation/installer.py @@ -23,6 +23,7 @@ from collections.abc import Sequence from cleo.io.io import IO + from packaging.utils import NormalizedName from poetry.core.packages.project_package import ProjectPackage from poetry.config.config import Config @@ -60,7 +61,7 @@ def __init__( self._execute_operations = True self._lock = False - self._whitelist: list[str] = [] + self._whitelist: list[NormalizedName] = [] self._extras: list[str] = [] diff --git a/src/poetry/mixology/__init__.py b/src/poetry/mixology/__init__.py index 88d9d174229..32b52549dad 100644 --- a/src/poetry/mixology/__init__.py +++ b/src/poetry/mixology/__init__.py @@ -9,16 +9,10 @@ from poetry.core.packages.project_package import ProjectPackage from poetry.mixology.result import SolverResult - from poetry.packages import DependencyPackage from poetry.puzzle.provider import Provider -def resolve_version( - root: ProjectPackage, - provider: Provider, - locked: dict[str, list[DependencyPackage]] | None = None, - use_latest: list[str] | None = None, -) -> SolverResult: - solver = VersionSolver(root, provider, locked=locked, use_latest=use_latest) +def resolve_version(root: ProjectPackage, provider: Provider) -> SolverResult: + solver = VersionSolver(root, provider) return solver.solve() diff --git a/src/poetry/mixology/version_solver.py b/src/poetry/mixology/version_solver.py index 7ff1d13ba80..7650ebf086f 100644 --- a/src/poetry/mixology/version_solver.py +++ b/src/poetry/mixology/version_solver.py @@ -18,12 +18,12 @@ from poetry.mixology.result import SolverResult from poetry.mixology.set_relation import SetRelation from poetry.mixology.term import Term -from poetry.packages import DependencyPackage if TYPE_CHECKING: from poetry.core.packages.project_package import ProjectPackage + from poetry.packages import DependencyPackage from poetry.puzzle.provider import Provider @@ -82,23 +82,10 @@ class VersionSolver: on how this solver works. """ - def __init__( - self, - root: ProjectPackage, - provider: Provider, - locked: dict[str, list[DependencyPackage]] | None = None, - use_latest: list[str] | None = None, - ) -> None: + def __init__(self, root: ProjectPackage, provider: Provider) -> None: self._root = root self._provider = provider self._dependency_cache = DependencyCache(provider) - self._locked = locked or {} - - if use_latest is None: - use_latest = [] - - self._use_latest = use_latest - self._incompatibilities: dict[str, list[Incompatibility]] = {} self._contradicted_incompatibilities: set[Incompatibility] = set() self._solution = PartialSolution() @@ -384,12 +371,12 @@ def _get_min(dependency: Dependency) -> tuple[bool, int]: if dependency.is_direct_origin(): return False, -1 - if dependency.name in self._use_latest: + if dependency.name in self._provider.use_latest: # If we're forced to use the latest version of a package, it effectively # only has one version to choose from. return not dependency.marker.is_any(), 1 - locked = self._get_locked(dependency) + locked = self._provider.get_locked(dependency) if locked: return not dependency.marker.is_any(), 1 @@ -406,7 +393,7 @@ def _get_min(dependency: Dependency) -> tuple[bool, int]: else: dependency = min(*unsatisfied, key=_get_min) - locked = self._get_locked(dependency) + locked = self._provider.get_locked(dependency) if locked is None: try: packages = self._dependency_cache.search_for(dependency) @@ -499,23 +486,5 @@ def _add_incompatibility(self, incompatibility: Incompatibility) -> None: incompatibility ) - def _get_locked(self, dependency: Dependency) -> DependencyPackage | None: - if dependency.name in self._use_latest: - return None - - locked = self._locked.get(dependency.name, []) - for dependency_package in locked: - package = dependency_package.package - if ( - # Locked dependencies are always without features. - # Thus, we can't use is_same_package_as() here because it compares - # the complete_name (including features). - dependency.name == package.name - and dependency.is_same_source_as(package) - and dependency.constraint.allows(package.version) - ): - return DependencyPackage(dependency, package) - return None - def _log(self, text: str) -> None: self._provider.debug(text, self._solution.attempted_solutions) diff --git a/src/poetry/puzzle/provider.py b/src/poetry/puzzle/provider.py index 87bb37e7769..6c6548a0605 100644 --- a/src/poetry/puzzle/provider.py +++ b/src/poetry/puzzle/provider.py @@ -12,6 +12,7 @@ from contextlib import contextmanager from pathlib import Path from typing import TYPE_CHECKING +from typing import Collection from typing import cast from cleo.ui.progress_indicator import ProgressIndicator @@ -42,6 +43,7 @@ from collections.abc import Iterator from cleo.io.io import IO + from packaging.utils import NormalizedName from poetry.core.packages.dependency import Dependency from poetry.core.packages.directory_dependency import DirectoryDependency from poetry.core.packages.file_dependency import FileDependency @@ -127,6 +129,7 @@ def __init__( io: IO, *, installed: list[Package] | None = None, + locked: list[Package] | None = None, ) -> None: self._package = package self._pool = pool @@ -140,11 +143,27 @@ def __init__( self._source_root: Path | None = None self._installed_packages = installed if installed is not None else [] self._direct_origin_packages: dict[str, Package] = {} + self._locked: dict[NormalizedName, list[DependencyPackage]] = defaultdict(list) + self._use_latest: Collection[NormalizedName] = [] + + for package in locked or []: + self._locked[package.name].append( + DependencyPackage(package.to_dependency(), package) + ) + for dependency_packages in self._locked.values(): + dependency_packages.sort( + key=lambda p: p.package.version, + reverse=True, + ) @property def pool(self) -> Pool: return self._pool + @property + def use_latest(self) -> Collection[NormalizedName]: + return self._use_latest + def is_debugging(self) -> bool: return self._is_debugging @@ -161,9 +180,10 @@ def use_source_root(self, source_root: Path) -> Iterator[Provider]: original_source_root = self._source_root self._source_root = source_root - yield self - - self._source_root = original_source_root + try: + yield self + finally: + self._source_root = original_source_root @contextmanager def use_environment(self, env: Env) -> Iterator[Provider]: @@ -172,10 +192,20 @@ def use_environment(self, env: Env) -> Iterator[Provider]: self._env = env self._python_constraint = Version.parse(env.marker_env["python_full_version"]) - yield self + try: + yield self + finally: + self._env = None + self._python_constraint = original_python_constraint - self._env = None - self._python_constraint = original_python_constraint + @contextmanager + def use_latest_for(self, names: Collection[NormalizedName]) -> Iterator[Provider]: + self._use_latest = names + + try: + yield self + finally: + self._use_latest = [] @staticmethod def validate_package_for_dependency( @@ -800,6 +830,24 @@ def fmt_warning(d: Dependency) -> str: return dependency_package + def get_locked(self, dependency: Dependency) -> DependencyPackage | None: + if dependency.name in self._use_latest: + return None + + locked = self._locked.get(dependency.name, []) + for dependency_package in locked: + package = dependency_package.package + if ( + # Locked dependencies are always without features. + # Thus, we can't use is_same_package_as() here because it compares + # the complete_name (including features). + dependency.name == package.name + and dependency.is_same_source_as(package) + and dependency.constraint.allows(package.version) + ): + return DependencyPackage(dependency, package) + return None + def debug(self, message: str, depth: int = 0) -> None: if not (self._io.is_very_verbose() or self._io.is_debug()): return diff --git a/src/poetry/puzzle/solver.py b/src/poetry/puzzle/solver.py index 80a83cdd921..d6928e22ef4 100644 --- a/src/poetry/puzzle/solver.py +++ b/src/poetry/puzzle/solver.py @@ -5,6 +5,7 @@ from collections import defaultdict from contextlib import contextmanager from typing import TYPE_CHECKING +from typing import Collection from typing import FrozenSet from typing import Tuple from typing import TypeVar @@ -13,7 +14,6 @@ from poetry.mixology import resolve_version from poetry.mixology.failure import SolveFailure -from poetry.packages import DependencyPackage from poetry.puzzle.exceptions import OverrideNeeded from poetry.puzzle.exceptions import SolverProblemError from poetry.puzzle.provider import Indicator @@ -24,10 +24,12 @@ from collections.abc import Iterator from cleo.io.io import IO + from packaging.utils import NormalizedName from poetry.core.packages.dependency import Dependency from poetry.core.packages.package import Package from poetry.core.packages.project_package import ProjectPackage + from poetry.packages import DependencyPackage from poetry.puzzle.transaction import Transaction from poetry.repositories import Pool from poetry.utils.env import Env @@ -49,7 +51,7 @@ def __init__( self._io = io self._provider = Provider( - self._package, self._pool, self._io, installed=installed + self._package, self._pool, self._io, installed=installed, locked=locked ) self._overrides: list[dict[DependencyPackage, dict[str, Dependency]]] = [] @@ -62,12 +64,14 @@ def use_environment(self, env: Env) -> Iterator[None]: with self.provider.use_environment(env): yield - def solve(self, use_latest: list[str] | None = None) -> Transaction: + def solve( + self, use_latest: Collection[NormalizedName] | None = None + ) -> Transaction: from poetry.puzzle.transaction import Transaction - with self._progress(): + with self._progress(), self._provider.use_latest_for(use_latest or []): start = time.time() - packages, depths = self._solve(use_latest=use_latest) + packages, depths = self._solve() end = time.time() if len(self._overrides) > 1: @@ -106,7 +110,6 @@ def _progress(self) -> Iterator[None]: def _solve_in_compatibility_mode( self, overrides: tuple[dict[DependencyPackage, dict[str, Dependency]], ...], - use_latest: list[str] | None = None, ) -> tuple[list[Package], list[int]]: packages = [] depths = [] @@ -116,7 +119,7 @@ def _solve_in_compatibility_mode( f"with the following overrides ({override})." ) self._provider.set_overrides(override) - _packages, _depths = self._solve(use_latest=use_latest) + _packages, _depths = self._solve() for index, package in enumerate(_packages): if package not in packages: packages.append(package) @@ -133,31 +136,16 @@ def _solve_in_compatibility_mode( return packages, depths - def _solve( - self, use_latest: list[str] | None = None - ) -> tuple[list[Package], list[int]]: + def _solve(self) -> tuple[list[Package], list[int]]: if self._provider._overrides: self._overrides.append(self._provider._overrides) - locked: dict[str, list[DependencyPackage]] = defaultdict(list) - for package in self._locked_packages: - locked[package.name].append( - DependencyPackage(package.to_dependency(), package) - ) - for dependency_packages in locked.values(): - dependency_packages.sort( - key=lambda p: p.package.version, - reverse=True, - ) - try: - result = resolve_version( - self._package, self._provider, locked=locked, use_latest=use_latest - ) + result = resolve_version(self._package, self._provider) packages = result.packages except OverrideNeeded as e: - return self._solve_in_compatibility_mode(e.overrides, use_latest=use_latest) + return self._solve_in_compatibility_mode(e.overrides) except SolveFailure as e: raise SolverProblemError(e) diff --git a/tests/mixology/helpers.py b/tests/mixology/helpers.py index 0120bdb72ff..3aa080f2d5f 100644 --- a/tests/mixology/helpers.py +++ b/tests/mixology/helpers.py @@ -7,10 +7,11 @@ from poetry.factory import Factory from poetry.mixology.failure import SolveFailure from poetry.mixology.version_solver import VersionSolver -from poetry.packages import DependencyPackage if TYPE_CHECKING: + from packaging.utils import NormalizedName + from poetry.core.factory import DependencyConstraint from poetry.core.packages.project_package import ProjectPackage from poetry.repositories import Repository @@ -21,7 +22,7 @@ def add_to_repo( repository: Repository, name: str, version: str, - deps: dict[str, str] | None = None, + deps: dict[str, DependencyConstraint] | None = None, python: str | None = None, ) -> None: package = Package(name, version) @@ -41,32 +42,27 @@ def check_solver_result( result: dict[str, str] | None = None, error: str | None = None, tries: int | None = None, - locked: dict[str, Package] | None = None, - use_latest: list[str] | None = None, + use_latest: list[NormalizedName] | None = None, ) -> None: - if locked is not None: - locked = { - k: [DependencyPackage(l.to_dependency(), l)] for k, l in locked.items() - } - - solver = VersionSolver(root, provider, locked=locked, use_latest=use_latest) - try: - solution = solver.solve() - except SolveFailure as e: - if error: - assert str(e) == error - - if tries is not None: - assert solver.solution.attempted_solutions == tries - - return - - raise - except AssertionError as e: - if error: - assert str(e) == error - return - raise + solver = VersionSolver(root, provider) + with provider.use_latest_for(use_latest or []): + try: + solution = solver.solve() + except SolveFailure as e: + if error: + assert str(e) == error + + if tries is not None: + assert solver.solution.attempted_solutions == tries + + return + + raise + except AssertionError as e: + if error: + assert str(e) == error + return + raise packages = {} for package in solution.packages: diff --git a/tests/mixology/version_solver/test_with_lock.py b/tests/mixology/version_solver/test_with_lock.py index e9d07d21d7b..15519b8fb02 100644 --- a/tests/mixology/version_solver/test_with_lock.py +++ b/tests/mixology/version_solver/test_with_lock.py @@ -2,21 +2,25 @@ from typing import TYPE_CHECKING +from cleo.io.null_io import NullIO +from packaging.utils import canonicalize_name + from poetry.factory import Factory from tests.helpers import get_package from tests.mixology.helpers import add_to_repo from tests.mixology.helpers import check_solver_result +from tests.mixology.version_solver.conftest import Provider if TYPE_CHECKING: from poetry.core.packages.project_package import ProjectPackage + from poetry.repositories import Pool from poetry.repositories import Repository - from tests.mixology.version_solver.conftest import Provider def test_with_compatible_locked_dependencies( - root: ProjectPackage, provider: Provider, repo: Repository + root: ProjectPackage, repo: Repository, pool: Pool ): root.add_dependency(Factory.create_dependency("foo", "*")) @@ -27,16 +31,18 @@ def test_with_compatible_locked_dependencies( add_to_repo(repo, "bar", "1.0.1") add_to_repo(repo, "bar", "1.0.2") + locked = [get_package("foo", "1.0.1"), get_package("bar", "1.0.1")] + provider = Provider(root, pool, NullIO(), locked=locked) + check_solver_result( root, provider, result={"foo": "1.0.1", "bar": "1.0.1"}, - locked={"foo": get_package("foo", "1.0.1"), "bar": get_package("bar", "1.0.1")}, ) def test_with_incompatible_locked_dependencies( - root: ProjectPackage, provider: Provider, repo: Repository + root: ProjectPackage, repo: Repository, pool: Pool ): root.add_dependency(Factory.create_dependency("foo", ">1.0.1")) @@ -47,16 +53,18 @@ def test_with_incompatible_locked_dependencies( add_to_repo(repo, "bar", "1.0.1") add_to_repo(repo, "bar", "1.0.2") + locked = [get_package("foo", "1.0.1"), get_package("bar", "1.0.1")] + provider = Provider(root, pool, NullIO(), locked=locked) + check_solver_result( root, provider, result={"foo": "1.0.2", "bar": "1.0.2"}, - locked={"foo": get_package("foo", "1.0.1"), "bar": get_package("bar", "1.0.1")}, ) def test_with_unrelated_locked_dependencies( - root: ProjectPackage, provider: Provider, repo: Repository + root: ProjectPackage, repo: Repository, pool: Pool ): root.add_dependency(Factory.create_dependency("foo", "*")) @@ -68,16 +76,18 @@ def test_with_unrelated_locked_dependencies( add_to_repo(repo, "bar", "1.0.2") add_to_repo(repo, "baz", "1.0.0") + locked = [get_package("baz", "1.0.1")] + provider = Provider(root, pool, NullIO(), locked=locked) + check_solver_result( root, provider, result={"foo": "1.0.2", "bar": "1.0.2"}, - locked={"baz": get_package("baz", "1.0.1")}, ) def test_unlocks_dependencies_if_necessary_to_ensure_that_a_new_dependency_is_satisfied( - root: ProjectPackage, provider: Provider, repo: Repository + root: ProjectPackage, repo: Repository, pool: Pool ): root.add_dependency(Factory.create_dependency("foo", "*")) root.add_dependency(Factory.create_dependency("newdep", "2.0.0")) @@ -92,6 +102,14 @@ def test_unlocks_dependencies_if_necessary_to_ensure_that_a_new_dependency_is_sa add_to_repo(repo, "qux", "2.0.0") add_to_repo(repo, "newdep", "2.0.0", deps={"baz": ">=1.5.0"}) + locked = [ + get_package("foo", "2.0.0"), + get_package("bar", "1.0.0"), + get_package("baz", "1.0.0"), + get_package("qux", "1.0.0"), + ] + provider = Provider(root, pool, NullIO(), locked=locked) + check_solver_result( root, provider, @@ -102,17 +120,11 @@ def test_unlocks_dependencies_if_necessary_to_ensure_that_a_new_dependency_is_sa "qux": "1.0.0", "newdep": "2.0.0", }, - locked={ - "foo": get_package("foo", "2.0.0"), - "bar": get_package("bar", "1.0.0"), - "baz": get_package("baz", "1.0.0"), - "qux": get_package("qux", "1.0.0"), - }, ) def test_with_compatible_locked_dependencies_use_latest( - root: ProjectPackage, provider: Provider, repo: Repository + root: ProjectPackage, repo: Repository, pool: Pool ): root.add_dependency(Factory.create_dependency("foo", "*")) root.add_dependency(Factory.create_dependency("baz", "*")) @@ -126,21 +138,23 @@ def test_with_compatible_locked_dependencies_use_latest( add_to_repo(repo, "baz", "1.0.0") add_to_repo(repo, "baz", "1.0.1") + locked = [ + get_package("foo", "1.0.1"), + get_package("bar", "1.0.1"), + get_package("baz", "1.0.0"), + ] + provider = Provider(root, pool, NullIO(), locked=locked) + check_solver_result( root, provider, result={"foo": "1.0.2", "bar": "1.0.2", "baz": "1.0.0"}, - locked={ - "foo": get_package("foo", "1.0.1"), - "bar": get_package("bar", "1.0.1"), - "baz": get_package("baz", "1.0.0"), - }, - use_latest=["foo"], + use_latest=[canonicalize_name("foo")], ) def test_with_compatible_locked_dependencies_with_extras( - root: ProjectPackage, provider: Provider, repo: Repository + root: ProjectPackage, repo: Repository, pool: Pool ): root.add_dependency(Factory.create_dependency("foo", "^1.0")) @@ -159,13 +173,15 @@ def test_with_compatible_locked_dependencies_with_extras( add_to_repo(repo, "baz", "1.0.0") add_to_repo(repo, "baz", "1.0.1") + locked = [ + get_package("foo", "1.0.0"), + get_package("bar", "1.0.0"), + get_package("baz", "1.0.0"), + ] + provider = Provider(root, pool, NullIO(), locked=locked) + check_solver_result( root, provider, result={"foo": "1.0.0", "bar": "1.0.0", "baz": "1.0.0"}, - locked={ - "foo": get_package("foo", "1.0.0"), - "bar": get_package("bar", "1.0.0"), - "baz": get_package("baz", "1.0.0"), - }, ) diff --git a/tests/puzzle/test_solver.py b/tests/puzzle/test_solver.py index a71206b7780..e18c1202c50 100644 --- a/tests/puzzle/test_solver.py +++ b/tests/puzzle/test_solver.py @@ -7,6 +7,7 @@ import pytest from cleo.io.null_io import NullIO +from packaging.utils import canonicalize_name from poetry.core.packages.dependency import Dependency from poetry.core.packages.package import Package from poetry.core.packages.project_package import ProjectPackage @@ -17,7 +18,6 @@ from poetry.packages import DependencyPackage from poetry.puzzle import Solver from poetry.puzzle.exceptions import SolverProblemError -from poetry.repositories.installed_repository import InstalledRepository from poetry.repositories.pool import Pool from poetry.repositories.repository import Repository from poetry.utils.env import MockEnv @@ -58,16 +58,6 @@ def package() -> ProjectPackage: return ProjectPackage("root", "1.0") -@pytest.fixture() -def installed() -> InstalledRepository: - return InstalledRepository() - - -@pytest.fixture() -def locked() -> Repository: - return Repository("locked") - - @pytest.fixture() def repo() -> Repository: return Repository("repo") @@ -79,14 +69,8 @@ def pool(repo: Repository) -> Pool: @pytest.fixture() -def solver( - package: ProjectPackage, - pool: Pool, - installed: InstalledRepository, - locked: Repository, - io: NullIO, -) -> Solver: - return Solver(package, pool, installed.packages, locked.packages, io) +def solver(package: ProjectPackage, pool: Pool, io: NullIO) -> Solver: + return Solver(package, pool, [], [], io) def check_solver_result( @@ -130,32 +114,30 @@ def test_solver_install_single( package_a = get_package("A", "1.0") repo.add_package(package_a) - transaction = solver.solve([get_dependency("A")]) + transaction = solver.solve([get_dependency("A").name]) check_solver_result(transaction, [{"job": "install", "package": package_a}]) def test_solver_remove_if_no_longer_locked( - solver: Solver, locked: Repository, installed: InstalledRepository + package: ProjectPackage, pool: Pool, io: NullIO ): package_a = get_package("A", "1.0") - installed.add_package(package_a) - locked.add_package(package_a) + solver = Solver(package, pool, [package_a], [package_a], io) transaction = solver.solve() check_solver_result(transaction, [{"job": "remove", "package": package_a}]) -def test_remove_non_installed(solver: Solver, repo: Repository, locked: Repository): +def test_remove_non_installed( + package: ProjectPackage, repo: Repository, pool: Pool, io: NullIO +): package_a = get_package("A", "1.0") - locked.add_package(package_a) - repo.add_package(package_a) - request = [] - - transaction = solver.solve(request) + solver = Solver(package, pool, [], [package_a], io) + transaction = solver.solve([]) check_solver_result(transaction, []) @@ -173,10 +155,7 @@ def test_install_non_existing_package_fail( def test_install_unpublished_package_does_not_fail( - installed: InstalledRepository, - solver: Solver, - repo: Repository, - package: ProjectPackage, + package: ProjectPackage, repo: Repository, pool: Pool, io: NullIO ): package.add_dependency(Factory.create_dependency("B", "1")) @@ -185,8 +164,8 @@ def test_install_unpublished_package_does_not_fail( package_b.add_dependency(Factory.create_dependency("A", "1.0")) repo.add_package(package_a) - installed.add_package(package_b) + solver = Solver(package, pool, [package_b], [], io) transaction = solver.solve() check_solver_result( @@ -288,17 +267,14 @@ def test_install_with_deps_in_order( def test_install_installed( - solver: Solver, - repo: Repository, - installed: InstalledRepository, - package: ProjectPackage, + package: ProjectPackage, repo: Repository, pool: Pool, io: NullIO ): package.add_dependency(Factory.create_dependency("A", "*")) package_a = get_package("A", "1.0") - installed.add_package(package_a) repo.add_package(package_a) + solver = Solver(package, pool, [package_a], [], io) transaction = solver.solve() check_solver_result( @@ -307,20 +283,16 @@ def test_install_installed( def test_update_installed( - solver: Solver, - repo: Repository, - installed: InstalledRepository, - package: ProjectPackage, + package: ProjectPackage, repo: Repository, pool: Pool, io: NullIO ): package.add_dependency(Factory.create_dependency("A", "*")) - installed.add_package(get_package("A", "1.0")) - package_a = get_package("A", "1.0") new_package_a = get_package("A", "1.1") repo.add_package(package_a) repo.add_package(new_package_a) + solver = Solver(package, pool, [get_package("A", "1.0")], [], io) transaction = solver.solve() check_solver_result( @@ -329,17 +301,11 @@ def test_update_installed( def test_update_with_use_latest( - solver: Solver, - repo: Repository, - installed: InstalledRepository, - package: ProjectPackage, - locked: Repository, + package: ProjectPackage, repo: Repository, pool: Pool, io: NullIO ): package.add_dependency(Factory.create_dependency("A", "*")) package.add_dependency(Factory.create_dependency("B", "*")) - installed.add_package(get_package("A", "1.0")) - package_a = get_package("A", "1.0") new_package_a = get_package("A", "1.1") package_b = get_package("B", "1.0") @@ -349,9 +315,10 @@ def test_update_with_use_latest( repo.add_package(package_b) repo.add_package(new_package_b) - locked.add_package(package_a) - locked.add_package(package_b) + installed = [get_package("A", "1.0")] + locked = [package_a, package_b] + solver = Solver(package, pool, installed, locked, io) transaction = solver.solve(use_latest=[package_b.name]) check_solver_result( @@ -976,7 +943,7 @@ def test_solver_sub_dependencies_with_requirements_complex( def test_solver_sub_dependencies_with_not_supported_python_version( - solver: Solver, repo: Repository, package: Package + solver: Solver, repo: Repository, package: ProjectPackage ): set_package_python_versions(solver.provider, "^3.5") package.add_dependency(Factory.create_dependency("A", "*")) @@ -998,7 +965,7 @@ def test_solver_sub_dependencies_with_not_supported_python_version( def test_solver_sub_dependencies_with_not_supported_python_version_transitive( - solver: Solver, repo: Repository, package: Package + solver: Solver, repo: Repository, package: ProjectPackage ): set_package_python_versions(solver.provider, "^3.4") @@ -1042,7 +1009,7 @@ def test_solver_sub_dependencies_with_not_supported_python_version_transitive( def test_solver_with_dependency_in_both_main_and_dev_dependencies( - solver: Solver, repo: Repository, package: Package + solver: Solver, repo: Repository, package: ProjectPackage ): set_package_python_versions(solver.provider, "^3.5") package.add_dependency(Factory.create_dependency("A", "*")) @@ -1095,7 +1062,7 @@ def test_solver_with_dependency_in_both_main_and_dev_dependencies( def test_solver_with_dependency_in_both_main_and_dev_dependencies_with_one_more_dependent( # noqa: E501 - solver: Solver, repo: Repository, package: Package + solver: Solver, repo: Repository, package: ProjectPackage ): package.add_dependency(Factory.create_dependency("A", "*")) package.add_dependency(Factory.create_dependency("E", "*")) @@ -1335,7 +1302,7 @@ def test_solver_duplicate_dependencies_different_constraints( def test_solver_duplicate_dependencies_different_constraints_same_requirements( - solver: Solver, repo: Repository, package: Package + solver: Solver, repo: Repository, package: ProjectPackage ): package.add_dependency(Factory.create_dependency("A", "*")) @@ -1362,7 +1329,7 @@ def test_solver_duplicate_dependencies_different_constraints_same_requirements( def test_solver_duplicate_dependencies_different_constraints_merge_by_marker( - solver: Solver, repo: Repository, package: Package + solver: Solver, repo: Repository, package: ProjectPackage ): package.add_dependency(Factory.create_dependency("A", "*")) @@ -1399,7 +1366,7 @@ def test_solver_duplicate_dependencies_different_constraints_merge_by_marker( def test_solver_duplicate_dependencies_different_sources_types_are_preserved( - solver: Solver, repo: Repository, package: Package + solver: Solver, repo: Repository, package: ProjectPackage ): pendulum = get_package("pendulum", "2.0.3") repo.add_package(pendulum) @@ -1460,7 +1427,7 @@ def test_solver_duplicate_dependencies_different_sources_types_are_preserved( def test_solver_duplicate_dependencies_different_constraints_merge_no_markers( - solver: Solver, repo: Repository, package: Package + solver: Solver, repo: Repository, package: ProjectPackage ): package.add_dependency(Factory.create_dependency("A", "*")) package.add_dependency(Factory.create_dependency("B", "1.0")) @@ -1503,7 +1470,7 @@ def test_solver_duplicate_dependencies_different_constraints_merge_no_markers( def test_solver_duplicate_dependencies_ignore_overrides_with_empty_marker_intersection( - solver: Solver, repo: Repository, package: Package + solver: Solver, repo: Repository, package: ProjectPackage ): """ Distinct requirements per marker: @@ -1574,7 +1541,7 @@ def test_solver_duplicate_dependencies_ignore_overrides_with_empty_marker_inters def test_solver_duplicate_dependencies_ignore_overrides_with_empty_marker_intersection2( - solver: Solver, repo: Repository, package: Package + solver: Solver, repo: Repository, package: ProjectPackage ): """ Empty intersection between top level dependency and transient dependency. @@ -1728,7 +1695,7 @@ def test_solver_fails_if_dependency_name_does_not_match_package( def test_solver_does_not_get_stuck_in_recursion_on_circular_dependency( - solver: Solver, repo: Repository, package: Package + solver: Solver, repo: Repository, package: ProjectPackage ): package_a = get_package("A", "1.0") package_a.add_dependency(Factory.create_dependency("B", "^1.0")) @@ -1831,7 +1798,7 @@ def test_solver_can_resolve_git_dependencies_with_extras( ids=["branch", "tag", "rev"], ) def test_solver_can_resolve_git_dependencies_with_ref( - solver: Solver, repo: Repository, package: Package, ref: dict[str, str] + solver: Solver, repo: Repository, package: ProjectPackage, ref: dict[str, str] ): pendulum = get_package("pendulum", "2.0.3") cleo = get_package("cleo", "1.0.0") @@ -1866,7 +1833,7 @@ def test_solver_can_resolve_git_dependencies_with_ref( def test_solver_does_not_trigger_conflict_for_python_constraint_if_python_requirement_is_compatible( # noqa: E501 - solver: Solver, repo: Repository, package: Package + solver: Solver, repo: Repository, package: ProjectPackage ): set_package_python_versions(solver.provider, "~2.7 || ^3.4") package.add_dependency( @@ -1884,7 +1851,7 @@ def test_solver_does_not_trigger_conflict_for_python_constraint_if_python_requir def test_solver_does_not_trigger_conflict_for_python_constraint_if_python_requirement_is_compatible_multiple( # noqa: E501 - solver: Solver, repo: Repository, package: Package + solver: Solver, repo: Repository, package: ProjectPackage ): set_package_python_versions(solver.provider, "~2.7 || ^3.4") package.add_dependency( @@ -1916,7 +1883,7 @@ def test_solver_does_not_trigger_conflict_for_python_constraint_if_python_requir def test_solver_triggers_conflict_for_dependency_python_not_fully_compatible_with_package_python( # noqa: E501 - solver: Solver, repo: Repository, package: Package + solver: Solver, repo: Repository, package: ProjectPackage ): set_package_python_versions(solver.provider, "~2.7 || ^3.4") package.add_dependency( @@ -1933,7 +1900,7 @@ def test_solver_triggers_conflict_for_dependency_python_not_fully_compatible_wit def test_solver_finds_compatible_package_for_dependency_python_not_fully_compatible_with_package_python( # noqa: E501 - solver: Solver, repo: Repository, package: Package + solver: Solver, repo: Repository, package: ProjectPackage ): set_package_python_versions(solver.provider, "~2.7 || ^3.4") package.add_dependency( @@ -1955,7 +1922,7 @@ def test_solver_finds_compatible_package_for_dependency_python_not_fully_compati def test_solver_does_not_trigger_new_resolution_on_duplicate_dependencies_if_only_extras( # noqa: E501 - solver: Solver, repo: Repository, package: Package + solver: Solver, repo: Repository, package: ProjectPackage ): dep1 = Dependency.create_from_pep_508('B (>=1.0); extra == "foo"') dep1.activate() @@ -1993,7 +1960,7 @@ def test_solver_does_not_trigger_new_resolution_on_duplicate_dependencies_if_onl def test_solver_does_not_raise_conflict_for_locked_conditional_dependencies( - solver: Solver, repo: Repository, package: Package + solver: Solver, repo: Repository, package: ProjectPackage ): set_package_python_versions(solver.provider, "~2.7 || ^3.4") package.add_dependency( @@ -2025,7 +1992,7 @@ def test_solver_does_not_raise_conflict_for_locked_conditional_dependencies( def test_solver_returns_extras_if_requested_in_dependencies_and_not_in_root_package( - solver: Solver, repo: Repository, package: Package + solver: Solver, repo: Repository, package: ProjectPackage ): package.add_dependency(Factory.create_dependency("A", "*")) package.add_dependency(Factory.create_dependency("B", "*")) @@ -2064,7 +2031,7 @@ def test_solver_returns_extras_if_requested_in_dependencies_and_not_in_root_pack def test_solver_should_not_resolve_prerelease_version_if_not_requested( - solver: Solver, repo: Repository, package: Package + solver: Solver, repo: Repository, package: ProjectPackage ): package.add_dependency(Factory.create_dependency("A", "~1.8.0")) package.add_dependency(Factory.create_dependency("B", "^0.5.0")) @@ -2083,7 +2050,7 @@ def test_solver_should_not_resolve_prerelease_version_if_not_requested( def test_solver_ignores_dependencies_with_incompatible_python_full_version_marker( - solver: Solver, repo: Repository, package: Package + solver: Solver, repo: Repository, package: ProjectPackage ): set_package_python_versions(solver.provider, "^3.6") package.add_dependency(Factory.create_dependency("A", "^1.0")) @@ -2116,7 +2083,7 @@ def test_solver_ignores_dependencies_with_incompatible_python_full_version_marke def test_solver_git_dependencies_update( - solver: Solver, repo: Repository, package: Package, installed: InstalledRepository + package: ProjectPackage, repo: Repository, pool: Pool, io: NullIO ): pendulum = get_package("pendulum", "2.0.3") cleo = get_package("cleo", "1.0.0") @@ -2139,12 +2106,12 @@ def test_solver_git_dependencies_update( source_reference=DEFAULT_SOURCE_REF, source_resolved_reference=MOCK_DEFAULT_GIT_REVISION, ) - installed.add_package(demo_installed) package.add_dependency( Factory.create_dependency("demo", {"git": "https://github.com/demo/demo.git"}) ) + solver = Solver(package, pool, [demo_installed], [], io) transaction = solver.solve() ops = check_solver_result( @@ -2165,7 +2132,7 @@ def test_solver_git_dependencies_update( def test_solver_git_dependencies_update_skipped( - solver: Solver, repo: Repository, package: Package, installed: InstalledRepository + package: ProjectPackage, repo: Repository, pool: Pool, io: NullIO ): pendulum = get_package("pendulum", "2.0.3") cleo = get_package("cleo", "1.0.0") @@ -2180,12 +2147,12 @@ def test_solver_git_dependencies_update_skipped( source_reference="master", source_resolved_reference=MOCK_DEFAULT_GIT_REVISION, ) - installed.add_package(demo) package.add_dependency( Factory.create_dependency("demo", {"git": "https://github.com/demo/demo.git"}) ) + solver = Solver(package, pool, [demo], [], io) transaction = solver.solve() check_solver_result( @@ -2198,7 +2165,7 @@ def test_solver_git_dependencies_update_skipped( def test_solver_git_dependencies_short_hash_update_skipped( - solver: Solver, repo: Repository, package: Package, installed: InstalledRepository + package: ProjectPackage, repo: Repository, pool: Pool, io: NullIO ): pendulum = get_package("pendulum", "2.0.3") cleo = get_package("cleo", "1.0.0") @@ -2213,7 +2180,6 @@ def test_solver_git_dependencies_short_hash_update_skipped( source_reference=MOCK_DEFAULT_GIT_REVISION, source_resolved_reference=MOCK_DEFAULT_GIT_REVISION, ) - installed.add_package(demo) package.add_dependency( Factory.create_dependency( @@ -2221,6 +2187,7 @@ def test_solver_git_dependencies_short_hash_update_skipped( ) ) + solver = Solver(package, pool, [demo], [], io) transaction = solver.solve() check_solver_result( @@ -2280,15 +2247,13 @@ def test_solver_can_resolve_directory_dependencies( def test_solver_can_resolve_directory_dependencies_nested_editable( repo: Repository, pool: Pool, - installed: InstalledRepository, - locked: Repository, io: NullIO, ): base = Path(__file__).parent.parent / "fixtures" / "project_with_nested_local" poetry = Factory().create_poetry(cwd=base) package = poetry.package - solver = Solver(package, pool, installed.packages, locked.packages, io) + solver = Solver(package, pool, [], [], io) transaction = solver.solve() @@ -2520,15 +2485,12 @@ def test_solver_can_resolve_wheel_dependencies_with_extras( def test_solver_can_solve_with_legacy_repository_using_proper_dists( - package: ProjectPackage, - installed: InstalledRepository, - locked: Repository, - io: NullIO, + package: ProjectPackage, io: NullIO ): repo = MockLegacyRepository() pool = Pool([repo]) - solver = Solver(package, pool, installed.packages, locked.packages, io) + solver = Solver(package, pool, [], [], io) package.add_dependency(Factory.create_dependency("isort", "4.3.4")) @@ -2566,8 +2528,6 @@ def test_solver_can_solve_with_legacy_repository_using_proper_dists( def test_solver_can_solve_with_legacy_repository_using_proper_python_compatible_dists( package: ProjectPackage, - installed: InstalledRepository, - locked: Repository, io: NullIO, ): package.python_versions = "^3.7" @@ -2575,7 +2535,7 @@ def test_solver_can_solve_with_legacy_repository_using_proper_python_compatible_ repo = MockLegacyRepository() pool = Pool([repo]) - solver = Solver(package, pool, installed.packages, locked.packages, io) + solver = Solver(package, pool, [], [], io) package.add_dependency(Factory.create_dependency("isort", "4.3.4")) @@ -2598,18 +2558,13 @@ def test_solver_can_solve_with_legacy_repository_using_proper_python_compatible_ ) -def test_solver_skips_invalid_versions( - package: ProjectPackage, - installed: InstalledRepository, - locked: Repository, - io: NullIO, -): +def test_solver_skips_invalid_versions(package: ProjectPackage, io: NullIO): package.python_versions = "^3.7" repo = MockPyPIRepository() pool = Pool([repo]) - solver = Solver(package, pool, installed.packages, locked.packages, io) + solver = Solver(package, pool, [], [], io) package.add_dependency(Factory.create_dependency("trackpy", "^0.4")) @@ -2645,10 +2600,7 @@ def test_multiple_constraints_on_root( def test_solver_chooses_most_recent_version_amongst_repositories( - package: ProjectPackage, - installed: InstalledRepository, - locked: Repository, - io: NullIO, + package: ProjectPackage, io: NullIO ): package.python_versions = "^3.7" package.add_dependency(Factory.create_dependency("tomlkit", {"version": "^0.5"})) @@ -2656,7 +2608,7 @@ def test_solver_chooses_most_recent_version_amongst_repositories( repo = MockLegacyRepository() pool = Pool([repo, MockPyPIRepository()]) - solver = Solver(package, pool, installed.packages, locked.packages, io) + solver = Solver(package, pool, [], [], io) transaction = solver.solve() @@ -2669,10 +2621,7 @@ def test_solver_chooses_most_recent_version_amongst_repositories( def test_solver_chooses_from_correct_repository_if_forced( - package: ProjectPackage, - installed: InstalledRepository, - locked: Repository, - io: NullIO, + package: ProjectPackage, io: NullIO ): package.python_versions = "^3.7" package.add_dependency( @@ -2682,7 +2631,7 @@ def test_solver_chooses_from_correct_repository_if_forced( repo = MockLegacyRepository() pool = Pool([repo, MockPyPIRepository()]) - solver = Solver(package, pool, installed.packages, locked.packages, io) + solver = Solver(package, pool, [], [], io) transaction = solver.solve() @@ -2707,8 +2656,6 @@ def test_solver_chooses_from_correct_repository_if_forced( def test_solver_chooses_from_correct_repository_if_forced_and_transitive_dependency( package: ProjectPackage, - installed: InstalledRepository, - locked: Repository, io: NullIO, ): package.python_versions = "^3.7" @@ -2723,7 +2670,7 @@ def test_solver_chooses_from_correct_repository_if_forced_and_transitive_depende repo.add_package(foo) pool = Pool([MockLegacyRepository(), repo, MockPyPIRepository()]) - solver = Solver(package, pool, installed.packages, locked.packages, io) + solver = Solver(package, pool, [], [], io) transaction = solver.solve() @@ -2751,10 +2698,7 @@ def test_solver_chooses_from_correct_repository_if_forced_and_transitive_depende def test_solver_does_not_choose_from_secondary_repository_by_default( - package: ProjectPackage, - installed: InstalledRepository, - locked: Repository, - io: NullIO, + package: ProjectPackage, io: NullIO ): package.python_versions = "^3.7" package.add_dependency(Factory.create_dependency("clikit", {"version": "^0.2.0"})) @@ -2763,7 +2707,7 @@ def test_solver_does_not_choose_from_secondary_repository_by_default( pool.add_repository(MockPyPIRepository(), secondary=True) pool.add_repository(MockLegacyRepository()) - solver = Solver(package, pool, installed.packages, locked.packages, io) + solver = Solver(package, pool, [], [], io) transaction = solver.solve() @@ -2802,8 +2746,6 @@ def test_solver_does_not_choose_from_secondary_repository_by_default( def test_solver_chooses_from_secondary_if_explicit( package: ProjectPackage, - installed: InstalledRepository, - locked: Repository, io: NullIO, ): package.python_versions = "^3.7" @@ -2815,7 +2757,7 @@ def test_solver_chooses_from_secondary_if_explicit( pool.add_repository(MockPyPIRepository(), secondary=True) pool.add_repository(MockLegacyRepository()) - solver = Solver(package, pool, installed.packages, locked.packages, io) + solver = Solver(package, pool, [], [], io) transaction = solver.solve() @@ -2846,11 +2788,9 @@ def test_solver_chooses_from_secondary_if_explicit( def test_solver_discards_packages_with_empty_markers( package: ProjectPackage, - installed: InstalledRepository, - locked: Repository, - io: NullIO, - pool: Pool, repo: Repository, + pool: Pool, + io: NullIO, ): package.python_versions = "~2.7 || ^3.4" package.add_dependency( @@ -2872,7 +2812,7 @@ def test_solver_discards_packages_with_empty_markers( repo.add_package(package_b) repo.add_package(package_c) - solver = Solver(package, pool, installed.packages, locked.packages, io) + solver = Solver(package, pool, [], [], io) transaction = solver.solve() @@ -2886,7 +2826,7 @@ def test_solver_discards_packages_with_empty_markers( def test_solver_does_not_raise_conflict_for_conditional_dev_dependencies( - solver: Solver, repo: Repository, package: Package + solver: Solver, repo: Repository, package: ProjectPackage ): set_package_python_versions(solver.provider, "~2.7 || ^3.5") package.add_dependency( @@ -2918,7 +2858,7 @@ def test_solver_does_not_raise_conflict_for_conditional_dev_dependencies( def test_solver_does_not_loop_indefinitely_on_duplicate_constraints_with_extras( - solver: Solver, repo: Repository, package: Package + solver: Solver, repo: Repository, package: ProjectPackage ): set_package_python_versions(solver.provider, "~2.7 || ^3.5") package.add_dependency( @@ -2949,11 +2889,9 @@ def test_solver_does_not_loop_indefinitely_on_duplicate_constraints_with_extras( def test_solver_does_not_fail_with_locked_git_and_non_git_dependencies( + package: ProjectPackage, repo: Repository, - package: Package, - locked: Repository, pool: Pool, - installed: InstalledRepository, io: NullIO, ): package.add_dependency( @@ -2970,16 +2908,13 @@ def test_solver_does_not_fail_with_locked_git_and_non_git_dependencies( source_resolved_reference=MOCK_DEFAULT_GIT_REVISION, ) - installed.add_package(git_package) - - locked.add_package(get_package("a", "1.2.3")) - locked.add_package(git_package) - repo.add_package(get_package("a", "1.2.3")) repo.add_package(Package("pendulum", "2.1.2")) - solver = Solver(package, pool, installed.packages, locked.packages, io) + installed = [git_package] + locked = [get_package("a", "1.2.3"), git_package] + solver = Solver(package, pool, installed, locked, io) transaction = solver.solve() check_solver_result( @@ -3017,7 +2952,7 @@ def test_ignore_python_constraint_no_overlap_dependencies( def test_solver_should_not_go_into_an_infinite_loop_on_duplicate_dependencies( - solver: Solver, repo: Repository, package: Package + solver: Solver, repo: Repository, package: ProjectPackage ): set_package_python_versions(solver.provider, "~2.7 || ^3.5") package.add_dependency(Factory.create_dependency("A", "^1.0")) @@ -3049,17 +2984,10 @@ def test_solver_should_not_go_into_an_infinite_loop_on_duplicate_dependencies( ) -def test_solver_synchronize_single( - package: ProjectPackage, - pool: Pool, - installed: InstalledRepository, - locked: Repository, - io: NullIO, -): - solver = Solver(package, pool, installed.packages, locked.packages, io) +def test_solver_synchronize_single(package: ProjectPackage, pool: Pool, io: NullIO): package_a = get_package("a", "1.0") - installed.add_package(package_a) + solver = Solver(package, pool, [package_a], [], io) transaction = solver.solve() check_solver_result( @@ -3071,21 +2999,18 @@ def test_solver_synchronize_single( def test_solver_with_synchronization_keeps_critical_package( package: ProjectPackage, pool: Pool, - installed: InstalledRepository, - locked: Repository, io: NullIO, ): - solver = Solver(package, pool, installed.packages, locked.packages, io) package_pip = get_package("setuptools", "1.0") - installed.add_package(package_pip) + solver = Solver(package, pool, [package_pip], [], io) transaction = solver.solve() check_solver_result(transaction, []) def test_solver_cannot_choose_another_version_for_directory_dependencies( - solver: Solver, repo: Repository, package: Package + solver: Solver, repo: Repository, package: ProjectPackage ): pendulum = get_package("pendulum", "2.0.3") demo = get_package("demo", "0.1.0") @@ -3114,7 +3039,7 @@ def test_solver_cannot_choose_another_version_for_directory_dependencies( def test_solver_cannot_choose_another_version_for_file_dependencies( - solver: Solver, repo: Repository, package: Package + solver: Solver, repo: Repository, package: ProjectPackage ): pendulum = get_package("pendulum", "2.0.3") demo = get_package("demo", "0.0.8") @@ -3141,7 +3066,7 @@ def test_solver_cannot_choose_another_version_for_file_dependencies( def test_solver_cannot_choose_another_version_for_git_dependencies( - solver: Solver, repo: Repository, package: Package + solver: Solver, repo: Repository, package: ProjectPackage ): pendulum = get_package("pendulum", "2.0.3") demo = get_package("demo", "0.0.8") @@ -3165,7 +3090,7 @@ def test_solver_cannot_choose_another_version_for_git_dependencies( def test_solver_cannot_choose_another_version_for_url_dependencies( solver: Solver, repo: Repository, - package: Package, + package: ProjectPackage, http: type[httpretty.httpretty], ): path = ( @@ -3204,7 +3129,7 @@ def test_solver_cannot_choose_another_version_for_url_dependencies( def test_solver_should_not_update_same_version_packages_if_installed_has_no_source_type( - solver: Solver, repo: Repository, package: Package, installed: InstalledRepository + package: ProjectPackage, repo: Repository, pool: Pool, io: NullIO ): package.add_dependency(Factory.create_dependency("foo", "1.0.0")) @@ -3216,8 +3141,8 @@ def test_solver_should_not_update_same_version_packages_if_installed_has_no_sour source_reference="custom", ) repo.add_package(foo) - installed.add_package(get_package("foo", "1.0.0")) + solver = Solver(package, pool, [get_package("foo", "1.0.0")], [], io) transaction = solver.solve() check_solver_result( @@ -3226,7 +3151,7 @@ def test_solver_should_not_update_same_version_packages_if_installed_has_no_sour def test_solver_should_use_the_python_constraint_from_the_environment_if_available( - solver: Solver, repo: Repository, package: Package, installed: InstalledRepository + solver: Solver, repo: Repository, package: ProjectPackage ): set_package_python_versions(solver.provider, "~2.7 || ^3.5") package.add_dependency(Factory.create_dependency("A", "^1.0")) @@ -3253,7 +3178,7 @@ def test_solver_should_use_the_python_constraint_from_the_environment_if_availab def test_solver_should_resolve_all_versions_for_multiple_duplicate_dependencies( - solver: Solver, repo: Repository, package: Package + solver: Solver, repo: Repository, package: ProjectPackage ): package.python_versions = "~2.7 || ^3.5" package.add_dependency( @@ -3301,7 +3226,7 @@ def test_solver_should_resolve_all_versions_for_multiple_duplicate_dependencies( def test_solver_should_not_raise_errors_for_irrelevant_python_constraints( - solver: Solver, repo: Repository, package: Package + solver: Solver, repo: Repository, package: ProjectPackage ): package.python_versions = "^3.6" set_package_python_versions(solver.provider, "^3.6") @@ -3394,7 +3319,7 @@ def test_solver_can_resolve_for_packages_with_missing_extras( def test_solver_can_resolve_python_restricted_package_dependencies( - solver: Solver, repo: Repository, package: Package, locked: Repository + package: ProjectPackage, repo: Repository, pool: Pool, io: NullIO ): package.add_dependency( Factory.create_dependency("futures", {"version": "^3.3.0", "python": "~2.7"}) @@ -3409,13 +3334,11 @@ def test_solver_can_resolve_python_restricted_package_dependencies( pre_commit = Package("pre-commit", "2.7.1") pre_commit.python_versions = ">=3.6.1" - locked.add_package(futures) - locked.add_package(pre_commit) - repo.add_package(futures) repo.add_package(pre_commit) - transaction = solver.solve(use_latest=["pre-commit"]) + solver = Solver(package, pool, [], [futures, pre_commit], io) + transaction = solver.solve(use_latest=[canonicalize_name("pre-commit")]) check_solver_result( transaction, @@ -3427,7 +3350,7 @@ def test_solver_can_resolve_python_restricted_package_dependencies( def test_solver_should_not_raise_errors_for_irrelevant_transitive_python_constraints( - solver: Solver, repo: Repository, package: Package + solver: Solver, repo: Repository, package: ProjectPackage ): package.python_versions = "~2.7 || ^3.5" set_package_python_versions(solver.provider, "~2.7 || ^3.5") @@ -3478,13 +3401,12 @@ def test_solver_should_not_raise_errors_for_irrelevant_transitive_python_constra @pytest.mark.parametrize("is_locked", [False, True]) def test_solver_keeps_multiple_locked_dependencies_for_same_package( - solver: Solver, + package: ProjectPackage, repo: Repository, - package: Package, - locked: Repository, + pool: Pool, + io: NullIO, is_locked: bool, ): - set_package_python_versions(solver.provider, "^3.6") package.add_dependency( Factory.create_dependency("A", {"version": "~1.1", "python": "<3.7"}) ) @@ -3510,13 +3432,14 @@ def test_solver_keeps_multiple_locked_dependencies_for_same_package( if is_locked: a11_locked = a11.clone() a11_locked.python_versions = "<3.7" - locked.add_package(a11_locked) a12_locked = a12.clone() a12_locked.python_versions = ">=3.7" - locked.add_package(a12_locked) - locked.add_package(b03.clone()) - locked.add_package(b04.clone()) + locked = [a11_locked, a12_locked, b03.clone(), b04.clone()] + else: + locked = [] + solver = Solver(package, pool, [], locked, io) + set_package_python_versions(solver.provider, "^3.6") transaction = solver.solve() check_solver_result( @@ -3635,21 +3558,14 @@ def test_solver_incompatible_dependency_with_and_without_extras( def test_update_with_prerelease_and_no_solution( - solver: Solver, - repo: Repository, - installed: InstalledRepository, - package: ProjectPackage, - locked: Repository, + package: ProjectPackage, repo: Repository, pool: Pool, io: NullIO ): # Locked and installed: cleo which depends on an old version of crashtest. cleo = get_package("cleo", "1.0.0a5") crashtest = get_package("crashtest", "0.3.0") cleo.add_dependency(Factory.create_dependency("crashtest", {"version": "<0.4.0"})) - locked.add_package(cleo) - locked.add_package(crashtest) - - installed.add_package(cleo) - installed.add_package(crashtest) + installed = [cleo, crashtest] + locked = [cleo, crashtest] # Try to upgrade to a new version of crashtest, this will be disallowed by the # dependency from cleo. @@ -3663,5 +3579,7 @@ def test_update_with_prerelease_and_no_solution( repo.add_package(newer_crashtest) repo.add_package(even_newer_crashtest) + solver = Solver(package, pool, installed, locked, io) + with pytest.raises(SolverProblemError): solver.solve()