diff --git a/src/poetry/mixology/version_solver.py b/src/poetry/mixology/version_solver.py index c1e7a4d3bae..4999a35fd9b 100644 --- a/src/poetry/mixology/version_solver.py +++ b/src/poetry/mixology/version_solver.py @@ -96,9 +96,10 @@ def __init__(self, root: ProjectPackage, provider: Provider) -> None: self._provider = provider self._dependency_cache = DependencyCache(provider) self._incompatibilities: dict[str, list[Incompatibility]] = {} - self._contradicted_incompatibilities: dict[int, set[Incompatibility]] = ( - collections.defaultdict(set) - ) + self._contradicted_incompatibilities: set[Incompatibility] = set() + self._contradicted_incompatibilities_by_level: dict[ + int, set[Incompatibility] + ] = collections.defaultdict(set) self._solution = PartialSolution() @property @@ -147,10 +148,7 @@ def _propagate(self, package: str) -> None: # we can derive stronger assignments sooner and more eagerly find # conflicts. for incompatibility in reversed(self._incompatibilities[package]): - if any( - incompatibility in c - for c in self._contradicted_incompatibilities.values() - ): + if incompatibility in self._contradicted_incompatibilities: continue result = self._propagate_incompatibility(incompatibility) @@ -199,9 +197,10 @@ def _propagate_incompatibility( # If term is already contradicted by _solution, then # incompatibility is contradicted as well and there's nothing new we # can deduce from it. - self._contradicted_incompatibilities[self._solution.decision_level].add( - incompatibility - ) + self._contradicted_incompatibilities.add(incompatibility) + self._contradicted_incompatibilities_by_level[ + self._solution.decision_level + ].add(incompatibility) return None elif relation == SetRelation.OVERLAPPING: # If more than one term is inconclusive, we can't deduce anything about @@ -219,9 +218,10 @@ def _propagate_incompatibility( if unsatisfied is None: return _conflict - self._contradicted_incompatibilities[self._solution.decision_level].add( - incompatibility - ) + self._contradicted_incompatibilities.add(incompatibility) + self._contradicted_incompatibilities_by_level[ + self._solution.decision_level + ].add(incompatibility) adverb = "not " if unsatisfied.is_positive() else "" self._log(f"derived: {adverb}{unsatisfied.dependency}") @@ -318,7 +318,9 @@ def _resolve_conflict(self, incompatibility: Incompatibility) -> Incompatibility for level in range( self._solution.decision_level, previous_satisfier_level, -1 ): - self._contradicted_incompatibilities.pop(level, None) + self._contradicted_incompatibilities.difference_update( + self._contradicted_incompatibilities_by_level.pop(level, set()), + ) self._dependency_cache.clear_level(level) self._solution.backtrack(previous_satisfier_level)