Commit f317b003 by Sébastien Eustace

Improve dependency resolution debugging

parent 92d0eddf
......@@ -4,6 +4,9 @@ from typing import Any
from typing import Dict
from typing import List
from poetry.packages import Dependency
from poetry.packages import Package
from .assignment import Assignment
from .incompatibility import Incompatibility
from .set_relation import SetRelation
......@@ -25,7 +28,7 @@ class PartialSolution:
self._assignments = [] # type: List[Assignment]
# The decisions made for each package.
self._decisions = OrderedDict() # type: Dict[str, Any]
self._decisions = OrderedDict() # type: Dict[str, Package]
# The intersection of all positive Assignments for each package, minus any
# negative Assignments that refer to that package.
......@@ -33,38 +36,41 @@ class PartialSolution:
# This is derived from self._assignments.
self._positive = OrderedDict() # type: Dict[str, Term]
# The union of all negative [Assignment]s for each package.
# The union of all negative Assignments for each package.
#
# If a package has any positive [Assignment]s, it doesn't appear in this
# If a package has any positive Assignments, it doesn't appear in this
# map.
#
# This is derived from self._assignments.
self._negative = OrderedDict() # type: Dict[str, Dict[str, Term]]
# The number of distinct solutions that have been attempted so far.
self._attempted_solutions = 1
# Whether the solver is currently backtracking.
self._backtracking = False
@property
def decisions(self): # type: () -> Any
def decisions(self): # type: () -> List[Package]
return list(self._decisions.values())
@property
def decision_level(self):
def decision_level(self): # type: () -> int
return len(self._decisions)
@property
def attempted_solutions(self):
def attempted_solutions(self): # type: () -> int
return self._attempted_solutions
@property
def unsatisfied(self):
def unsatisfied(self): # type: () -> List[Dependency]
return [
term.dependency
for term in self._positive.values()
if term.dependency.name not in self._decisions
]
def decide(self, package): # type: (Any) -> None
def decide(self, package): # type: (Package) -> None
"""
Adds an assignment of package as a decision
and increments the decision level.
......@@ -82,7 +88,7 @@ class PartialSolution:
self._assign(Assignment.decision(package, self.decision_level, len(self._assignments)))
def derive(self, dependency, is_positive, cause
): # type: (Any, bool, Incompatibility) -> None
): # type: (Dependency, bool, Incompatibility) -> None
"""
Adds an assignment of package as a derivation.
"""
......@@ -101,6 +107,10 @@ class PartialSolution:
self._register(assignment)
def backtrack(self, decision_level): # type: (int) -> None
"""
Resets the current decision level to decision_level, and removes all
assignments made after that level.
"""
self._backtracking = True
packages = set()
......
# -*- coding: utf-8 -*-
from typing import Union
from poetry.packages import Dependency
from .set_relation import SetRelation
......@@ -8,9 +10,14 @@ class Term(object):
"""
A statement about a package which is true or false for a given selection of
package versions.
See https://github.com/dart-lang/pub/tree/master/doc/solver.md#term.
"""
def __init__(self, dependency, is_positive):
def __init__(self,
dependency, # type: Dependency
is_positive # type: bool
):
self._dependency = dependency
self._positive = is_positive
......@@ -100,7 +107,7 @@ class Term(object):
# not foo ^1.5.0 is a superset of not foo ^1.0.0
return SetRelation.OVERLAPPING
def intersect(self, other): # type: (Term) -> Term
def intersect(self, other): # type: (Term) -> Union[Term, None]
"""
Returns a Term that represents the packages
allowed by both this term and another
......
......@@ -363,7 +363,7 @@ class Provider:
if self.is_debugging():
debug_info = str(message)
debug_info = '\n'.join([
'<comment>:{}:</> {}'.format(str(depth).rjust(4), s)
'<comment>{}:</> {}'.format(str(depth).rjust(4), s)
for s in debug_info.split('\n')
]) + '\n'
......
......@@ -257,6 +257,8 @@ class PyPiRepository(Repository):
)
def _get_release_info(self, name, version): # type: (str, str) -> dict
self._log('Getting info for {} ({}) from PyPI'.format(name, version), 'debug')
json_data = self._get('pypi/{}/{}/json'.format(name, version))
if json_data is None:
raise ValueError('Package [{}] not found.'.format(name))
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment