def test_candidate_inconsistent_error(): requirement = "foo" candidate = "bar" class Provider(AbstractProvider): def identify(self, d): assert d is requirement or d is candidate return d def get_preference(self, *_): return 0 def get_dependencies(self, _): return [] def find_matches(self, rs): assert len(rs) == 1 and rs[0] is requirement return [candidate] def is_satisfied_by(self, r, c): assert r is requirement assert c is candidate return False resolver = Resolver(Provider(), BaseReporter()) with pytest.raises(InconsistentCandidate) as ctx: resolver.resolve([requirement]) assert str(ctx.value) == "Provided candidate 'bar' does not satisfy 'foo'" assert ctx.value.candidate is candidate assert list(ctx.value.criterion.iter_requirement()) == [requirement]
def run_resolver(*args): reporter = Reporter() resolver = Resolver(Provider(), reporter) try: resolver.resolve(*args) return reporter.backtracking_causes except ResolutionImpossible as e: return e.causes
def test_resolver(provider, base_reporter): resolver = Resolver(provider, base_reporter) if provider.expected_conflicts: with pytest.raises(ResolutionImpossible) as ctx: result = resolver.resolve(provider.root_requirements) print(_format_resolution(result)) # Provide some debugging hints. assert _format_conflicts(ctx.value) == provider.expected_conflicts else: result = resolver.resolve(provider.root_requirements) assert _format_resolution(result) == provider.expected_resolution
def main(reqs): # Things I want to resolve. requirements = [Requirement(r) for r in reqs] provider = Provider() reporter = Reporter() # Create the (reusable) resolver. resolver = Resolver(provider, reporter) # Kick off the resolution process, and get the final result. result = resolver.resolve(requirements) display_resolution(result)
def test_candidate_depends_on_requirements_of_same_identifier(specifiers): # This test ensures if a candidate has multiple dependencies under the same # identifier, all dependencies of that identifier are correctly pulled in. # The parametrization ensures both requirement ordering work. # Parent depends on child twice, one allows v2, the other does not. # Each candidate is a 3-tuple (name, version, dependencies). # Each requirement is a 2-tuple (name, allowed_versions). # Candidate v2 is in from so it is preferred when both are allowed. all_candidates = { "parent": [("parent", "1", [("child", s) for s in specifiers])], "child": [("child", "2", []), ("child", "1", [])], } class Provider(AbstractProvider): def identify(self, requirement_or_candidate): return requirement_or_candidate[0] def get_preference(self, **_): return 0 def get_dependencies(self, candidate): return candidate[2] def find_matches(self, identifier, requirements, incompatibilities): assert not list(incompatibilities[identifier]) return (candidate for candidate in all_candidates[identifier] if all(candidate[1] in r[1] for r in requirements[identifier])) def is_satisfied_by(self, requirement, candidate): return candidate[1] in requirement[1] # Now when resolved, both requirements to child specified by parent should # be pulled, and the resolver should choose v1, not v2 (happens if the # v1-only requirement is dropped). resolver = Resolver(Provider(), BaseReporter()) result = resolver.resolve([("parent", {"1"})]) assert set(result.mapping) == {"parent", "child"} assert result.mapping["child"] == ("child", "1", [])
def main(): """Resolve requirements as project names on PyPI. The requirements are taken as command-line arguments and the resolution result will be printed to stdout. """ if len(sys.argv) == 1: print("Usage:", sys.argv[0], "<PyPI project name(s)>") return # Things I want to resolve. reqs = sys.argv[1:] requirements = [Requirement(r) for r in reqs] # Create the (reusable) resolver. provider = PyPIProvider() reporter = BaseReporter() resolver = Resolver(provider, reporter) # Kick off the resolution process, and get the final result. print("Resolving", ", ".join(reqs)) result = resolver.resolve(requirements) display_resolution(result)
def test_candidate_inconsistent_error(): requirement = "foo" candidate = "bar" class Provider(AbstractProvider): def __init__(self, requirement, candidate): self.requirement = requirement self.candidate = candidate def identify(self, requirement_or_candidate): assert requirement_or_candidate is self.requirement return requirement_or_candidate def get_preference(self, **_): return 0 def get_dependencies(self, **_): return [] def find_matches(self, identifier, requirements, incompatibilities): assert list(requirements[identifier]) == [self.requirement] assert next(incompatibilities[identifier], None) is None return [self.candidate] def is_satisfied_by(self, requirement, candidate): assert requirement is self.requirement assert candidate is self.candidate return False resolver = Resolver(Provider(requirement, candidate), BaseReporter()) with pytest.raises(InconsistentCandidate) as ctx: resolver.resolve([requirement]) assert str(ctx.value) == "Provided candidate 'bar' does not satisfy 'foo'" assert ctx.value.candidate is candidate assert list(ctx.value.criterion.iter_requirement()) == [requirement]
from pypi_wheel_provider import PyPIProvider, Requirement from visualization.generate import generate_html from visualization.reporter import GraphGeneratingReporter from resolvelib import Resolver if __name__ == "__main__": provider = PyPIProvider() reporter = GraphGeneratingReporter() resolver = Resolver(provider, reporter) reqs = [Requirement("oslo.utils==1.4.0")] try: resolver.resolve(reqs) finally: with open("out2.html", "w") as f: generate_html(reporter.evolution, f)
#collection_requirements = [Requirement('amazon.aws', '1.2.0', None, None)] #collection_requirements = [Requirement('amazon.aws', '1.2.1-dev3', None, None)] print() print('Given collection requirements:') #print(f'{collection_requirements=}') for abstract_req in collection_requirements: print(f'\t* {abstract_req.fqcn}\t"{abstract_req.ver}"') print() context.CLIARGS = { # patch a value normally populated by the CLI 'ignore_certs': False, 'type': 'collection', } galaxy_api = GalaxyAPI(Galaxy(), 'default_galaxy', C.GALAXY_SERVER) resolver = Resolver( AnsibleGalaxyProvider(api=galaxy_api), BaseReporter(), ) print() print('Computing the dependency tree...') print() concrete_requirements = resolver.resolve( collection_requirements, max_rounds=2_000_000, # avoid too deep backtracking; taken from pip ) print() print('Resolved concrete transitive dependencies:') #print(f'{concrete_requirements=}') #print(f'{concrete_requirements.mapping=}') for coll_name, concrete_pin in concrete_requirements.mapping.items(): print(f'\t* {coll_name}\t"{concrete_pin.ver}"') print()