def install_with_pip(prefix, index, specs): r = Resolve(index) for_conda = [] try: next(r.find_matches(MatchSpec('pip'))) except StopIteration: print("Pip not found, running `conda install pip` ...") try: install_package(prefix, 'pip') except Exception as e: print("Could not install pip --- continuing...") return specs for s in specs: try: next(r.find_matches(MatchSpec(s))) except StopIteration: if s == 'pip': for_conda.append(s) continue print("Conda package not available for %s, attempting to install " "via pip" % s) pip_install(prefix, s) else: for_conda.append(s) return for_conda
def test_circular_dependencies(): index2 = index.copy() index2['package1-1.0-0.tar.bz2'] = IndexRecord(**{ 'build': '0', 'build_number': 0, 'depends': ['package2'], 'name': 'package1', 'requires': ['package2'], 'version': '1.0', }) index2['package2-1.0-0.tar.bz2'] = IndexRecord(**{ 'build': '0', 'build_number': 0, 'depends': ['package1'], 'name': 'package2', 'requires': ['package1'], 'version': '1.0', }) index2 = {Dist(key): value for key, value in iteritems(index2)} r = Resolve(index2) assert set(r.find_matches(MatchSpec('package1'))) == { Dist('package1-1.0-0.tar.bz2'), } assert set(r.get_reduced_index(['package1']).keys()) == { Dist('package1-1.0-0.tar.bz2'), Dist('package2-1.0-0.tar.bz2'), } assert r.install(['package1']) == r.install(['package2']) == \ r.install(['package1', 'package2']) == [ Dist('package1-1.0-0.tar.bz2'), Dist('package2-1.0-0.tar.bz2'), ]
def test_circular_dependencies(): index2 = index.copy() index2["package1-1.0-0.tar.bz2"] = { "build": "0", "build_number": 0, "depends": ["package2"], "name": "package1", "requires": ["package2"], "version": "1.0", } index2["package2-1.0-0.tar.bz2"] = { "build": "0", "build_number": 0, "depends": ["package1"], "name": "package2", "requires": ["package1"], "version": "1.0", } r = Resolve(index2) assert set(r.find_matches(MatchSpec("package1"))) == {"package1-1.0-0.tar.bz2"} assert set(r.get_dists(["package1"]).keys()) == {"package1-1.0-0.tar.bz2", "package2-1.0-0.tar.bz2"} assert ( r.solve(["package1"]) == r.solve(["package2"]) == r.solve(["package1", "package2"]) == ["package1-1.0-0.tar.bz2", "package2-1.0-0.tar.bz2"] )
def test_circular_dependencies(): index2 = index.copy() index2['package1-1.0-0.tar.bz2'] = Record(**{ 'build': '0', 'build_number': 0, 'depends': ['package2'], 'name': 'package1', 'requires': ['package2'], 'version': '1.0', }) index2['package2-1.0-0.tar.bz2'] = Record(**{ 'build': '0', 'build_number': 0, 'depends': ['package1'], 'name': 'package2', 'requires': ['package1'], 'version': '1.0', }) index2 = {Dist(key): value for key, value in iteritems(index2)} r = Resolve(index2) assert set(r.find_matches(MatchSpec('package1'))) == { Dist('package1-1.0-0.tar.bz2'), } assert set(r.get_reduced_index(['package1']).keys()) == { Dist('package1-1.0-0.tar.bz2'), Dist('package2-1.0-0.tar.bz2'), } assert r.install(['package1']) == r.install(['package2']) == \ r.install(['package1', 'package2']) == [ Dist('package1-1.0-0.tar.bz2'), Dist('package2-1.0-0.tar.bz2'), ]
def test_circular_dependencies(): index2 = index.copy() index2['package1-1.0-0.tar.bz2'] = { 'build': '0', 'build_number': 0, 'depends': ['package2'], 'name': 'package1', 'requires': ['package2'], 'version': '1.0', } index2['package2-1.0-0.tar.bz2'] = { 'build': '0', 'build_number': 0, 'depends': ['package1'], 'name': 'package2', 'requires': ['package1'], 'version': '1.0', } r = Resolve(index2) assert set(r.find_matches(MatchSpec('package1'))) == { 'package1-1.0-0.tar.bz2', } assert set(r.get_dists(['package1']).keys()) == { 'package1-1.0-0.tar.bz2', 'package2-1.0-0.tar.bz2', } assert r.solve(['package1']) == r.solve(['package2']) == \ r.solve(['package1', 'package2']) == [ 'package1-1.0-0.tar.bz2', 'package2-1.0-0.tar.bz2', ]
def install_from_pypi(prefix, index, specs): r = Resolve(index) for_conda = [] for s in specs: try: next(r.find_matches(MatchSpec(s))) except StopIteration: print("Conda package not available for %s, attempting to create " "and install conda package from pypi" % s) recipedir = create_recipe(s) pkgname = build_package(prefix, recipedir) install_package(prefix, pkgname) else: for_conda.append(s) return for_conda
def test_optional_dependencies(): index2 = index.copy() index2['package1-1.0-0.tar.bz2'] = IndexRecord(**{ 'build': '0', 'build_number': 0, 'depends': ['package2 >1.0 (optional)'], 'name': 'package1', 'requires': ['package2'], 'version': '1.0', }) index2['package2-1.0-0.tar.bz2'] = IndexRecord(**{ 'build': '0', 'build_number': 0, 'depends': [], 'name': 'package2', 'requires': [], 'version': '1.0', }) index2['package2-2.0-0.tar.bz2'] = IndexRecord(**{ 'build': '0', 'build_number': 0, 'depends': [], 'name': 'package2', 'requires': [], 'version': '2.0', }) index2 = {Dist(key): value for key, value in iteritems(index2)} r = Resolve(index2) assert set(r.find_matches(MatchSpec('package1'))) == { Dist('package1-1.0-0.tar.bz2'), } assert set(r.get_reduced_index(['package1']).keys()) == { Dist('package1-1.0-0.tar.bz2'), Dist('package2-2.0-0.tar.bz2'), } assert r.install(['package1']) == [ Dist('package1-1.0-0.tar.bz2'), ] assert r.install(['package1', 'package2']) == r.install(['package1', 'package2 >1.0']) == [ Dist('package1-1.0-0.tar.bz2'), Dist('package2-2.0-0.tar.bz2'), ] assert raises(UnsatisfiableError, lambda: r.install(['package1', 'package2 <2.0'])) assert raises(UnsatisfiableError, lambda: r.install(['package1', 'package2 1.0']))
def test_circular_dependencies(): index2 = index.copy() index2['package1-1.0-0.tar.bz2'] = IndexRecord( **{ "channel": "defaults", "subdir": context.subdir, "md5": "0123456789", "fn": "doesnt-matter-here", 'build': '0', 'build_number': 0, 'depends': ['package2'], 'name': 'package1', 'requires': ['package2'], 'version': '1.0', }) index2['package2-1.0-0.tar.bz2'] = IndexRecord( **{ "channel": "defaults", "subdir": context.subdir, "md5": "0123456789", "fn": "doesnt-matter-here", 'build': '0', 'build_number': 0, 'depends': ['package1'], 'name': 'package2', 'requires': ['package1'], 'version': '1.0', }) index2 = {Dist(key): value for key, value in iteritems(index2)} r = Resolve(index2) assert set(r.find_matches(MatchSpec('package1'))) == { Dist('package1-1.0-0.tar.bz2'), } assert set(r.get_reduced_index(['package1']).keys()) == { Dist('package1-1.0-0.tar.bz2'), Dist('package2-1.0-0.tar.bz2'), } assert r.install(['package1']) == r.install(['package2']) == \ r.install(['package1', 'package2']) == [ Dist('package1-1.0-0.tar.bz2'), Dist('package2-1.0-0.tar.bz2'), ]
def execute(specs: List[str], r: Resolve) -> None: mspecs = [MatchSpec(m) for m in specs] unmet_dependency = None # type: Union[None, str] pkgs = implicated_packages(specs, r) unmet_depgraph = {} # type: Dict[str, Set[str]] # mapping from package name to all of the filenames that are plausible # installation candidates for that package valid = {} # type: Dict # when all of the plausible installation candidates for a package are # removed from ``valid``, we record the reason for that exclusion in # this dict, which maps package names to descriptions (english strings). exclusion_reasons = OrderedDict() # type: OrderedDict for pkg in pkgs: try: # if we have a matchspec for this package, get the valid files # for it. ms = next((ms for ms in mspecs if ms.name == MatchSpec(pkg).name)) except StopIteration: # if this package is an indirect dependency, we just have the name, # so we get all of the candidate files ms = MatchSpec(pkg) valid[pkg] = list(r.find_matches(ms)) while True: # in each iteration of this loop, we try to prune out some packages # from the valid dict. # first, record the number of filenames in the valid dict. use this # to ditect convergence and control terminatio of the while loop. pre_length = sum(len(fns) for fns in valid.values()) # iterate over the items in ``valid`` with the keys in the order # of pkgs, so that we go up the dependency chain. for key, fns in zip(pkgs, (valid[pkg] for pkg in pkgs)): # map filenames to a dict whose keys are the MatchSpecs # that this file depends on, and the values are whether # or not that MatchSpec currently has *any* valid files that # would satisfy it. satisfied = {fn: deps_are_satisfiable(fn, valid, r) for fn in fns} # files can only stay in valid if each of their dependencies # is satisfiable. valid[key] = { fn for fn, sat in satisfied.items() if all(sat.values()) } # if a certain package now has zero valid installation candidates, # we want to record a string to help explain why. if len(valid[key]) == 0 and key not in exclusion_reasons: unmet_depgraph[key] = { ms.name for ms2sat in satisfied.values() for ms in ms2sat if not ms2sat[ms] } fn2coloreddeps = {} # type: Dict[str, str] for fn, sat in satisfied.items(): parts = [ colored(d.spec, 'green' if sat[d] else 'red') for d in sorted(sat, key=lambda m: m.spec) ] fn2coloreddeps[fn] = ', '.join(parts) lines = ['No %s binary matches specs:' % colored(key, 'blue')] max_fn_length = max(len(fn) for fn in fn2coloreddeps.keys()) fn_spec = '%-{0:d}s'.format(max_fn_length - 6) for fn in sorted(fn2coloreddeps.keys(), reverse=True): coloreddeps = fn2coloreddeps[fn] # strip off the '.tar.bz2' when making the printout lines.append(''.join( (' ', fn_spec % (fn[:-8] + ': '), coloreddeps))) exclusion_reasons[key] = '\n'.join(lines) # if a package with zero installation candidates is *required* # (in the user's supplied specs), then we know we've failed. if any(key == ms.name for ms in mspecs): unmet_dependency = key # convergence without any invalidated packages, so we can't generate # a hint :( post_length = sum(len(fns) for fns in valid.values()) if pre_length == post_length: break if unmet_dependency is not None: print_output(unmet_dependency, exclusion_reasons, unmet_depgraph) return None
def deps_are_satisfiable(fn: str, valid: Dict[str, List[str]], r: Resolve) -> Dict[MatchSpec, bool]: return { ms: any(depfn in valid[ms.name] for depfn in r.find_matches(ms)) for ms in r.ms_depends(fn) }
def test_nonexistent_deps(): index2 = index.copy() index2['mypackage-1.0-py33_0.tar.bz2'] = IndexRecord(**{ 'build': 'py33_0', 'build_number': 0, 'depends': ['nose', 'python 3.3*', 'notarealpackage 2.0*'], 'name': 'mypackage', 'requires': ['nose 1.2.1', 'python 3.3'], 'version': '1.0', }) index2['mypackage-1.1-py33_0.tar.bz2'] = IndexRecord(**{ 'build': 'py33_0', 'build_number': 0, 'depends': ['nose', 'python 3.3*'], 'name': 'mypackage', 'requires': ['nose 1.2.1', 'python 3.3'], 'version': '1.1', }) index2['anotherpackage-1.0-py33_0.tar.bz2'] = IndexRecord(**{ 'build': 'py33_0', 'build_number': 0, 'depends': ['nose', 'mypackage 1.1'], 'name': 'anotherpackage', 'requires': ['nose', 'mypackage 1.1'], 'version': '1.0', }) index2['anotherpackage-2.0-py33_0.tar.bz2'] = IndexRecord(**{ 'build': 'py33_0', 'build_number': 0, 'depends': ['nose', 'mypackage'], 'name': 'anotherpackage', 'requires': ['nose', 'mypackage'], 'version': '2.0', }) index2 = {Dist(key): value for key, value in iteritems(index2)} r = Resolve(index2) assert set(r.find_matches(MatchSpec('mypackage'))) == { Dist('mypackage-1.0-py33_0.tar.bz2'), Dist('mypackage-1.1-py33_0.tar.bz2'), } assert set(d.to_filename() for d in r.get_reduced_index(['mypackage']).keys()) == { 'mypackage-1.1-py33_0.tar.bz2', 'nose-1.1.2-py33_0.tar.bz2', 'nose-1.2.1-py33_0.tar.bz2', 'nose-1.3.0-py33_0.tar.bz2', 'openssl-1.0.1c-0.tar.bz2', 'python-3.3.0-2.tar.bz2', 'python-3.3.0-3.tar.bz2', 'python-3.3.0-4.tar.bz2', 'python-3.3.0-pro0.tar.bz2', 'python-3.3.0-pro1.tar.bz2', 'python-3.3.1-0.tar.bz2', 'python-3.3.2-0.tar.bz2', 'readline-6.2-0.tar.bz2', 'sqlite-3.7.13-0.tar.bz2', 'system-5.8-0.tar.bz2', 'system-5.8-1.tar.bz2', 'tk-8.5.13-0.tar.bz2', 'zlib-1.2.7-0.tar.bz2'} target_result = r.install(['mypackage']) assert target_result == r.install(['mypackage 1.1']) assert target_result == [ Dist(add_defaults_if_no_channel(dname)) for dname in [ '<unknown>::mypackage-1.1-py33_0.tar.bz2', 'nose-1.3.0-py33_0.tar.bz2', 'openssl-1.0.1c-0.tar.bz2', 'python-3.3.2-0.tar.bz2', 'readline-6.2-0.tar.bz2', 'sqlite-3.7.13-0.tar.bz2', 'system-5.8-1.tar.bz2', 'tk-8.5.13-0.tar.bz2', 'zlib-1.2.7-0.tar.bz2', ]] assert raises(NoPackagesFoundError, lambda: r.install(['mypackage 1.0'])) assert raises(NoPackagesFoundError, lambda: r.install(['mypackage 1.0', 'burgertime 1.0'])) assert r.install(['anotherpackage 1.0']) == [ Dist(add_defaults_if_no_channel(dname)) for dname in [ '<unknown>::anotherpackage-1.0-py33_0.tar.bz2', '<unknown>::mypackage-1.1-py33_0.tar.bz2', 'nose-1.3.0-py33_0.tar.bz2', 'openssl-1.0.1c-0.tar.bz2', 'python-3.3.2-0.tar.bz2', 'readline-6.2-0.tar.bz2', 'sqlite-3.7.13-0.tar.bz2', 'system-5.8-1.tar.bz2', 'tk-8.5.13-0.tar.bz2', 'zlib-1.2.7-0.tar.bz2', ]] assert r.install(['anotherpackage']) == [ Dist(add_defaults_if_no_channel(dname)) for dname in [ '<unknown>::anotherpackage-2.0-py33_0.tar.bz2', '<unknown>::mypackage-1.1-py33_0.tar.bz2', 'nose-1.3.0-py33_0.tar.bz2', 'openssl-1.0.1c-0.tar.bz2', 'python-3.3.2-0.tar.bz2', 'readline-6.2-0.tar.bz2', 'sqlite-3.7.13-0.tar.bz2', 'system-5.8-1.tar.bz2', 'tk-8.5.13-0.tar.bz2', 'zlib-1.2.7-0.tar.bz2', ]] # This time, the latest version is messed up index3 = index.copy() index3['mypackage-1.1-py33_0.tar.bz2'] = IndexRecord(**{ 'build': 'py33_0', 'build_number': 0, 'depends': ['nose', 'python 3.3*', 'notarealpackage 2.0*'], 'name': 'mypackage', 'requires': ['nose 1.2.1', 'python 3.3'], 'version': '1.1', }) index3['mypackage-1.0-py33_0.tar.bz2'] = IndexRecord(**{ 'build': 'py33_0', 'build_number': 0, 'depends': ['nose', 'python 3.3*'], 'name': 'mypackage', 'requires': ['nose 1.2.1', 'python 3.3'], 'version': '1.0', }) index3['anotherpackage-1.0-py33_0.tar.bz2'] = IndexRecord(**{ 'build': 'py33_0', 'build_number': 0, 'depends': ['nose', 'mypackage 1.0'], 'name': 'anotherpackage', 'requires': ['nose', 'mypackage 1.0'], 'version': '1.0', }) index3['anotherpackage-2.0-py33_0.tar.bz2'] = IndexRecord(**{ 'build': 'py33_0', 'build_number': 0, 'depends': ['nose', 'mypackage'], 'name': 'anotherpackage', 'requires': ['nose', 'mypackage'], 'version': '2.0', }) index3 = {Dist(key): value for key, value in iteritems(index3)} r = Resolve(index3) assert set(d.to_filename() for d in r.find_matches(MatchSpec('mypackage'))) == { 'mypackage-1.0-py33_0.tar.bz2', 'mypackage-1.1-py33_0.tar.bz2', } assert set(d.to_filename() for d in r.get_reduced_index(['mypackage']).keys()) == { 'mypackage-1.0-py33_0.tar.bz2', 'nose-1.1.2-py33_0.tar.bz2', 'nose-1.2.1-py33_0.tar.bz2', 'nose-1.3.0-py33_0.tar.bz2', 'openssl-1.0.1c-0.tar.bz2', 'python-3.3.0-2.tar.bz2', 'python-3.3.0-3.tar.bz2', 'python-3.3.0-4.tar.bz2', 'python-3.3.0-pro0.tar.bz2', 'python-3.3.0-pro1.tar.bz2', 'python-3.3.1-0.tar.bz2', 'python-3.3.2-0.tar.bz2', 'readline-6.2-0.tar.bz2', 'sqlite-3.7.13-0.tar.bz2', 'system-5.8-0.tar.bz2', 'system-5.8-1.tar.bz2', 'tk-8.5.13-0.tar.bz2', 'zlib-1.2.7-0.tar.bz2'} assert r.install(['mypackage']) == r.install(['mypackage 1.0']) == [ Dist(add_defaults_if_no_channel(dname)) for dname in [ '<unknown>::mypackage-1.0-py33_0.tar.bz2', 'nose-1.3.0-py33_0.tar.bz2', 'openssl-1.0.1c-0.tar.bz2', 'python-3.3.2-0.tar.bz2', 'readline-6.2-0.tar.bz2', 'sqlite-3.7.13-0.tar.bz2', 'system-5.8-1.tar.bz2', 'tk-8.5.13-0.tar.bz2', 'zlib-1.2.7-0.tar.bz2', ]] assert raises(NoPackagesFoundError, lambda: r.install(['mypackage 1.1'])) assert r.install(['anotherpackage 1.0']) == [ Dist(add_defaults_if_no_channel(dname))for dname in [ '<unknown>::anotherpackage-1.0-py33_0.tar.bz2', '<unknown>::mypackage-1.0-py33_0.tar.bz2', 'nose-1.3.0-py33_0.tar.bz2', 'openssl-1.0.1c-0.tar.bz2', 'python-3.3.2-0.tar.bz2', 'readline-6.2-0.tar.bz2', 'sqlite-3.7.13-0.tar.bz2', 'system-5.8-1.tar.bz2', 'tk-8.5.13-0.tar.bz2', 'zlib-1.2.7-0.tar.bz2', ]] # If recursive checking is working correctly, this will give # anotherpackage 2.0, not anotherpackage 1.0 assert r.install(['anotherpackage']) == [ Dist(add_defaults_if_no_channel(dname))for dname in [ '<unknown>::anotherpackage-2.0-py33_0.tar.bz2', '<unknown>::mypackage-1.0-py33_0.tar.bz2', 'nose-1.3.0-py33_0.tar.bz2', 'openssl-1.0.1c-0.tar.bz2', 'python-3.3.2-0.tar.bz2', 'readline-6.2-0.tar.bz2', 'sqlite-3.7.13-0.tar.bz2', 'system-5.8-1.tar.bz2', 'tk-8.5.13-0.tar.bz2', 'zlib-1.2.7-0.tar.bz2', ]]
def test_nonexistent_deps(): index2 = index.copy() index2["mypackage-1.0-py33_0.tar.bz2"] = { "build": "py33_0", "build_number": 0, "depends": ["nose", "python 3.3*", "notarealpackage 2.0*"], "name": "mypackage", "requires": ["nose 1.2.1", "python 3.3"], "version": "1.0", } index2["mypackage-1.1-py33_0.tar.bz2"] = { "build": "py33_0", "build_number": 0, "depends": ["nose", "python 3.3*"], "name": "mypackage", "requires": ["nose 1.2.1", "python 3.3"], "version": "1.1", } index2["anotherpackage-1.0-py33_0.tar.bz2"] = { "build": "py33_0", "build_number": 0, "depends": ["nose", "mypackage 1.1"], "name": "anotherpackage", "requires": ["nose", "mypackage 1.1"], "version": "1.0", } index2["anotherpackage-2.0-py33_0.tar.bz2"] = { "build": "py33_0", "build_number": 0, "depends": ["nose", "mypackage"], "name": "anotherpackage", "requires": ["nose", "mypackage"], "version": "2.0", } r = Resolve(index2) assert set(r.find_matches(MatchSpec("mypackage"))) == { "mypackage-1.0-py33_0.tar.bz2", "mypackage-1.1-py33_0.tar.bz2", } assert set(r.get_dists(["mypackage"]).keys()) == { "mypackage-1.1-py33_0.tar.bz2", "nose-1.1.2-py26_0.tar.bz2", "nose-1.1.2-py27_0.tar.bz2", "nose-1.1.2-py33_0.tar.bz2", "nose-1.2.1-py26_0.tar.bz2", "nose-1.2.1-py27_0.tar.bz2", "nose-1.2.1-py33_0.tar.bz2", "nose-1.3.0-py26_0.tar.bz2", "nose-1.3.0-py27_0.tar.bz2", "nose-1.3.0-py33_0.tar.bz2", "openssl-1.0.1c-0.tar.bz2", "python-2.6.8-1.tar.bz2", "python-2.6.8-2.tar.bz2", "python-2.6.8-3.tar.bz2", "python-2.6.8-4.tar.bz2", "python-2.6.8-5.tar.bz2", "python-2.6.8-6.tar.bz2", "python-2.7.3-2.tar.bz2", "python-2.7.3-3.tar.bz2", "python-2.7.3-4.tar.bz2", "python-2.7.3-5.tar.bz2", "python-2.7.3-6.tar.bz2", "python-2.7.3-7.tar.bz2", "python-2.7.4-0.tar.bz2", "python-2.7.5-0.tar.bz2", "python-3.3.0-2.tar.bz2", "python-3.3.0-3.tar.bz2", "python-3.3.0-4.tar.bz2", "python-3.3.0-pro0.tar.bz2", "python-3.3.0-pro1.tar.bz2", "python-3.3.1-0.tar.bz2", "python-3.3.2-0.tar.bz2", "readline-6.2-0.tar.bz2", "sqlite-3.7.13-0.tar.bz2", "system-5.8-0.tar.bz2", "system-5.8-1.tar.bz2", "tk-8.5.13-0.tar.bz2", "zlib-1.2.7-0.tar.bz2", } assert set(r.get_dists(["mypackage"], max_only=True).keys()) == { "mypackage-1.1-py33_0.tar.bz2", "nose-1.3.0-py26_0.tar.bz2", "nose-1.3.0-py27_0.tar.bz2", "nose-1.3.0-py33_0.tar.bz2", "openssl-1.0.1c-0.tar.bz2", "python-2.6.8-6.tar.bz2", "python-2.7.5-0.tar.bz2", "python-3.3.2-0.tar.bz2", "readline-6.2-0.tar.bz2", "sqlite-3.7.13-0.tar.bz2", "system-5.8-1.tar.bz2", "tk-8.5.13-0.tar.bz2", "zlib-1.2.7-0.tar.bz2", } assert ( r.solve(["mypackage"]) == r.solve(["mypackage 1.1"]) == [ "mypackage-1.1-py33_0.tar.bz2", "nose-1.3.0-py33_0.tar.bz2", "openssl-1.0.1c-0.tar.bz2", "python-3.3.2-0.tar.bz2", "readline-6.2-0.tar.bz2", "sqlite-3.7.13-0.tar.bz2", "system-5.8-1.tar.bz2", "tk-8.5.13-0.tar.bz2", "zlib-1.2.7-0.tar.bz2", ] ) assert raises(NoPackagesFound, lambda: r.solve(["mypackage 1.0"])) assert r.solve(["anotherpackage 1.0"]) == [ "anotherpackage-1.0-py33_0.tar.bz2", "mypackage-1.1-py33_0.tar.bz2", "nose-1.3.0-py33_0.tar.bz2", "openssl-1.0.1c-0.tar.bz2", "python-3.3.2-0.tar.bz2", "readline-6.2-0.tar.bz2", "sqlite-3.7.13-0.tar.bz2", "system-5.8-1.tar.bz2", "tk-8.5.13-0.tar.bz2", "zlib-1.2.7-0.tar.bz2", ] assert r.solve(["anotherpackage"]) == [ "anotherpackage-2.0-py33_0.tar.bz2", "mypackage-1.1-py33_0.tar.bz2", "nose-1.3.0-py33_0.tar.bz2", "openssl-1.0.1c-0.tar.bz2", "python-3.3.2-0.tar.bz2", "readline-6.2-0.tar.bz2", "sqlite-3.7.13-0.tar.bz2", "system-5.8-1.tar.bz2", "tk-8.5.13-0.tar.bz2", "zlib-1.2.7-0.tar.bz2", ] # This time, the latest version is messed up index3 = index.copy() index3["mypackage-1.1-py33_0.tar.bz2"] = { "build": "py33_0", "build_number": 0, "depends": ["nose", "python 3.3*", "notarealpackage 2.0*"], "name": "mypackage", "requires": ["nose 1.2.1", "python 3.3"], "version": "1.1", } index3["mypackage-1.0-py33_0.tar.bz2"] = { "build": "py33_0", "build_number": 0, "depends": ["nose", "python 3.3*"], "name": "mypackage", "requires": ["nose 1.2.1", "python 3.3"], "version": "1.0", } index3["anotherpackage-1.0-py33_0.tar.bz2"] = { "build": "py33_0", "build_number": 0, "depends": ["nose", "mypackage 1.0"], "name": "anotherpackage", "requires": ["nose", "mypackage 1.0"], "version": "1.0", } index3["anotherpackage-2.0-py33_0.tar.bz2"] = { "build": "py33_0", "build_number": 0, "depends": ["nose", "mypackage"], "name": "anotherpackage", "requires": ["nose", "mypackage"], "version": "2.0", } r = Resolve(index3) assert set(r.find_matches(MatchSpec("mypackage"))) == { "mypackage-1.0-py33_0.tar.bz2", "mypackage-1.1-py33_0.tar.bz2", } assert set(r.get_dists(["mypackage"]).keys()) == { "mypackage-1.0-py33_0.tar.bz2", "nose-1.1.2-py26_0.tar.bz2", "nose-1.1.2-py27_0.tar.bz2", "nose-1.1.2-py33_0.tar.bz2", "nose-1.2.1-py26_0.tar.bz2", "nose-1.2.1-py27_0.tar.bz2", "nose-1.2.1-py33_0.tar.bz2", "nose-1.3.0-py26_0.tar.bz2", "nose-1.3.0-py27_0.tar.bz2", "nose-1.3.0-py33_0.tar.bz2", "openssl-1.0.1c-0.tar.bz2", "python-2.6.8-1.tar.bz2", "python-2.6.8-2.tar.bz2", "python-2.6.8-3.tar.bz2", "python-2.6.8-4.tar.bz2", "python-2.6.8-5.tar.bz2", "python-2.6.8-6.tar.bz2", "python-2.7.3-2.tar.bz2", "python-2.7.3-3.tar.bz2", "python-2.7.3-4.tar.bz2", "python-2.7.3-5.tar.bz2", "python-2.7.3-6.tar.bz2", "python-2.7.3-7.tar.bz2", "python-2.7.4-0.tar.bz2", "python-2.7.5-0.tar.bz2", "python-3.3.0-2.tar.bz2", "python-3.3.0-3.tar.bz2", "python-3.3.0-4.tar.bz2", "python-3.3.0-pro0.tar.bz2", "python-3.3.0-pro1.tar.bz2", "python-3.3.1-0.tar.bz2", "python-3.3.2-0.tar.bz2", "readline-6.2-0.tar.bz2", "sqlite-3.7.13-0.tar.bz2", "system-5.8-0.tar.bz2", "system-5.8-1.tar.bz2", "tk-8.5.13-0.tar.bz2", "zlib-1.2.7-0.tar.bz2", } assert raises(NoPackagesFound, lambda: r.get_dists(["mypackage"], max_only=True)) assert ( r.solve(["mypackage"]) == r.solve(["mypackage 1.0"]) == [ "mypackage-1.0-py33_0.tar.bz2", "nose-1.3.0-py33_0.tar.bz2", "openssl-1.0.1c-0.tar.bz2", "python-3.3.2-0.tar.bz2", "readline-6.2-0.tar.bz2", "sqlite-3.7.13-0.tar.bz2", "system-5.8-1.tar.bz2", "tk-8.5.13-0.tar.bz2", "zlib-1.2.7-0.tar.bz2", ] ) assert raises(NoPackagesFound, lambda: r.solve(["mypackage 1.1"])) assert r.solve(["anotherpackage 1.0"]) == [ "anotherpackage-1.0-py33_0.tar.bz2", "mypackage-1.0-py33_0.tar.bz2", "nose-1.3.0-py33_0.tar.bz2", "openssl-1.0.1c-0.tar.bz2", "python-3.3.2-0.tar.bz2", "readline-6.2-0.tar.bz2", "sqlite-3.7.13-0.tar.bz2", "system-5.8-1.tar.bz2", "tk-8.5.13-0.tar.bz2", "zlib-1.2.7-0.tar.bz2", ] # If recursive checking is working correctly, this will give # anotherpackage 2.0, not anotherpackage 1.0 assert r.solve(["anotherpackage"]) == [ "anotherpackage-2.0-py33_0.tar.bz2", "mypackage-1.0-py33_0.tar.bz2", "nose-1.3.0-py33_0.tar.bz2", "openssl-1.0.1c-0.tar.bz2", "python-3.3.2-0.tar.bz2", "readline-6.2-0.tar.bz2", "sqlite-3.7.13-0.tar.bz2", "system-5.8-1.tar.bz2", "tk-8.5.13-0.tar.bz2", "zlib-1.2.7-0.tar.bz2", ]
def test_nonexistent_deps(): index2 = index.copy() index2['mypackage-1.0-py33_0.tar.bz2'] = Record(**{ 'build': 'py33_0', 'build_number': 0, 'depends': ['nose', 'python 3.3*', 'notarealpackage 2.0*'], 'name': 'mypackage', 'requires': ['nose 1.2.1', 'python 3.3'], 'version': '1.0', }) index2['mypackage-1.1-py33_0.tar.bz2'] = Record(**{ 'build': 'py33_0', 'build_number': 0, 'depends': ['nose', 'python 3.3*'], 'name': 'mypackage', 'requires': ['nose 1.2.1', 'python 3.3'], 'version': '1.1', }) index2['anotherpackage-1.0-py33_0.tar.bz2'] = Record(**{ 'build': 'py33_0', 'build_number': 0, 'depends': ['nose', 'mypackage 1.1'], 'name': 'anotherpackage', 'requires': ['nose', 'mypackage 1.1'], 'version': '1.0', }) index2['anotherpackage-2.0-py33_0.tar.bz2'] = Record(**{ 'build': 'py33_0', 'build_number': 0, 'depends': ['nose', 'mypackage'], 'name': 'anotherpackage', 'requires': ['nose', 'mypackage'], 'version': '2.0', }) index2 = {Dist(key): value for key, value in iteritems(index2)} r = Resolve(index2) assert set(r.find_matches(MatchSpec('mypackage'))) == { Dist('mypackage-1.0-py33_0.tar.bz2'), Dist('mypackage-1.1-py33_0.tar.bz2'), } assert set(d.to_filename() for d in r.get_reduced_index(['mypackage']).keys()) == { 'mypackage-1.1-py33_0.tar.bz2', 'nose-1.1.2-py33_0.tar.bz2', 'nose-1.2.1-py33_0.tar.bz2', 'nose-1.3.0-py33_0.tar.bz2', 'openssl-1.0.1c-0.tar.bz2', 'python-3.3.0-2.tar.bz2', 'python-3.3.0-3.tar.bz2', 'python-3.3.0-4.tar.bz2', 'python-3.3.0-pro0.tar.bz2', 'python-3.3.0-pro1.tar.bz2', 'python-3.3.1-0.tar.bz2', 'python-3.3.2-0.tar.bz2', 'readline-6.2-0.tar.bz2', 'sqlite-3.7.13-0.tar.bz2', 'system-5.8-0.tar.bz2', 'system-5.8-1.tar.bz2', 'tk-8.5.13-0.tar.bz2', 'zlib-1.2.7-0.tar.bz2'} assert r.install(['mypackage']) == r.install(['mypackage 1.1']) == [Dist(dname) for dname in [ 'mypackage-1.1-py33_0.tar.bz2', 'nose-1.3.0-py33_0.tar.bz2', 'openssl-1.0.1c-0.tar.bz2', 'python-3.3.2-0.tar.bz2', 'readline-6.2-0.tar.bz2', 'sqlite-3.7.13-0.tar.bz2', 'system-5.8-1.tar.bz2', 'tk-8.5.13-0.tar.bz2', 'zlib-1.2.7-0.tar.bz2', ]] assert raises(NoPackagesFoundError, lambda: r.install(['mypackage 1.0'])) assert raises(NoPackagesFoundError, lambda: r.install(['mypackage 1.0', 'burgertime 1.0'])) assert r.install(['anotherpackage 1.0']) == [Dist(dname) for dname in [ 'anotherpackage-1.0-py33_0.tar.bz2', 'mypackage-1.1-py33_0.tar.bz2', 'nose-1.3.0-py33_0.tar.bz2', 'openssl-1.0.1c-0.tar.bz2', 'python-3.3.2-0.tar.bz2', 'readline-6.2-0.tar.bz2', 'sqlite-3.7.13-0.tar.bz2', 'system-5.8-1.tar.bz2', 'tk-8.5.13-0.tar.bz2', 'zlib-1.2.7-0.tar.bz2', ]] assert r.install(['anotherpackage']) == [Dist(dname) for dname in [ 'anotherpackage-2.0-py33_0.tar.bz2', 'mypackage-1.1-py33_0.tar.bz2', 'nose-1.3.0-py33_0.tar.bz2', 'openssl-1.0.1c-0.tar.bz2', 'python-3.3.2-0.tar.bz2', 'readline-6.2-0.tar.bz2', 'sqlite-3.7.13-0.tar.bz2', 'system-5.8-1.tar.bz2', 'tk-8.5.13-0.tar.bz2', 'zlib-1.2.7-0.tar.bz2', ]] # This time, the latest version is messed up index3 = index.copy() index3['mypackage-1.1-py33_0.tar.bz2'] = Record(**{ 'build': 'py33_0', 'build_number': 0, 'depends': ['nose', 'python 3.3*', 'notarealpackage 2.0*'], 'name': 'mypackage', 'requires': ['nose 1.2.1', 'python 3.3'], 'version': '1.1', }) index3['mypackage-1.0-py33_0.tar.bz2'] = Record(**{ 'build': 'py33_0', 'build_number': 0, 'depends': ['nose', 'python 3.3*'], 'name': 'mypackage', 'requires': ['nose 1.2.1', 'python 3.3'], 'version': '1.0', }) index3['anotherpackage-1.0-py33_0.tar.bz2'] = Record(**{ 'build': 'py33_0', 'build_number': 0, 'depends': ['nose', 'mypackage 1.0'], 'name': 'anotherpackage', 'requires': ['nose', 'mypackage 1.0'], 'version': '1.0', }) index3['anotherpackage-2.0-py33_0.tar.bz2'] = Record(**{ 'build': 'py33_0', 'build_number': 0, 'depends': ['nose', 'mypackage'], 'name': 'anotherpackage', 'requires': ['nose', 'mypackage'], 'version': '2.0', }) index3 = {Dist(key): value for key, value in iteritems(index3)} r = Resolve(index3) assert set(d.to_filename() for d in r.find_matches(MatchSpec('mypackage'))) == { 'mypackage-1.0-py33_0.tar.bz2', 'mypackage-1.1-py33_0.tar.bz2', } assert set(d.to_filename() for d in r.get_reduced_index(['mypackage']).keys()) == { 'mypackage-1.0-py33_0.tar.bz2', 'nose-1.1.2-py33_0.tar.bz2', 'nose-1.2.1-py33_0.tar.bz2', 'nose-1.3.0-py33_0.tar.bz2', 'openssl-1.0.1c-0.tar.bz2', 'python-3.3.0-2.tar.bz2', 'python-3.3.0-3.tar.bz2', 'python-3.3.0-4.tar.bz2', 'python-3.3.0-pro0.tar.bz2', 'python-3.3.0-pro1.tar.bz2', 'python-3.3.1-0.tar.bz2', 'python-3.3.2-0.tar.bz2', 'readline-6.2-0.tar.bz2', 'sqlite-3.7.13-0.tar.bz2', 'system-5.8-0.tar.bz2', 'system-5.8-1.tar.bz2', 'tk-8.5.13-0.tar.bz2', 'zlib-1.2.7-0.tar.bz2'} assert r.install(['mypackage']) == r.install(['mypackage 1.0']) == [Dist(dname) for dname in [ 'mypackage-1.0-py33_0.tar.bz2', 'nose-1.3.0-py33_0.tar.bz2', 'openssl-1.0.1c-0.tar.bz2', 'python-3.3.2-0.tar.bz2', 'readline-6.2-0.tar.bz2', 'sqlite-3.7.13-0.tar.bz2', 'system-5.8-1.tar.bz2', 'tk-8.5.13-0.tar.bz2', 'zlib-1.2.7-0.tar.bz2', ]] assert raises(NoPackagesFoundError, lambda: r.install(['mypackage 1.1'])) assert r.install(['anotherpackage 1.0']) == [Dist(dname) for dname in [ 'anotherpackage-1.0-py33_0.tar.bz2', 'mypackage-1.0-py33_0.tar.bz2', 'nose-1.3.0-py33_0.tar.bz2', 'openssl-1.0.1c-0.tar.bz2', 'python-3.3.2-0.tar.bz2', 'readline-6.2-0.tar.bz2', 'sqlite-3.7.13-0.tar.bz2', 'system-5.8-1.tar.bz2', 'tk-8.5.13-0.tar.bz2', 'zlib-1.2.7-0.tar.bz2', ]] # If recursive checking is working correctly, this will give # anotherpackage 2.0, not anotherpackage 1.0 assert r.install(['anotherpackage']) == [Dist(dname) for dname in [ 'anotherpackage-2.0-py33_0.tar.bz2', 'mypackage-1.0-py33_0.tar.bz2', 'nose-1.3.0-py33_0.tar.bz2', 'openssl-1.0.1c-0.tar.bz2', 'python-3.3.2-0.tar.bz2', 'readline-6.2-0.tar.bz2', 'sqlite-3.7.13-0.tar.bz2', 'system-5.8-1.tar.bz2', 'tk-8.5.13-0.tar.bz2', 'zlib-1.2.7-0.tar.bz2', ]]
def test_nonexistent_deps(): index2 = index.copy() index2['mypackage-1.0-py33_0.tar.bz2'] = { 'build': 'py33_0', 'build_number': 0, 'depends': ['nose', 'python 3.3*', 'notarealpackage 2.0*'], 'name': 'mypackage', 'requires': ['nose 1.2.1', 'python 3.3'], 'version': '1.0', } index2['mypackage-1.1-py33_0.tar.bz2'] = { 'build': 'py33_0', 'build_number': 0, 'depends': ['nose', 'python 3.3*'], 'name': 'mypackage', 'requires': ['nose 1.2.1', 'python 3.3'], 'version': '1.1', } index2['anotherpackage-1.0-py33_0.tar.bz2'] = { 'build': 'py33_0', 'build_number': 0, 'depends': ['nose', 'mypackage 1.1'], 'name': 'anotherpackage', 'requires': ['nose', 'mypackage 1.1'], 'version': '1.0', } index2['anotherpackage-2.0-py33_0.tar.bz2'] = { 'build': 'py33_0', 'build_number': 0, 'depends': ['nose', 'mypackage'], 'name': 'anotherpackage', 'requires': ['nose', 'mypackage'], 'version': '2.0', } r = Resolve(index2) assert set(r.find_matches(MatchSpec('mypackage'))) == { 'mypackage-1.0-py33_0.tar.bz2', 'mypackage-1.1-py33_0.tar.bz2', } assert set(r.get_dists(['mypackage']).keys()) == { 'mypackage-1.1-py33_0.tar.bz2', 'nose-1.1.2-py26_0.tar.bz2', 'nose-1.1.2-py27_0.tar.bz2', 'nose-1.1.2-py33_0.tar.bz2', 'nose-1.2.1-py26_0.tar.bz2', 'nose-1.2.1-py27_0.tar.bz2', 'nose-1.2.1-py33_0.tar.bz2', 'nose-1.3.0-py26_0.tar.bz2', 'nose-1.3.0-py27_0.tar.bz2', 'nose-1.3.0-py33_0.tar.bz2', 'openssl-1.0.1c-0.tar.bz2', 'python-2.6.8-1.tar.bz2', 'python-2.6.8-2.tar.bz2', 'python-2.6.8-3.tar.bz2', 'python-2.6.8-4.tar.bz2', 'python-2.6.8-5.tar.bz2', 'python-2.6.8-6.tar.bz2', 'python-2.7.3-2.tar.bz2', 'python-2.7.3-3.tar.bz2', 'python-2.7.3-4.tar.bz2', 'python-2.7.3-5.tar.bz2', 'python-2.7.3-6.tar.bz2', 'python-2.7.3-7.tar.bz2', 'python-2.7.4-0.tar.bz2', 'python-2.7.5-0.tar.bz2', 'python-3.3.0-2.tar.bz2', 'python-3.3.0-3.tar.bz2', 'python-3.3.0-4.tar.bz2', 'python-3.3.0-pro0.tar.bz2', 'python-3.3.0-pro1.tar.bz2', 'python-3.3.1-0.tar.bz2', 'python-3.3.2-0.tar.bz2', 'readline-6.2-0.tar.bz2', 'sqlite-3.7.13-0.tar.bz2', 'system-5.8-0.tar.bz2', 'system-5.8-1.tar.bz2', 'tk-8.5.13-0.tar.bz2', 'zlib-1.2.7-0.tar.bz2', } assert set(r.get_dists(['mypackage'], max_only=True).keys()) == { 'mypackage-1.1-py33_0.tar.bz2', 'nose-1.3.0-py26_0.tar.bz2', 'nose-1.3.0-py27_0.tar.bz2', 'nose-1.3.0-py33_0.tar.bz2', 'openssl-1.0.1c-0.tar.bz2', 'python-2.6.8-6.tar.bz2', 'python-2.7.5-0.tar.bz2', 'python-3.3.2-0.tar.bz2', 'readline-6.2-0.tar.bz2', 'sqlite-3.7.13-0.tar.bz2', 'system-5.8-1.tar.bz2', 'tk-8.5.13-0.tar.bz2', 'zlib-1.2.7-0.tar.bz2', } assert r.solve(['mypackage']) == r.solve(['mypackage 1.1']) == [ 'mypackage-1.1-py33_0.tar.bz2', 'nose-1.3.0-py33_0.tar.bz2', 'openssl-1.0.1c-0.tar.bz2', 'python-3.3.2-0.tar.bz2', 'readline-6.2-0.tar.bz2', 'sqlite-3.7.13-0.tar.bz2', 'system-5.8-1.tar.bz2', 'tk-8.5.13-0.tar.bz2', 'zlib-1.2.7-0.tar.bz2', ] assert raises(NoPackagesFound, lambda: r.solve(['mypackage 1.0'])) assert r.solve(['anotherpackage 1.0']) == [ 'anotherpackage-1.0-py33_0.tar.bz2', 'mypackage-1.1-py33_0.tar.bz2', 'nose-1.3.0-py33_0.tar.bz2', 'openssl-1.0.1c-0.tar.bz2', 'python-3.3.2-0.tar.bz2', 'readline-6.2-0.tar.bz2', 'sqlite-3.7.13-0.tar.bz2', 'system-5.8-1.tar.bz2', 'tk-8.5.13-0.tar.bz2', 'zlib-1.2.7-0.tar.bz2', ] assert r.solve(['anotherpackage']) == [ 'anotherpackage-2.0-py33_0.tar.bz2', 'mypackage-1.1-py33_0.tar.bz2', 'nose-1.3.0-py33_0.tar.bz2', 'openssl-1.0.1c-0.tar.bz2', 'python-3.3.2-0.tar.bz2', 'readline-6.2-0.tar.bz2', 'sqlite-3.7.13-0.tar.bz2', 'system-5.8-1.tar.bz2', 'tk-8.5.13-0.tar.bz2', 'zlib-1.2.7-0.tar.bz2', ] # This time, the latest version is messed up index3 = index.copy() index3['mypackage-1.1-py33_0.tar.bz2'] = { 'build': 'py33_0', 'build_number': 0, 'depends': ['nose', 'python 3.3*', 'notarealpackage 2.0*'], 'name': 'mypackage', 'requires': ['nose 1.2.1', 'python 3.3'], 'version': '1.1', } index3['mypackage-1.0-py33_0.tar.bz2'] = { 'build': 'py33_0', 'build_number': 0, 'depends': ['nose', 'python 3.3*'], 'name': 'mypackage', 'requires': ['nose 1.2.1', 'python 3.3'], 'version': '1.0', } index3['anotherpackage-1.0-py33_0.tar.bz2'] = { 'build': 'py33_0', 'build_number': 0, 'depends': ['nose', 'mypackage 1.0'], 'name': 'anotherpackage', 'requires': ['nose', 'mypackage 1.0'], 'version': '1.0', } index3['anotherpackage-2.0-py33_0.tar.bz2'] = { 'build': 'py33_0', 'build_number': 0, 'depends': ['nose', 'mypackage'], 'name': 'anotherpackage', 'requires': ['nose', 'mypackage'], 'version': '2.0', } r = Resolve(index3) assert set(r.find_matches(MatchSpec('mypackage'))) == { 'mypackage-1.0-py33_0.tar.bz2', 'mypackage-1.1-py33_0.tar.bz2', } assert set(r.get_dists(['mypackage']).keys()) == { 'mypackage-1.0-py33_0.tar.bz2', 'nose-1.1.2-py26_0.tar.bz2', 'nose-1.1.2-py27_0.tar.bz2', 'nose-1.1.2-py33_0.tar.bz2', 'nose-1.2.1-py26_0.tar.bz2', 'nose-1.2.1-py27_0.tar.bz2', 'nose-1.2.1-py33_0.tar.bz2', 'nose-1.3.0-py26_0.tar.bz2', 'nose-1.3.0-py27_0.tar.bz2', 'nose-1.3.0-py33_0.tar.bz2', 'openssl-1.0.1c-0.tar.bz2', 'python-2.6.8-1.tar.bz2', 'python-2.6.8-2.tar.bz2', 'python-2.6.8-3.tar.bz2', 'python-2.6.8-4.tar.bz2', 'python-2.6.8-5.tar.bz2', 'python-2.6.8-6.tar.bz2', 'python-2.7.3-2.tar.bz2', 'python-2.7.3-3.tar.bz2', 'python-2.7.3-4.tar.bz2', 'python-2.7.3-5.tar.bz2', 'python-2.7.3-6.tar.bz2', 'python-2.7.3-7.tar.bz2', 'python-2.7.4-0.tar.bz2', 'python-2.7.5-0.tar.bz2', 'python-3.3.0-2.tar.bz2', 'python-3.3.0-3.tar.bz2', 'python-3.3.0-4.tar.bz2', 'python-3.3.0-pro0.tar.bz2', 'python-3.3.0-pro1.tar.bz2', 'python-3.3.1-0.tar.bz2', 'python-3.3.2-0.tar.bz2', 'readline-6.2-0.tar.bz2', 'sqlite-3.7.13-0.tar.bz2', 'system-5.8-0.tar.bz2', 'system-5.8-1.tar.bz2', 'tk-8.5.13-0.tar.bz2', 'zlib-1.2.7-0.tar.bz2', } assert raises(NoPackagesFound, lambda: r.get_dists(['mypackage'], max_only=True)) assert r.solve(['mypackage']) == r.solve(['mypackage 1.0']) == [ 'mypackage-1.0-py33_0.tar.bz2', 'nose-1.3.0-py33_0.tar.bz2', 'openssl-1.0.1c-0.tar.bz2', 'python-3.3.2-0.tar.bz2', 'readline-6.2-0.tar.bz2', 'sqlite-3.7.13-0.tar.bz2', 'system-5.8-1.tar.bz2', 'tk-8.5.13-0.tar.bz2', 'zlib-1.2.7-0.tar.bz2', ] assert raises(NoPackagesFound, lambda: r.solve(['mypackage 1.1'])) assert r.solve(['anotherpackage 1.0']) == [ 'anotherpackage-1.0-py33_0.tar.bz2', 'mypackage-1.0-py33_0.tar.bz2', 'nose-1.3.0-py33_0.tar.bz2', 'openssl-1.0.1c-0.tar.bz2', 'python-3.3.2-0.tar.bz2', 'readline-6.2-0.tar.bz2', 'sqlite-3.7.13-0.tar.bz2', 'system-5.8-1.tar.bz2', 'tk-8.5.13-0.tar.bz2', 'zlib-1.2.7-0.tar.bz2', ] # If recursive checking is working correctly, this will give # anotherpackage 2.0, not anotherpackage 1.0 assert r.solve(['anotherpackage']) == [ 'anotherpackage-2.0-py33_0.tar.bz2', 'mypackage-1.0-py33_0.tar.bz2', 'nose-1.3.0-py33_0.tar.bz2', 'openssl-1.0.1c-0.tar.bz2', 'python-3.3.2-0.tar.bz2', 'readline-6.2-0.tar.bz2', 'sqlite-3.7.13-0.tar.bz2', 'system-5.8-1.tar.bz2', 'tk-8.5.13-0.tar.bz2', 'zlib-1.2.7-0.tar.bz2', ]
def execute(specs: List[str], r: Resolve) -> None: mspecs = [MatchSpec(m) for m in specs] unmet_dependency = None # type: Union[None, str] pkgs = implicated_packages(specs, r) unmet_depgraph = {} # type: Dict[str, Set[str]] # mapping from package name to all of the filenames that are plausible # installation candidates for that package valid = {} # type: Dict # when all of the plausible installation candidates for a package are # removed from ``valid``, we record the reason for that exclusion in # this dict, which maps package names to descriptions (english strings). exclusion_reasons = OrderedDict() # type: OrderedDict for pkg in pkgs: try: # if we have a matchspec for this package, get the valid files # for it. ms = next((ms for ms in mspecs if ms.name == MatchSpec(pkg).name)) except StopIteration: # if this package is an indirect dependency, we just have the name, # so we get all of the candidate files ms = MatchSpec(pkg) valid[pkg] = list(r.find_matches(ms)) while True: # in each iteration of this loop, we try to prune out some packages # from the valid dict. # first, record the number of filenames in the valid dict. use this # to ditect convergence and control terminatio of the while loop. pre_length = sum(len(fns) for fns in valid.values()) # iterate over the items in ``valid`` with the keys in the order # of pkgs, so that we go up the dependency chain. for key, fns in zip(pkgs, (valid[pkg] for pkg in pkgs)): # map filenames to a dict whose keys are the MatchSpecs # that this file depends on, and the values are whether # or not that MatchSpec currently has *any* valid files that # would satisfy it. satisfied = {fn: deps_are_satisfiable(fn, valid, r) for fn in fns} # files can only stay in valid if each of their dependencies # is satisfiable. valid[key] = {fn for fn, sat in satisfied.items() if all(sat.values())} # if a certain package now has zero valid installation candidates, # we want to record a string to help explain why. if len(valid[key]) == 0 and key not in exclusion_reasons: unmet_depgraph[key] = {ms.name for ms2sat in satisfied.values() for ms in ms2sat if not ms2sat[ms]} fn2coloreddeps = {} # type: Dict[str, str] for fn, sat in satisfied.items(): parts = [colored(d.spec, 'green' if sat[d] else 'red') for d in sorted(sat, key=lambda m: m.spec)] fn2coloreddeps[fn] = ', '.join(parts) lines = ['No %s binary matches specs:' % colored(key, 'blue')] max_fn_length = max(len(fn) for fn in fn2coloreddeps.keys()) fn_spec = '%-{0:d}s'.format(max_fn_length-6) for fn in sorted(fn2coloreddeps.keys(), reverse=True): coloreddeps = fn2coloreddeps[fn] # strip off the '.tar.bz2' when making the printout lines.append(''.join((' ', fn_spec % (fn[:-8] + ': '), coloreddeps))) exclusion_reasons[key] = '\n'.join(lines) # if a package with zero installation candidates is *required* # (in the user's supplied specs), then we know we've failed. if any(key == ms.name for ms in mspecs): unmet_dependency = key # convergence without any invalidated packages, so we can't generate # a hint :( post_length = sum(len(fns) for fns in valid.values()) if pre_length == post_length: break if unmet_dependency is not None: print_output(unmet_dependency, exclusion_reasons, unmet_depgraph) return None