def get_index_r_3(): with open(join(dirname(__file__), 'index3.json')) as fi: packages = json.load(fi) repodata = { "info": { "subdir": context.subdir, "arch": context.arch_name, "platform": context.platform, }, "packages": packages, } channel = Channel('https://conda.anaconda.org/channel-3/%s' % context.subdir) sd = SubdirData(channel) with env_var("CONDA_ADD_PIP_AS_PYTHON_DEPENDENCY", "false", reset_context): sd._process_raw_repodata_str(json.dumps(repodata)) sd._loaded = True SubdirData._cache_[channel.url(with_credentials=True)] = sd index = {Dist(prec): prec for prec in sd._package_records} r = Resolve(index, channels=(channel, )) return index, r
def test_track_features_match(self): dst = Dist('defaults::foo-1.2.3-4.tar.bz2') a = MatchSpec(features='test') assert text_type(a) == "*[features=test]" assert not a.match(DPkg(dst)) assert not a.match(DPkg(dst, track_features='')) a = MatchSpec(track_features='test') assert a.match(DPkg(dst, track_features='test')) assert not a.match(DPkg(dst, track_features='test2')) assert not a.match(DPkg(dst, track_features='test me')) assert not a.match(DPkg(dst, track_features='you test')) assert not a.match(DPkg(dst, track_features='you test me')) assert a.get_exact_value('track_features') == frozenset(('test', )) b = MatchSpec(track_features='mkl') assert not b.match(DPkg(dst)) assert b.match(DPkg(dst, track_features='mkl')) assert b.match(DPkg(dst, track_features='mkl')) assert not b.match(DPkg(dst, track_features='mkl debug')) assert not b.match(DPkg(dst, track_features='debug')) c = MatchSpec(track_features='nomkl') assert not c.match(DPkg(dst)) assert not c.match(DPkg(dst, track_features='mkl')) assert c.match(DPkg(dst, track_features='nomkl')) assert not c.match(DPkg(dst, track_features='nomkl debug')) # regression test for #6860 d = MatchSpec(track_features='') assert d.get_exact_value('track_features') == frozenset() d = MatchSpec(track_features=' ') assert d.get_exact_value('track_features') == frozenset() d = MatchSpec(track_features=('', '')) assert d.get_exact_value('track_features') == frozenset() d = MatchSpec(track_features=('', '', 'test')) assert d.get_exact_value('track_features') == frozenset(('test', ))
def test_install_package_with_feature(): index2 = index.copy() index2['mypackage-1.0-featurepy33_0.tar.bz2'] = IndexRecord(**{ 'build': 'featurepy33_0', 'build_number': 0, 'depends': ['python 3.3*'], 'name': 'mypackage', 'version': '1.0', 'features': 'feature', }) index2['feature-1.0-py33_0.tar.bz2'] = IndexRecord(**{ 'build': 'py33_0', 'build_number': 0, 'depends': ['python 3.3*'], 'name': 'feature', 'version': '1.0', 'track_features': 'feature', }) index2 = {Dist(key): value for key, value in iteritems(index2)} r = Resolve(index2) # It should not raise r.install(['mypackage','feature 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 test_broken_install(): installed = r.install(['pandas', 'python 2.7*', 'numpy 1.6*']) assert installed == [ Dist(fname) for fname in [ 'dateutil-2.1-py27_1.tar.bz2', 'numpy-1.6.2-py27_4.tar.bz2', 'openssl-1.0.1c-0.tar.bz2', 'pandas-0.11.0-np16py27_1.tar.bz2', 'python-2.7.5-0.tar.bz2', 'pytz-2013b-py27_0.tar.bz2', 'readline-6.2-0.tar.bz2', 'scipy-0.12.0-np16py27_0.tar.bz2', 'six-1.3.0-py27_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' ] ] # Add a fake package and an incompatible numpy installed2 = list(installed) installed2[1] = Dist('numpy-1.7.1-py33_p0.tar.bz2') installed2.append(Dist('notarealpackage-2.0-0.tar.bz2')) assert r.install([], installed2) == installed2 installed3 = r.install(['numpy'], installed2) installed4 = r.remove(['pandas'], installed2) assert set(installed4) == set(installed2[:3] + installed2[4:]) # Remove the installed version of pandas from the index index2 = index.copy() rec = index2[Dist('pandas-0.11.0-np16py27_1.tar.bz2')] index2[Dist('pandas-0.11.0-np16py27_1.tar.bz2')] = rec = rec.copy() rec['priority'] = MAX_CHANNEL_PRIORITY r2 = Resolve(index2) installed2 = r2.install(['pandas', 'python 2.7*', 'numpy 1.6*'], installed) assert installed2 == [ Dist(d) for d in [ 'dateutil-2.1-py27_1.tar.bz2', 'numpy-1.6.2-py27_4.tar.bz2', 'openssl-1.0.1c-0.tar.bz2', 'pandas-0.10.1-np16py27_0.tar.bz2', 'python-2.7.5-0.tar.bz2', 'pytz-2013b-py27_0.tar.bz2', 'readline-6.2-0.tar.bz2', 'scipy-0.11.0-np16py27_3.tar.bz2', 'six-1.3.0-py27_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_ensure_linked_actions_no_linked(self, load_meta): dists = [ Dist("test-88"), Dist("test-spec-42"), Dist("test-spec2-8.0.0.0.1-9") ] prefix = "some/prefix" link_actions = plan.ensure_linked_actions(dists, prefix) expected_output = defaultdict(list) expected_output["PREFIX"] = prefix expected_output["op_order"] = ('CHECK_FETCH', 'RM_FETCHED', 'FETCH', 'CHECK_EXTRACT', 'RM_EXTRACTED', 'EXTRACT', 'UNLINK', 'LINK', 'SYMLINK_CONDA') expected_output["LINK"] = [ Dist("test-88"), Dist("test-spec-42"), Dist("test-spec2-8.0.0.0.1-9") ] self.assertEquals(link_actions, expected_output)
def test_get_actions_multiple_dists_and_unlink(self, load_linked_data): install = [Dist("testspec2-4.3.0-2"), Dist("testspec1-1.1.1-py27_0")] r = generate_mocked_resolve(self.pkgs, install) dists_for_prefix = plan.SpecsForPrefix(prefix="root/prefix", r=r, specs=["testspec2 <4.3", "testspec1 1.1*"]) test_link_data = {"root/prefix": {Dist("testspec1-0.9.1-py27_2"): True}} with patch("conda.core.linked_data.linked_data_", test_link_data): actions = plan.get_actions_for_dists(dists_for_prefix, None, self.res.index, None, False, False, True, True) expected_output = defaultdict(list) expected_output["PREFIX"] = "root/prefix" expected_output["op_order"] = ('CHECK_FETCH', 'RM_FETCHED', 'FETCH', 'CHECK_EXTRACT', 'RM_EXTRACTED', 'EXTRACT', 'UNLINK', 'LINK', 'SYMLINK_CONDA') expected_output["LINK"] = [Dist("testspec2-4.3.0-2"), Dist("testspec1-1.1.1-py27_0")] expected_output["UNLINK"] = [Dist("testspec1-0.9.1-py27_2")] expected_output["SYMLINK_CONDA"] = [context.root_dir] assert expected_output["LINK"] == actions["LINK"] assert actions == expected_output
def test_update_in_private_env_append_unlink(self, remove_actions): required_solves = [plan.SpecsForPrefix(prefix="root/prefix/envs/_env_", specs=["test1", "test2"], r=self.res), plan.SpecsForPrefix(prefix=context.root_prefix, specs=["whatevs"], r=self.res)] action = defaultdict(list) action["PREFIX"] = "root/prefix/envs/_env_" action["LINK"] = [Dist("test1-2.1.4-1"), Dist("test2-1.1.1-8")] action_root = defaultdict(list) action_root["PREFIX"] = context.root_prefix action_root["LINK"] = [Dist("whatevs-54-54")] actions = [action, action_root] test_link_data = {context.root_prefix: {Dist("test1-2.1.4-1"): True}} with patch("conda.core.linked_data.linked_data_", test_link_data): plan.add_unlink_options_for_update(actions, required_solves, self.res.index) aug_action_root = defaultdict(list) aug_action_root["PREFIX"] = context.root_prefix aug_action_root["LINK"] = [Dist("whatevs-54-54")] aug_action_root["UNLINK"] = [Dist("test1-2.1.4-1")] expected_output = [action, aug_action_root] self.assertEquals(actions, expected_output)
def test_generate_eq(): dists = r.get_reduced_index(['anaconda']) r2 = Resolve(dists, True, True) C = r2.gen_clauses() eqv, eqb = r2.generate_version_metrics(C, list(r2.groups.keys())) # Should satisfy the following criteria: # - lower versions of the same package should should have higher # coefficients. # - the same versions of the same package (e.g., different build strings) # should have the same coefficients. # - a package that only has one version should not appear, unless # include=True as it will have a 0 coefficient. The same is true of the # latest version of a package. eqv = {Dist(key).to_filename(): value for key, value in iteritems(eqv)} eqb = {Dist(key).to_filename(): value for key, value in iteritems(eqb)} assert eqv == { 'anaconda-1.4.0-np15py26_0.tar.bz2': 1, 'anaconda-1.4.0-np15py27_0.tar.bz2': 1, 'anaconda-1.4.0-np16py26_0.tar.bz2': 1, 'anaconda-1.4.0-np16py27_0.tar.bz2': 1, 'anaconda-1.4.0-np17py26_0.tar.bz2': 1, 'anaconda-1.4.0-np17py27_0.tar.bz2': 1, 'anaconda-1.4.0-np17py33_0.tar.bz2': 1, 'astropy-0.2-np15py26_0.tar.bz2': 1, 'astropy-0.2-np15py27_0.tar.bz2': 1, 'astropy-0.2-np16py26_0.tar.bz2': 1, 'astropy-0.2-np16py27_0.tar.bz2': 1, 'astropy-0.2-np17py26_0.tar.bz2': 1, 'astropy-0.2-np17py27_0.tar.bz2': 1, 'astropy-0.2-np17py33_0.tar.bz2': 1, 'biopython-1.60-np15py26_0.tar.bz2': 1, 'biopython-1.60-np15py27_0.tar.bz2': 1, 'biopython-1.60-np16py26_0.tar.bz2': 1, 'biopython-1.60-np16py27_0.tar.bz2': 1, 'biopython-1.60-np17py26_0.tar.bz2': 1, 'biopython-1.60-np17py27_0.tar.bz2': 1, 'bitarray-0.8.0-py26_0.tar.bz2': 1, 'bitarray-0.8.0-py27_0.tar.bz2': 1, 'bitarray-0.8.0-py33_0.tar.bz2': 1, 'boto-2.8.0-py26_0.tar.bz2': 1, 'boto-2.8.0-py27_0.tar.bz2': 1, 'conda-1.4.4-py27_0.tar.bz2': 1, 'cython-0.18-py26_0.tar.bz2': 1, 'cython-0.18-py27_0.tar.bz2': 1, 'cython-0.18-py33_0.tar.bz2': 1, 'distribute-0.6.34-py26_1.tar.bz2': 1, 'distribute-0.6.34-py27_1.tar.bz2': 1, 'distribute-0.6.34-py33_1.tar.bz2': 1, 'gevent-0.13.7-py26_0.tar.bz2': 1, 'gevent-0.13.7-py27_0.tar.bz2': 1, 'ipython-0.13.1-py26_1.tar.bz2': 1, 'ipython-0.13.1-py27_1.tar.bz2': 1, 'ipython-0.13.1-py33_1.tar.bz2': 1, 'llvmpy-0.11.1-py26_0.tar.bz2': 1, 'llvmpy-0.11.1-py27_0.tar.bz2': 1, 'llvmpy-0.11.1-py33_0.tar.bz2': 1, 'lxml-3.0.2-py26_0.tar.bz2': 1, 'lxml-3.0.2-py27_0.tar.bz2': 1, 'lxml-3.0.2-py33_0.tar.bz2': 1, 'matplotlib-1.2.0-np15py26_1.tar.bz2': 1, 'matplotlib-1.2.0-np15py27_1.tar.bz2': 1, 'matplotlib-1.2.0-np16py26_1.tar.bz2': 1, 'matplotlib-1.2.0-np16py27_1.tar.bz2': 1, 'matplotlib-1.2.0-np17py26_1.tar.bz2': 1, 'matplotlib-1.2.0-np17py27_1.tar.bz2': 1, 'matplotlib-1.2.0-np17py33_1.tar.bz2': 1, 'nose-1.2.1-py26_0.tar.bz2': 1, 'nose-1.2.1-py27_0.tar.bz2': 1, 'nose-1.2.1-py33_0.tar.bz2': 1, 'numba-0.7.0-np16py26_1.tar.bz2': 1, 'numba-0.7.0-np16py27_1.tar.bz2': 1, 'numba-0.7.0-np17py26_1.tar.bz2': 1, 'numba-0.7.0-np17py27_1.tar.bz2': 1, 'numpy-1.5.1-py26_3.tar.bz2': 3, 'numpy-1.5.1-py27_3.tar.bz2': 3, 'numpy-1.6.2-py26_3.tar.bz2': 2, 'numpy-1.6.2-py26_4.tar.bz2': 2, 'numpy-1.6.2-py26_p4.tar.bz2': 2, 'numpy-1.6.2-py27_3.tar.bz2': 2, 'numpy-1.6.2-py27_4.tar.bz2': 2, 'numpy-1.6.2-py27_p4.tar.bz2': 2, 'numpy-1.7.0-py26_0.tar.bz2': 1, 'numpy-1.7.0-py27_0.tar.bz2': 1, 'numpy-1.7.0-py33_0.tar.bz2': 1, 'pandas-0.10.0-np16py26_0.tar.bz2': 2, 'pandas-0.10.0-np16py27_0.tar.bz2': 2, 'pandas-0.10.0-np17py26_0.tar.bz2': 2, 'pandas-0.10.0-np17py27_0.tar.bz2': 2, 'pandas-0.10.1-np16py26_0.tar.bz2': 1, 'pandas-0.10.1-np16py27_0.tar.bz2': 1, 'pandas-0.10.1-np17py26_0.tar.bz2': 1, 'pandas-0.10.1-np17py27_0.tar.bz2': 1, 'pandas-0.10.1-np17py33_0.tar.bz2': 1, 'pandas-0.8.1-np16py26_0.tar.bz2': 5, 'pandas-0.8.1-np16py27_0.tar.bz2': 5, 'pandas-0.8.1-np17py26_0.tar.bz2': 5, 'pandas-0.8.1-np17py27_0.tar.bz2': 5, 'pandas-0.9.0-np16py26_0.tar.bz2': 4, 'pandas-0.9.0-np16py27_0.tar.bz2': 4, 'pandas-0.9.0-np17py26_0.tar.bz2': 4, 'pandas-0.9.0-np17py27_0.tar.bz2': 4, 'pandas-0.9.1-np16py26_0.tar.bz2': 3, 'pandas-0.9.1-np16py27_0.tar.bz2': 3, 'pandas-0.9.1-np17py26_0.tar.bz2': 3, 'pandas-0.9.1-np17py27_0.tar.bz2': 3, 'pip-1.2.1-py26_1.tar.bz2': 1, 'pip-1.2.1-py27_1.tar.bz2': 1, 'pip-1.2.1-py33_1.tar.bz2': 1, 'psutil-0.6.1-py26_0.tar.bz2': 1, 'psutil-0.6.1-py27_0.tar.bz2': 1, 'psutil-0.6.1-py33_0.tar.bz2': 1, 'pyflakes-0.6.1-py26_0.tar.bz2': 1, 'pyflakes-0.6.1-py27_0.tar.bz2': 1, 'pyflakes-0.6.1-py33_0.tar.bz2': 1, 'python-2.6.8-6.tar.bz2': 4, 'python-2.7.3-7.tar.bz2': 3, 'python-2.7.4-0.tar.bz2': 2, 'python-3.3.0-4.tar.bz2': 1, 'pytz-2012j-py26_0.tar.bz2': 1, 'pytz-2012j-py27_0.tar.bz2': 1, 'pytz-2012j-py33_0.tar.bz2': 1, 'requests-0.13.9-py26_0.tar.bz2': 1, 'requests-0.13.9-py27_0.tar.bz2': 1, 'requests-0.13.9-py33_0.tar.bz2': 1, 'scikit-learn-0.13-np15py26_1.tar.bz2': 1, 'scikit-learn-0.13-np15py27_1.tar.bz2': 1, 'scikit-learn-0.13-np16py26_1.tar.bz2': 1, 'scikit-learn-0.13-np16py27_1.tar.bz2': 1, 'scikit-learn-0.13-np17py26_1.tar.bz2': 1, 'scikit-learn-0.13-np17py27_1.tar.bz2': 1, 'scipy-0.11.0-np15py26_3.tar.bz2': 1, 'scipy-0.11.0-np15py27_3.tar.bz2': 1, 'scipy-0.11.0-np16py26_3.tar.bz2': 1, 'scipy-0.11.0-np16py27_3.tar.bz2': 1, 'scipy-0.11.0-np17py26_3.tar.bz2': 1, 'scipy-0.11.0-np17py27_3.tar.bz2': 1, 'scipy-0.11.0-np17py33_3.tar.bz2': 1, 'six-1.2.0-py26_0.tar.bz2': 1, 'six-1.2.0-py27_0.tar.bz2': 1, 'six-1.2.0-py33_0.tar.bz2': 1, 'spyder-2.1.13-py27_0.tar.bz2': 1, 'sqlalchemy-0.7.8-py26_0.tar.bz2': 1, 'sqlalchemy-0.7.8-py27_0.tar.bz2': 1, 'sqlalchemy-0.7.8-py33_0.tar.bz2': 1, 'sympy-0.7.1-py26_0.tar.bz2': 1, 'sympy-0.7.1-py27_0.tar.bz2': 1, 'tornado-2.4.1-py26_0.tar.bz2': 1, 'tornado-2.4.1-py27_0.tar.bz2': 1, 'tornado-2.4.1-py33_0.tar.bz2': 1, 'xlrd-0.9.0-py26_0.tar.bz2': 1, 'xlrd-0.9.0-py27_0.tar.bz2': 1, 'xlrd-0.9.0-py33_0.tar.bz2': 1, 'xlwt-0.7.4-py26_0.tar.bz2': 1, 'xlwt-0.7.4-py27_0.tar.bz2': 1} assert eqb == { 'cairo-1.12.2-0.tar.bz2': 1, 'cubes-0.10.2-py27_0.tar.bz2': 1, 'dateutil-2.1-py26_0.tar.bz2': 1, 'dateutil-2.1-py27_0.tar.bz2': 1, 'dateutil-2.1-py33_0.tar.bz2': 1, 'gevent-websocket-0.3.6-py26_1.tar.bz2': 1, 'gevent-websocket-0.3.6-py27_1.tar.bz2': 1, 'gevent_zeromq-0.2.5-py26_1.tar.bz2': 1, 'gevent_zeromq-0.2.5-py27_1.tar.bz2': 1, 'libnetcdf-4.2.1.1-0.tar.bz2': 1, 'numexpr-2.0.1-np16py26_1.tar.bz2': 2, 'numexpr-2.0.1-np16py26_2.tar.bz2': 1, 'numexpr-2.0.1-np16py26_ce0.tar.bz2': 3, 'numexpr-2.0.1-np16py26_p1.tar.bz2': 2, 'numexpr-2.0.1-np16py26_p2.tar.bz2': 1, 'numexpr-2.0.1-np16py26_pro0.tar.bz2': 3, 'numexpr-2.0.1-np16py27_1.tar.bz2': 2, 'numexpr-2.0.1-np16py27_2.tar.bz2': 1, 'numexpr-2.0.1-np16py27_ce0.tar.bz2': 3, 'numexpr-2.0.1-np16py27_p1.tar.bz2': 2, 'numexpr-2.0.1-np16py27_p2.tar.bz2': 1, 'numexpr-2.0.1-np16py27_pro0.tar.bz2': 3, 'numexpr-2.0.1-np17py26_1.tar.bz2': 2, 'numexpr-2.0.1-np17py26_2.tar.bz2': 1, 'numexpr-2.0.1-np17py26_ce0.tar.bz2': 3, 'numexpr-2.0.1-np17py26_p1.tar.bz2': 2, 'numexpr-2.0.1-np17py26_p2.tar.bz2': 1, 'numexpr-2.0.1-np17py26_pro0.tar.bz2': 3, 'numexpr-2.0.1-np17py27_1.tar.bz2': 2, 'numexpr-2.0.1-np17py27_2.tar.bz2': 1, 'numexpr-2.0.1-np17py27_ce0.tar.bz2': 3, 'numexpr-2.0.1-np17py27_p1.tar.bz2': 2, 'numexpr-2.0.1-np17py27_p2.tar.bz2': 1, 'numexpr-2.0.1-np17py27_pro0.tar.bz2': 3, 'numpy-1.6.2-py26_3.tar.bz2': 1, 'numpy-1.6.2-py27_3.tar.bz2': 1, 'py2cairo-1.10.0-py26_0.tar.bz2': 1, 'py2cairo-1.10.0-py27_0.tar.bz2': 1, 'pycurl-7.19.0-py26_0.tar.bz2': 1, 'pycurl-7.19.0-py27_0.tar.bz2': 1, 'pysal-1.5.0-np15py27_0.tar.bz2': 1, 'pysal-1.5.0-np16py27_0.tar.bz2': 1, 'pysal-1.5.0-np17py27_0.tar.bz2': 1, 'pytest-2.3.4-py26_0.tar.bz2': 1, 'pytest-2.3.4-py27_0.tar.bz2': 1, 'pyzmq-2.2.0.1-py26_0.tar.bz2': 1, 'pyzmq-2.2.0.1-py27_0.tar.bz2': 1, 'pyzmq-2.2.0.1-py33_0.tar.bz2': 1, 'scikit-image-0.8.2-np16py26_0.tar.bz2': 1, 'scikit-image-0.8.2-np16py27_0.tar.bz2': 1, 'scikit-image-0.8.2-np17py26_0.tar.bz2': 1, 'scikit-image-0.8.2-np17py27_0.tar.bz2': 1, 'scikit-image-0.8.2-np17py33_0.tar.bz2': 1, 'sphinx-1.1.3-py26_2.tar.bz2': 1, 'sphinx-1.1.3-py27_2.tar.bz2': 1, 'sphinx-1.1.3-py33_2.tar.bz2': 1, 'statsmodels-0.4.3-np16py26_0.tar.bz2': 1, 'statsmodels-0.4.3-np16py27_0.tar.bz2': 1, 'statsmodels-0.4.3-np17py26_0.tar.bz2': 1, 'statsmodels-0.4.3-np17py27_0.tar.bz2': 1, 'system-5.8-0.tar.bz2': 1, 'theano-0.5.0-np15py26_0.tar.bz2': 1, 'theano-0.5.0-np15py27_0.tar.bz2': 1, 'theano-0.5.0-np16py26_0.tar.bz2': 1, 'theano-0.5.0-np16py27_0.tar.bz2': 1, 'theano-0.5.0-np17py26_0.tar.bz2': 1, 'theano-0.5.0-np17py27_0.tar.bz2': 1, 'zeromq-2.2.0-0.tar.bz2': 1}
def test_anaconda_nomkl(self): dists = r.install(['anaconda 1.5.0', 'python 2.7*', 'numpy 1.7*']) self.assertEqual(len(dists), 107) self.assertTrue(Dist('defaults::scipy-0.12.0-np17py27_0.tar.bz2') in dists)
def test_get_dists(): dists = r.get_reduced_index(["anaconda 1.5.0"]) assert Dist('defaults::anaconda-1.5.0-np17py27_0.tar.bz2') in dists assert Dist('defaults::dynd-python-0.3.0-np17py33_0.tar.bz2') in dists
class TestAddUnlinkOptionsForUpdate(unittest.TestCase): def setUp(self): pkgs = [(None, "test1", "default", "1.0.1"), ("env", "test1", "default", "2.1.4"), ("env", "test2", "default", "1.1.1"), (None, "test3", "default", "1.2.0"), (None, "test4", "default", "1.2.1")] self.res = generate_mocked_resolve(pkgs) @patch("conda.plan.remove_actions", return_value=generate_remove_action("root/prefix", [Dist("test1-2.1.4-1")])) def test_update_in_private_env_add_remove_action(self, remove_actions): required_solves = [ plan.SpecsForPrefix(prefix="root/prefix/envs/_env_", specs=["test1", "test2"], r=self.res), plan.SpecsForPrefix(prefix=context.root_dir, specs=["test3"], r=self.res) ] action = defaultdict(list) action["PREFIX"] = "root/prefix/envs/_env_" action["LINK"] = [Dist("test1-2.1.4-1"), Dist("test2-1.1.1-8")] actions = [action] test_link_data = {context.root_prefix: {Dist("test1-2.1.4-1"): True}} with patch("conda.core.linked_data.linked_data_", test_link_data): plan.add_unlink_options_for_update(actions, required_solves, self.res.index) expected_output = [ action, generate_remove_action("root/prefix", [Dist("test1-2.1.4-1")]) ] self.assertEquals(actions, expected_output) @patch("conda.plan.remove_actions", return_value=generate_remove_action("root/prefix", [Dist("test1-2.1.4-1")])) def test_update_in_private_env_append_unlink(self, remove_actions): required_solves = [ plan.SpecsForPrefix(prefix="root/prefix/envs/_env_", specs=["test1", "test2"], r=self.res), plan.SpecsForPrefix(prefix=context.root_prefix, specs=["whatevs"], r=self.res) ] action = defaultdict(list) action["PREFIX"] = "root/prefix/envs/_env_" action["LINK"] = [Dist("test1-2.1.4-1"), Dist("test2-1.1.1-8")] action_root = defaultdict(list) action_root["PREFIX"] = context.root_prefix action_root["LINK"] = [Dist("whatevs-54-54")] actions = [action, action_root] test_link_data = {context.root_prefix: {Dist("test1-2.1.4-1"): True}} with patch("conda.core.linked_data.linked_data_", test_link_data): plan.add_unlink_options_for_update(actions, required_solves, self.res.index) aug_action_root = defaultdict(list) aug_action_root["PREFIX"] = context.root_prefix aug_action_root["LINK"] = [Dist("whatevs-54-54")] aug_action_root["UNLINK"] = [Dist("test1-2.1.4-1")] expected_output = [action, aug_action_root] self.assertEquals(actions, expected_output) @patch("conda.cli.common.get_private_envs_json", return_value={ "test3-1.2.0": "some/prefix/envs/_env_", "test4-2.1.0-22": "some/prefix/envs/_env_" }) def test_update_in_root_env(self, prefix_if_in_private_env): required_solves = [ plan.SpecsForPrefix(prefix=context.root_dir, specs=["test3", "test4"], r=self.res) ] action = defaultdict(list) action["PREFIX"] = "root/prefix" action["LINK"] = [Dist("test3-1.2.0"), Dist("test4-1.2.1")] actions = [action] plan.add_unlink_options_for_update(actions, required_solves, self.res.index) expected_output = [ action, generate_remove_action( "some/prefix/envs/_env_", [Dist("test3-1.2.0"), Dist("test4-2.1.0-22")]) ] self.assertEquals(actions, expected_output)
def test_scipy_mkl(self): dists = r.install(['scipy', 'python 2.7*', 'numpy 1.7*', 'mkl@']) self.assert_have_mkl(dists, ('numpy', 'scipy')) self.assertTrue(Dist('defaults::scipy-0.12.0-np17py27_p0.tar.bz2') in dists)
def test_no_features(): # Without this, there would be another solution including 'scipy-0.11.0-np16py26_p3.tar.bz2'. assert r.install(['python 2.6*', 'numpy 1.6*', 'scipy 0.11*'], returnall=True) == [[Dist(add_defaults_if_no_channel(fname)) for fname in [ 'numpy-1.6.2-py26_4.tar.bz2', 'openssl-1.0.1c-0.tar.bz2', 'python-2.6.8-6.tar.bz2', 'readline-6.2-0.tar.bz2', 'scipy-0.11.0-np16py26_3.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(['python 2.6*', 'numpy 1.6*', 'scipy 0.11*', 'mkl@'], returnall=True) == [[Dist(add_defaults_if_no_channel(fname)) for fname in [ 'mkl-rt-11.0-p0.tar.bz2', # This, 'numpy-1.6.2-py26_p4.tar.bz2', # this, 'openssl-1.0.1c-0.tar.bz2', 'python-2.6.8-6.tar.bz2', 'readline-6.2-0.tar.bz2', 'scipy-0.11.0-np16py26_p3.tar.bz2', # and this are different. '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', ]]] index2 = index.copy() index2["defaults::pandas-0.12.0-np16py27_0.tar.bz2"] = IndexRecord(**{ "build": "np16py27_0", "build_number": 0, "depends": [ "dateutil", "numpy 1.6*", "python 2.7*", "pytz" ], "name": "pandas", "requires": [ "dateutil 1.5", "numpy 1.6", "python 2.7", "pytz" ], "version": "0.12.0" }) # Make it want to choose the pro version by having it be newer. index2["defaults::numpy-1.6.2-py27_p5.tar.bz2"] = IndexRecord(**{ "build": "py27_p5", "build_number": 5, "depends": [ "mkl-rt 11.0", "python 2.7*" ], "features": "mkl", "name": "numpy", "pub_date": "2013-04-29", "requires": [ "mkl-rt 11.0", "python 2.7" ], "version": "1.6.2" }) index2 = {Dist(key): value for key, value in iteritems(index2)} r2 = Resolve(index2) # This should not pick any mkl packages (the difference here is that none # of the specs directly have mkl versions) assert r2.solve(['pandas 0.12.0 np16py27_0', 'python 2.7*'], returnall=True) == [[Dist(add_defaults_if_no_channel(fname)) for fname in [ 'dateutil-2.1-py27_1.tar.bz2', 'numpy-1.6.2-py27_4.tar.bz2', 'openssl-1.0.1c-0.tar.bz2', 'pandas-0.12.0-np16py27_0.tar.bz2', 'python-2.7.5-0.tar.bz2', 'pytz-2013b-py27_0.tar.bz2', 'readline-6.2-0.tar.bz2', 'six-1.3.0-py27_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 r2.solve(['pandas 0.12.0 np16py27_0', 'python 2.7*', 'mkl@'], returnall=True)[0] == [[Dist(add_defaults_if_no_channel(fname)) for fname in [ 'dateutil-2.1-py27_1.tar.bz2', 'mkl-rt-11.0-p0.tar.bz2', # This 'numpy-1.6.2-py27_p5.tar.bz2', # and this are different. 'openssl-1.0.1c-0.tar.bz2', 'pandas-0.12.0-np16py27_0.tar.bz2', 'python-2.7.5-0.tar.bz2', 'pytz-2013b-py27_0.tar.bz2', 'readline-6.2-0.tar.bz2', 'six-1.3.0-py27_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', ]]][0]
def test_dist(self): with env_unmodified(conda_tests_ctxt_mgmt_def_pol): dst = Dist('defaults::foo-1.2.3-4.tar.bz2') a = MatchSpec(dst) b = MatchSpec(a) c = MatchSpec(dst, optional=True, target='burg') d = MatchSpec(a, build='5') assert a == b assert hash(a) == hash(b) assert a is b assert a != c assert hash(a) != hash(c) assert a != d assert hash(a) != hash(d) p = MatchSpec(channel='defaults', name='python', version=VersionSpec('3.5*')) assert p.match( Dist(channel='defaults', dist_name='python-3.5.3-1', name='python', version='3.5.3', build_string='1', build_number=1, base_url=None, platform=None)) assert not p.match( Dist(channel='defaults', dist_name='python-3.6.0-0', name='python', version='3.6.0', build_string='0', build_number=0, base_url=None, platform=None)) assert p.match( Dist(channel='defaults', dist_name='python-3.5.1-0', name='python', version='3.5.1', build_string='0', build_number=0, base_url=None, platform=None)) assert p.match( PackageRecord( name='python', version='3.5.1', build='0', build_number=0, depends=('openssl 1.0.2*', 'readline 6.2*', 'sqlite', 'tk 8.5*', 'xz 5.0.5', 'zlib 1.2*', 'pip'), channel=Channel(scheme='https', auth=None, location='repo.anaconda.com', token=None, name='pkgs/main', platform='osx-64', package_filename=None), subdir='osx-64', fn='python-3.5.1-0.tar.bz2', md5='a813bc0a32691ab3331ac9f37125164c', size=14678857, priority=0, url= 'https://repo.anaconda.com/pkgs/main/osx-64/python-3.5.1-0.tar.bz2' ))
def setUp(self): self.linked_in_root = { Dist("test1-1.2.3-bs_7"): generate_mocked_record("test1-1.2.3-bs_7") }
def test_match(self): for spec, res in [ ('numpy 1.7*', True), ('numpy 1.7.1', True), ('numpy 1.7', False), ('numpy 1.5*', False), ('numpy >=1.5', True), ('numpy >=1.5,<2', True), ('numpy >=1.8,<1.9', False), ('numpy >1.5,<2,!=1.7.1', False), ('numpy >1.8,<2|==1.7', False), ('numpy >1.8,<2|>=1.7.1', True), ('numpy >=1.8|1.7*', True), ('numpy ==1.7', False), ('numpy >=1.5,>1.6', True), ('numpy ==1.7.1', True), ('numpy >=1,*.7.*', True), ('numpy *.7.*,>=1', True), ('numpy >=1,*.8.*', False), ('numpy >=2,*.7.*', False), ('numpy 1.6*|1.7*', True), ('numpy 1.6*|1.8*', False), ('numpy 1.6.2|1.7*', True), ('numpy 1.6.2|1.7.1', True), ('numpy 1.6.2|1.7.0', False), ('numpy 1.7.1 py27_0', True), ('numpy 1.7.1 py26_0', False), ('numpy >1.7.1a', True), ('python', False), ]: m = MatchSpec(spec) self.assertEqual(m.match(Dist('numpy-1.7.1-py27_0.tar.bz2')), res) # both version numbers conforming to PEP 440 self.assertFalse( MatchSpec('numpy >=1.0.1').match(Dist('numpy-1.0.1a-0.tar.bz2'))) # both version numbers non-conforming to PEP 440 self.assertFalse( MatchSpec('numpy >=1.0.1.vc11').match( Dist('numpy-1.0.1a.vc11-0.tar.bz2'))) self.assertTrue( MatchSpec('numpy >=1.0.1*.vc11').match( Dist('numpy-1.0.1a.vc11-0.tar.bz2'))) # one conforming, other non-conforming to PEP 440 self.assertTrue( MatchSpec('numpy <1.0.1').match( Dist('numpy-1.0.1.vc11-0.tar.bz2'))) self.assertTrue( MatchSpec('numpy <1.0.1').match( Dist('numpy-1.0.1a.vc11-0.tar.bz2'))) self.assertFalse( MatchSpec('numpy >=1.0.1.vc11').match( Dist('numpy-1.0.1a-0.tar.bz2'))) self.assertTrue( MatchSpec('numpy >=1.0.1a').match(Dist('numpy-1.0.1z-0.tar.bz2'))) self.assertTrue( MatchSpec('numpy >=1.0.1a py27*').match( Dist('numpy-1.0.1z-py27_1.tar.bz2'))) self.assertTrue( MatchSpec('blas * openblas').match( Dist('blas-1.0-openblas.tar.bz2'))) self.assertTrue(MatchSpec('blas').is_simple()) self.assertFalse(MatchSpec('blas').is_exact()) self.assertFalse(MatchSpec('blas 1.0').is_simple()) self.assertFalse(MatchSpec('blas 1.0').is_exact()) self.assertFalse(MatchSpec('blas 1.0 1').is_simple()) self.assertTrue(MatchSpec('blas 1.0 1').is_exact()) self.assertFalse(MatchSpec('blas 1.0 *').is_exact()) m = MatchSpec('blas 1.0', optional=True) m2 = MatchSpec(m, optional=False) m3 = MatchSpec(m2, target='blas-1.0-0.tar.bz2') m4 = MatchSpec(m3, target=None, optional=True) self.assertTrue(m.spec == m2.spec and m.optional != m2.optional) self.assertTrue(m2.spec == m3.spec and m2.optional == m3.optional and m2.target != m3.target) self.assertTrue(m == m4) self.assertRaises(ValueError, MatchSpec, 'blas (optional') self.assertRaises(ValueError, MatchSpec, 'blas (optional,test)')
def clone_env(prefix1, prefix2, verbose=True, quiet=False, index_args=None): """ clone existing prefix1 into new prefix2 """ untracked_files = untracked(prefix1) # Discard conda and any package that depends on it drecs = linked_data(prefix1) filter = {} found = True while found: found = False for dist, info in iteritems(drecs): name = info['name'] if name in filter: continue if name == 'conda': filter['conda'] = dist found = True break for dep in info.get('depends', []): if MatchSpec(dep).name in filter: filter[name] = dist found = True if filter: if not quiet: print( 'The following packages cannot be cloned out of the root environment:' ) for pkg in itervalues(filter): print(' - ' + pkg) drecs = { dist: info for dist, info in iteritems(drecs) if info['name'] not in filter } # Resolve URLs for packages that do not have URLs r = None index = {} unknowns = [dist for dist, info in iteritems(drecs) if not info.get('url')] notfound = [] if unknowns: index_args = index_args or {} index = get_index(**index_args) r = Resolve(index, sort=True) for dist in unknowns: name = dist.dist_name fn = dist.to_filename() fkeys = [d for d in r.index.keys() if r.index[d]['fn'] == fn] if fkeys: del drecs[dist] dist_str = sorted(fkeys, key=r.version_key, reverse=True)[0] drecs[Dist(dist_str)] = r.index[dist_str] else: notfound.append(fn) if notfound: what = "Package%s " % ('' if len(notfound) == 1 else 's') notfound = '\n'.join(' - ' + fn for fn in notfound) msg = '%s missing in current %s channels:%s' % (what, context.subdir, notfound) raise CondaRuntimeError(msg) # Assemble the URL and channel list urls = {} for dist, info in iteritems(drecs): fkey = dist if fkey not in index: info['not_fetched'] = True index[fkey] = info r = None urls[dist] = info['url'] if r is None: r = Resolve(index) dists = r.dependency_sort({d.quad[0]: d for d in urls.keys()}) urls = [urls[d] for d in dists] if verbose: print('Packages: %d' % len(dists)) print('Files: %d' % len(untracked_files)) for f in untracked_files: src = join(prefix1, f) dst = join(prefix2, f) dst_dir = dirname(dst) if islink(dst_dir) or isfile(dst_dir): rm_rf(dst_dir) if not isdir(dst_dir): os.makedirs(dst_dir) if islink(src): os.symlink(os.readlink(src), dst) continue try: with open(src, 'rb') as fi: data = fi.read() except IOError: continue try: s = data.decode('utf-8') s = s.replace(prefix1, prefix2) data = s.encode('utf-8') except UnicodeDecodeError: # data is binary pass with open(dst, 'wb') as fo: fo.write(data) shutil.copystat(src, dst) actions = explicit(urls, prefix2, verbose=not quiet, index=index, force_extract=False, index_args=index_args) return actions, untracked_files
def explicit(specs, prefix, verbose=False, force_extract=True, index_args=None, index=None): actions = defaultdict(list) actions['PREFIX'] = prefix actions[ 'op_order'] = RM_FETCHED, FETCH, RM_EXTRACTED, EXTRACT, UNLINK, LINK, SYMLINK_CONDA linked = {dist.dist_name: dist for dist in install_linked(prefix)} index_args = index_args or {} index = index or {} verifies = [] # List[Tuple(filename, md5)] channels = set() for spec in specs: if spec == '@EXPLICIT': continue # Format: (url|path)(:#md5)? m = url_pat.match(spec) if m is None: raise ParseError('Could not parse explicit URL: %s' % spec) url_p, fn, md5 = m.group('url_p'), m.group('fn'), m.group('md5') if not is_url(url_p): if url_p is None: url_p = curdir elif not isdir(url_p): raise CondaFileNotFoundError(join(url_p, fn)) url_p = path_to_url(url_p).rstrip('/') url = "{0}/{1}".format(url_p, fn) # is_local: if the tarball is stored locally (file://) # is_cache: if the tarball is sitting in our cache is_local = not is_url(url) or url.startswith('file://') prefix = cached_url(url) if is_local else None is_cache = prefix is not None if is_cache: # Channel information from the cache schannel = DEFAULTS if prefix == '' else prefix[:-2] else: # Channel information from the URL channel, schannel = Channel(url).url_channel_wtf prefix = '' if schannel == DEFAULTS else schannel + '::' fn = prefix + fn dist = Dist(fn[:-8]) # Add explicit file to index so we'll be sure to see it later if is_local: index[dist] = Record( **{ 'fn': dist.to_filename(), 'url': url, 'md5': md5, 'build': dist.quad[2], 'build_number': dist.build_number(), 'name': dist.quad[0], 'version': dist.quad[1], }) verifies.append((fn, md5)) pkg_path = is_fetched(dist) dir_path = is_extracted(dist) # Don't re-fetch unless there is an MD5 mismatch # Also remove explicit tarballs from cache, unless the path *is* to the cache if pkg_path and not is_cache and (is_local or md5 and md5_file(pkg_path) != md5): # This removes any extracted copies as well actions[RM_FETCHED].append(dist) pkg_path = dir_path = None # Don't re-extract unless forced, or if we can't check the md5 if dir_path and (force_extract or md5 and not pkg_path): actions[RM_EXTRACTED].append(dist) dir_path = None if not dir_path: if not pkg_path: pkg_path, conflict = find_new_location(dist) pkg_path = join(pkg_path, dist.to_filename()) if conflict: actions[RM_FETCHED].append(Dist(conflict)) if not is_local: if dist not in index or index[dist].get('not_fetched'): channels.add(schannel) verifies.append((dist.to_filename(), md5)) actions[FETCH].append(dist) actions[EXTRACT].append(dist) # unlink any installed package with that name name = dist.dist_name if name in linked: actions[UNLINK].append(linked[name]) ###################################### # copied from conda/plan.py TODO: refactor ###################################### # check for link action fetched_dist = dir_path or pkg_path[:-8] fetched_dir = dirname(fetched_dist) try: # Determine what kind of linking is necessary if not dir_path: # If not already extracted, create some dummy # data to test with rm_rf(fetched_dist) ppath = join(fetched_dist, 'info') os.makedirs(ppath) index_json = join(ppath, 'index.json') with open(index_json, 'w'): pass if context.always_copy: lt = LINK_COPY elif try_hard_link(fetched_dir, prefix, dist): lt = LINK_HARD elif context.allow_softlinks and not on_win: lt = LINK_SOFT else: lt = LINK_COPY actions[LINK].append('%s %d' % (dist, lt)) except (OSError, IOError): actions[LINK].append('%s %d' % (dist, LINK_COPY)) finally: if not dir_path: # Remove the dummy data try: rm_rf(fetched_dist) except (OSError, IOError): pass ###################################### # ^^^^^^^^^^ copied from conda/plan.py ###################################### # Pull the repodata for channels we are using if channels: index_args = index_args or {} index_args = index_args.copy() index_args['prepend'] = False index_args['channel_urls'] = list(channels) index.update(get_index(**index_args)) # Finish the MD5 verification for fn, md5 in verifies: info = index.get(Dist(fn)) if info is None: raise PackageNotFoundError(fn, "no package '%s' in index" % fn) if md5 and 'md5' not in info: sys.stderr.write('Warning: cannot lookup MD5 of: %s' % fn) if md5 and info['md5'] != md5: raise MD5MismatchError( 'MD5 mismatch for: %s\n spec: %s\n repo: %s' % (fn, md5, info['md5'])) execute_actions(actions, index=index, verbose=verbose) return actions
def UNLINK_CMD(state, arg): log.debug("=======> UNLINKING %s <=======", arg) dist = Dist(arg) unlink(state['prefix'], dist)
def LINK_CMD(state, arg): dist, lt = split_linkarg(arg) dist = Dist(dist) log.debug("=======> LINKING %s <=======", dist) link(state['prefix'], dist, lt, index=state['index'])
def test_display_actions(): os.environ['CONDA_SHOW_CHANNEL_URLS'] = 'False' reset_context(()) actions = defaultdict( list, {"FETCH": [Dist('sympy-0.7.2-py27_0'), Dist("numpy-1.7.1-py27_0")]}) # The older test index doesn't have the size metadata d = Dist.from_string('sympy-0.7.2-py27_0.tar.bz2') index[d] = IndexRecord.from_objects(index[d], size=4374752) d = Dist.from_string("numpy-1.7.1-py27_0.tar.bz2") index[d] = IndexRecord.from_objects(index[d], size=5994338) with captured() as c: display_actions(actions, index) assert c.stdout == """ The following packages will be downloaded: package | build ---------------------------|----------------- sympy-0.7.2 | py27_0 4.2 MB numpy-1.7.1 | py27_0 5.7 MB ------------------------------------------------------------ Total: 9.9 MB """ actions = defaultdict( list, { 'PREFIX': '/Users/aaronmeurer/anaconda/envs/test', 'SYMLINK_CONDA': ['/Users/aaronmeurer/anaconda'], 'LINK': [ 'python-3.3.2-0', 'readline-6.2-0 1', 'sqlite-3.7.13-0 1', 'tk-8.5.13-0 1', 'zlib-1.2.7-0 1' ] }) with captured() as c: display_actions(actions, index) assert c.stdout == """ The following NEW packages will be INSTALLED: python: 3.3.2-0 \n\ readline: 6.2-0 \n\ sqlite: 3.7.13-0 tk: 8.5.13-0 zlib: 1.2.7-0 \n\ """ actions['UNLINK'] = actions['LINK'] actions['LINK'] = [] with captured() as c: display_actions(actions, index) assert c.stdout == """ The following packages will be REMOVED: python: 3.3.2-0 \n\ readline: 6.2-0 \n\ sqlite: 3.7.13-0 tk: 8.5.13-0 zlib: 1.2.7-0 \n\ """ actions = defaultdict(list, { 'LINK': ['cython-0.19.1-py33_0'], 'UNLINK': ['cython-0.19-py33_0'] }) with captured() as c: display_actions(actions, index) assert c.stdout == """ The following packages will be UPDATED: cython: 0.19-py33_0 --> 0.19.1-py33_0 """ actions['LINK'], actions['UNLINK'] = actions['UNLINK'], actions['LINK'] with captured() as c: display_actions(actions, index) assert c.stdout == """ The following packages will be DOWNGRADED due to dependency conflicts: cython: 0.19.1-py33_0 --> 0.19-py33_0 """ actions = defaultdict( list, { 'LINK': [ 'cython-0.19.1-py33_0', 'dateutil-1.5-py33_0', 'numpy-1.7.1-py33_0' ], 'UNLINK': ['cython-0.19-py33_0', 'dateutil-2.1-py33_1', 'pip-1.3.1-py33_1'] }) with captured() as c: display_actions(actions, index) assert c.stdout == """ The following NEW packages will be INSTALLED: numpy: 1.7.1-py33_0 The following packages will be REMOVED: pip: 1.3.1-py33_1 The following packages will be UPDATED: cython: 0.19-py33_0 --> 0.19.1-py33_0 The following packages will be DOWNGRADED due to dependency conflicts: dateutil: 2.1-py33_1 --> 1.5-py33_0 \n\ """ actions = defaultdict( list, { 'LINK': ['cython-0.19.1-py33_0', 'dateutil-2.1-py33_1'], 'UNLINK': ['cython-0.19-py33_0', 'dateutil-1.5-py33_0'] }) with captured() as c: display_actions(actions, index) assert c.stdout == """ The following packages will be UPDATED: cython: 0.19-py33_0 --> 0.19.1-py33_0 dateutil: 1.5-py33_0 --> 2.1-py33_1 \n\ """ actions['LINK'], actions['UNLINK'] = actions['UNLINK'], actions['LINK'] with captured() as c: display_actions(actions, index) assert c.stdout == """
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_different_names(self): pkgs = [ Package(fn, r.index[Dist(fn)]) for fn in ['llvm-3.1-1.tar.bz2', 'python-2.7.5-0.tar.bz2'] ] self.assertRaises(TypeError, pkgs.sort)
from conda.common.compat import iteritems, text_type from conda.exceptions import NoPackagesFoundError, UnsatisfiableError from conda.models.dist import Dist from conda.models.index_record import IndexRecord from conda.resolve import MatchSpec, Resolve from conda.models.package import Package from os.path import dirname, join import pytest from conda.resolve import MatchSpec, Package, Resolve, NoPackagesFound, Unsatisfiable from tests.helpers import raises with open(join(dirname(__file__), 'index.json')) as fi: index = { Dist(key): IndexRecord(**value) for key, value in iteritems(json.load(fi)) } r = Resolve(index) f_mkl = set(['mkl']) class TestMatchSpec(unittest.TestCase): def test_match(self): for spec, res in [ ('numpy 1.7*', True), ('numpy 1.7.1', True), ('numpy 1.7', False), ('numpy 1.5*', False),
def test_display_actions_show_channel_urls(): os.environ['CONDA_SHOW_CHANNEL_URLS'] = 'True' reset_context(()) actions = defaultdict( list, {"FETCH": ['sympy-0.7.2-py27_0', "numpy-1.7.1-py27_0"]}) # The older test index doesn't have the size metadata d = Dist('sympy-0.7.2-py27_0.tar.bz2') index[d] = IndexRecord.from_objects(d, size=4374752) d = Dist('numpy-1.7.1-py27_0.tar.bz2') index[d] = IndexRecord.from_objects(d, size=5994338) with captured() as c: display_actions(actions, index) assert c.stdout == """ The following packages will be downloaded: package | build ---------------------------|----------------- sympy-0.7.2 | py27_0 4.2 MB <unknown> numpy-1.7.1 | py27_0 5.7 MB <unknown> ------------------------------------------------------------ Total: 9.9 MB """ actions = defaultdict( list, { 'PREFIX': '/Users/aaronmeurer/anaconda/envs/test', 'SYMLINK_CONDA': ['/Users/aaronmeurer/anaconda'], 'LINK': [ 'python-3.3.2-0', 'readline-6.2-0', 'sqlite-3.7.13-0', 'tk-8.5.13-0', 'zlib-1.2.7-0' ] }) with captured() as c: display_actions(actions, index) assert c.stdout == """Package plan for environment '/Users/aaronmeurer/anaconda/envs/test': The following NEW packages will be INSTALLED: python: 3.3.2-0 <unknown> readline: 6.2-0 <unknown> sqlite: 3.7.13-0 <unknown> tk: 8.5.13-0 <unknown> zlib: 1.2.7-0 <unknown> """ actions['UNLINK'] = actions['LINK'] actions['LINK'] = [] with captured() as c: display_actions(actions, index) assert c.stdout == """Package plan for environment '/Users/aaronmeurer/anaconda/envs/test': The following packages will be REMOVED: python: 3.3.2-0 <unknown> readline: 6.2-0 <unknown> sqlite: 3.7.13-0 <unknown> tk: 8.5.13-0 <unknown> zlib: 1.2.7-0 <unknown> """ actions = defaultdict(list, { 'LINK': ['cython-0.19.1-py33_0'], 'UNLINK': ['cython-0.19-py33_0'] }) with captured() as c: display_actions(actions, index) assert c.stdout == """ The following packages will be UPDATED: cython: 0.19-py33_0 <unknown> --> 0.19.1-py33_0 <unknown> """ actions['LINK'], actions['UNLINK'] = actions['UNLINK'], actions['LINK'] with captured() as c: display_actions(actions, index) assert c.stdout == """ The following packages will be DOWNGRADED: cython: 0.19.1-py33_0 <unknown> --> 0.19-py33_0 <unknown> """ actions = defaultdict( list, { 'LINK': [ 'cython-0.19.1-py33_0', 'dateutil-1.5-py33_0', 'numpy-1.7.1-py33_0' ], 'UNLINK': ['cython-0.19-py33_0', 'dateutil-2.1-py33_1', 'pip-1.3.1-py33_1'] }) with captured() as c: display_actions(actions, index) assert c.stdout == """ The following NEW packages will be INSTALLED: numpy: 1.7.1-py33_0 <unknown> The following packages will be REMOVED: pip: 1.3.1-py33_1 <unknown> The following packages will be UPDATED: cython: 0.19-py33_0 <unknown> --> 0.19.1-py33_0 <unknown> The following packages will be DOWNGRADED: dateutil: 2.1-py33_1 <unknown> --> 1.5-py33_0 <unknown> """ actions = defaultdict( list, { 'LINK': ['cython-0.19.1-py33_0', 'dateutil-2.1-py33_1'], 'UNLINK': ['cython-0.19-py33_0', 'dateutil-1.5-py33_0'] }) with captured() as c: display_actions(actions, index) assert c.stdout == """ The following packages will be UPDATED: cython: 0.19-py33_0 <unknown> --> 0.19.1-py33_0 <unknown> dateutil: 1.5-py33_0 <unknown> --> 2.1-py33_1 <unknown> """ actions['LINK'], actions['UNLINK'] = actions['UNLINK'], actions['LINK'] with captured() as c: display_actions(actions, index) assert c.stdout == """ The following packages will be DOWNGRADED: cython: 0.19.1-py33_0 <unknown> --> 0.19-py33_0 <unknown> dateutil: 2.1-py33_1 <unknown> --> 1.5-py33_0 <unknown> """ actions['LINK'], actions['UNLINK'] = actions['UNLINK'], actions['LINK'] d = Dist('cython-0.19.1-py33_0.tar.bz2') index[d] = IndexRecord.from_objects(d, channel='my_channel') d = Dist('dateutil-1.5-py33_0.tar.bz2') index[d] = IndexRecord.from_objects(d, channel='my_channel') with captured() as c: display_actions(actions, index) assert c.stdout == """ The following packages will be UPDATED: cython: 0.19-py33_0 <unknown> --> 0.19.1-py33_0 my_channel dateutil: 1.5-py33_0 my_channel --> 2.1-py33_1 <unknown> \n\ """ actions['LINK'], actions['UNLINK'] = actions['UNLINK'], actions['LINK'] with captured() as c: display_actions(actions, index) assert c.stdout == """
def test_dist_with_channel_url(self): # standard named channel url = "https://repo.anaconda.com/pkgs/free/win-64/spyder-app-2.3.8-py27_0.tar.bz2" d = Dist(url) assert d.channel == 'defaults' assert d.name == 'spyder-app' assert d.version == '2.3.8' assert d.build_string == 'py27_0' assert d.to_url() == url assert d.is_channel is True # standard url channel url = "https://not.real.continuum.io/pkgs/free/win-64/spyder-app-2.3.8-py27_0.tar.bz2" d = Dist(url) assert d.channel == 'defaults' # because pkgs/anaconda is in defaults assert d.name == 'spyder-app' assert d.version == '2.3.8' assert d.build_string == 'py27_0' assert d.to_url() == url assert d.is_channel is True # another standard url channel url = "https://not.real.continuum.io/not/anaconda/win-64/spyder-app-2.3.8-py27_0.tar.bz2" d = Dist(url) assert d.channel == 'https://not.real.continuum.io/not/anaconda' assert d.name == 'spyder-app' assert d.version == '2.3.8' assert d.build_string == 'py27_0' assert d.to_url() == url assert d.is_channel is True # local file url that is a named channel conda_bld_path = join(gettempdir(), 'conda-bld') try: mkdir_p(conda_bld_path) with env_var('CONDA_BLD_PATH', conda_bld_path, reset_context): url = path_to_url( join_url(context.croot, 'osx-64', 'bcrypt-3.1.1-py35_2.tar.bz2')) d = Dist(url) assert d.channel == 'local' assert d.name == 'bcrypt' assert d.version == '3.1.1' assert d.build_string == 'py35_2' assert d.to_url() == url assert d.is_channel is True finally: rm_rf(conda_bld_path) # local file url that is not a named channel url = join_url('file:///some/location/on/disk', 'osx-64', 'bcrypt-3.1.1-py35_2.tar.bz2') d = Dist(url) assert d.channel == 'file:///some/location/on/disk' assert d.name == 'bcrypt' assert d.version == '3.1.1' assert d.build_string == 'py35_2' assert d.to_url() == url assert d.is_channel is True
def test_display_actions_link_type(): os.environ['CONDA_SHOW_CHANNEL_URLS'] = 'False' reset_context(()) actions = defaultdict( list, { 'LINK': [ 'cython-0.19.1-py33_0 2', 'dateutil-1.5-py33_0 2', 'numpy-1.7.1-py33_0 2', 'python-3.3.2-0 2', 'readline-6.2-0 2', 'sqlite-3.7.13-0 2', 'tk-8.5.13-0 2', 'zlib-1.2.7-0 2' ] }) with captured() as c: display_actions(actions, index) assert c.stdout == """ The following NEW packages will be INSTALLED: cython: 0.19.1-py33_0 (softlink) dateutil: 1.5-py33_0 (softlink) numpy: 1.7.1-py33_0 (softlink) python: 3.3.2-0 (softlink) readline: 6.2-0 (softlink) sqlite: 3.7.13-0 (softlink) tk: 8.5.13-0 (softlink) zlib: 1.2.7-0 (softlink) """ actions = defaultdict( list, { 'LINK': ['cython-0.19.1-py33_0 2', 'dateutil-2.1-py33_1 2'], 'UNLINK': ['cython-0.19-py33_0', 'dateutil-1.5-py33_0'] }) with captured() as c: display_actions(actions, index) assert c.stdout == """ The following packages will be UPDATED: cython: 0.19-py33_0 --> 0.19.1-py33_0 (softlink) dateutil: 1.5-py33_0 --> 2.1-py33_1 (softlink) """ actions = defaultdict( list, { 'LINK': ['cython-0.19-py33_0 2', 'dateutil-1.5-py33_0 2'], 'UNLINK': ['cython-0.19.1-py33_0', 'dateutil-2.1-py33_1'] }) with captured() as c: display_actions(actions, index) assert c.stdout == """ The following packages will be DOWNGRADED: cython: 0.19.1-py33_0 --> 0.19-py33_0 (softlink) dateutil: 2.1-py33_1 --> 1.5-py33_0 (softlink) """ actions = defaultdict( list, { 'LINK': [ 'cython-0.19.1-py33_0 1', 'dateutil-1.5-py33_0 1', 'numpy-1.7.1-py33_0 1', 'python-3.3.2-0 1', 'readline-6.2-0 1', 'sqlite-3.7.13-0 1', 'tk-8.5.13-0 1', 'zlib-1.2.7-0 1' ] }) with captured() as c: display_actions(actions, index) assert c.stdout == """ The following NEW packages will be INSTALLED: cython: 0.19.1-py33_0 dateutil: 1.5-py33_0 \n\ numpy: 1.7.1-py33_0 \n\ python: 3.3.2-0 \n\ readline: 6.2-0 \n\ sqlite: 3.7.13-0 \n\ tk: 8.5.13-0 \n\ zlib: 1.2.7-0 \n\ """ actions = defaultdict( list, { 'LINK': ['cython-0.19.1-py33_0 1', 'dateutil-2.1-py33_1 1'], 'UNLINK': ['cython-0.19-py33_0', 'dateutil-1.5-py33_0'] }) with captured() as c: display_actions(actions, index) assert c.stdout == """ The following packages will be UPDATED: cython: 0.19-py33_0 --> 0.19.1-py33_0 dateutil: 1.5-py33_0 --> 2.1-py33_1 \n\ """ actions = defaultdict( list, { 'LINK': ['cython-0.19-py33_0 1', 'dateutil-1.5-py33_0 1'], 'UNLINK': ['cython-0.19.1-py33_0', 'dateutil-2.1-py33_1'] }) with captured() as c: display_actions(actions, index) assert c.stdout == """ The following packages will be DOWNGRADED: cython: 0.19.1-py33_0 --> 0.19-py33_0 dateutil: 2.1-py33_1 --> 1.5-py33_0 \n\ """ actions = defaultdict( list, { 'LINK': [ 'cython-0.19.1-py33_0 3', 'dateutil-1.5-py33_0 3', 'numpy-1.7.1-py33_0 3', 'python-3.3.2-0 3', 'readline-6.2-0 3', 'sqlite-3.7.13-0 3', 'tk-8.5.13-0 3', 'zlib-1.2.7-0 3' ] }) with captured() as c: display_actions(actions, index) assert c.stdout == """ The following NEW packages will be INSTALLED: cython: 0.19.1-py33_0 (copy) dateutil: 1.5-py33_0 (copy) numpy: 1.7.1-py33_0 (copy) python: 3.3.2-0 (copy) readline: 6.2-0 (copy) sqlite: 3.7.13-0 (copy) tk: 8.5.13-0 (copy) zlib: 1.2.7-0 (copy) """ actions = defaultdict( list, { 'LINK': ['cython-0.19.1-py33_0 3', 'dateutil-2.1-py33_1 3'], 'UNLINK': ['cython-0.19-py33_0', 'dateutil-1.5-py33_0'] }) with captured() as c: display_actions(actions, index) assert c.stdout == """ The following packages will be UPDATED: cython: 0.19-py33_0 --> 0.19.1-py33_0 (copy) dateutil: 1.5-py33_0 --> 2.1-py33_1 (copy) """ actions = defaultdict( list, { 'LINK': ['cython-0.19-py33_0 3', 'dateutil-1.5-py33_0 3'], 'UNLINK': ['cython-0.19.1-py33_0', 'dateutil-2.1-py33_1'] }) with captured() as c: display_actions(actions, index) assert c.stdout == """ The following packages will be DOWNGRADED: cython: 0.19.1-py33_0 --> 0.19-py33_0 (copy) dateutil: 2.1-py33_1 --> 1.5-py33_0 (copy) """ os.environ['CONDA_SHOW_CHANNEL_URLS'] = 'True' reset_context(()) d = Dist('cython-0.19.1-py33_0.tar.bz2') index[d] = IndexRecord.from_objects(index[d], channel='my_channel') d = Dist('dateutil-1.5-py33_0.tar.bz2') index[d] = IndexRecord.from_objects(index[d], channel='my_channel') actions = defaultdict( list, { 'LINK': [ 'cython-0.19.1-py33_0 3', 'dateutil-1.5-py33_0 3', 'numpy-1.7.1-py33_0 3', 'python-3.3.2-0 3', 'readline-6.2-0 3', 'sqlite-3.7.13-0 3', 'tk-8.5.13-0 3', 'zlib-1.2.7-0 3' ] }) with captured() as c: display_actions(actions, index) assert c.stdout == """ The following NEW packages will be INSTALLED: cython: 0.19.1-py33_0 my_channel (copy) dateutil: 1.5-py33_0 my_channel (copy) numpy: 1.7.1-py33_0 <unknown> (copy) python: 3.3.2-0 <unknown> (copy) readline: 6.2-0 <unknown> (copy) sqlite: 3.7.13-0 <unknown> (copy) tk: 8.5.13-0 <unknown> (copy) zlib: 1.2.7-0 <unknown> (copy) """ actions = defaultdict( list, { 'LINK': ['cython-0.19.1-py33_0 3', 'dateutil-2.1-py33_1 3'], 'UNLINK': ['cython-0.19-py33_0', 'dateutil-1.5-py33_0'] }) with captured() as c: display_actions(actions, index) assert c.stdout == """ The following packages will be UPDATED: cython: 0.19-py33_0 <unknown> --> 0.19.1-py33_0 my_channel (copy) dateutil: 1.5-py33_0 my_channel --> 2.1-py33_1 <unknown> (copy) """ actions = defaultdict( list, { 'LINK': ['cython-0.19-py33_0 3', 'dateutil-1.5-py33_0 3'], 'UNLINK': ['cython-0.19.1-py33_0', 'dateutil-2.1-py33_1'] }) with captured() as c: display_actions(actions, index) assert c.stdout == """
from conda.models.match_spec import MatchSpec from conda.plan import display_actions import conda.plan as plan from conda.resolve import Resolve from conda.utils import on_win from .decorators import skip_if_no_mock from .gateways.disk.test_permissions import tempdir from .helpers import captured, mock, tempdir try: from unittest.mock import patch except ImportError: from mock import patch with open(join(dirname(__file__), 'index.json')) as fi: index = {Dist(k): IndexRecord(**v) for k, v in iteritems(json.load(fi))} r = Resolve(index) def solve(specs): return [Dist.from_string(fn) for fn in r.solve(specs)] class add_unlink_TestCase(unittest.TestCase): def generate_random_dist(self): return "foobar-%s-0" % random.randint(100, 200) @contextmanager def mock_platform(self, windows=False): with mock.patch.object(plan, "sys") as sys: sys.platform = "win32" if windows else "not win32"
class TestGetActionsForDist(unittest.TestCase): def setUp(self): self.pkgs = [(None, "test-spec", "defaults", "1"), ("ranenv", "test-spec", "defaults", "5"), (None, "test-spec2", "defaults", "1"), ("ranenv", "test", "defaults", "1.2.0")] self.res = generate_mocked_resolve(self.pkgs) @patch("conda.core.linked_data.load_meta", return_value=True) def test_ensure_linked_actions_all_linked(self, load_meta): dists = [ Dist("test-88"), Dist("test-spec-42"), Dist("test-spec2-8.0.0.0.1-9") ] prefix = "some/prefix" link_actions = plan.ensure_linked_actions(dists, prefix) expected_output = defaultdict(list) expected_output["PREFIX"] = prefix expected_output["op_order"] = ('CHECK_FETCH', 'RM_FETCHED', 'FETCH', 'CHECK_EXTRACT', 'RM_EXTRACTED', 'EXTRACT', 'UNLINK', 'LINK', 'SYMLINK_CONDA') self.assertEquals(link_actions, expected_output) @patch("conda.core.linked_data.load_meta", return_value=False) def test_ensure_linked_actions_no_linked(self, load_meta): dists = [ Dist("test-88"), Dist("test-spec-42"), Dist("test-spec2-8.0.0.0.1-9") ] prefix = "some/prefix" link_actions = plan.ensure_linked_actions(dists, prefix) expected_output = defaultdict(list) expected_output["PREFIX"] = prefix expected_output["op_order"] = ('CHECK_FETCH', 'RM_FETCHED', 'FETCH', 'CHECK_EXTRACT', 'RM_EXTRACTED', 'EXTRACT', 'UNLINK', 'LINK', 'SYMLINK_CONDA') expected_output["LINK"] = [ Dist("test-88"), Dist("test-spec-42"), Dist("test-spec2-8.0.0.0.1-9") ] self.assertEquals(link_actions, expected_output) def test_get_actions_for_dist(self): install = [Dist("test-1.2.0-py36_7")] r = generate_mocked_resolve(self.pkgs, install) dists_for_prefix = plan.SpecsForPrefix( prefix="some/prefix/envs/_ranenv_", r=r, specs=["test 1.2.0"]) actions = plan.get_actions_for_dists(dists_for_prefix, None, self.res.index, None, False, False, True, True) expected_output = defaultdict(list) expected_output["PREFIX"] = "some/prefix/envs/_ranenv_" expected_output["op_order"] = ('CHECK_FETCH', 'RM_FETCHED', 'FETCH', 'CHECK_EXTRACT', 'RM_EXTRACTED', 'EXTRACT', 'UNLINK', 'LINK', 'SYMLINK_CONDA') expected_output["LINK"] = [Dist("test-1.2.0-py36_7")] expected_output["SYMLINK_CONDA"] = [context.root_dir] self.assertEquals(actions, expected_output) def test_get_actions_multiple_dists(self): install = [Dist("testspec2-4.3.0-1"), Dist("testspecs-1.1.1-4")] r = generate_mocked_resolve(self.pkgs, install) dists_for_prefix = plan.SpecsForPrefix( prefix="root/prefix", r=r, specs=["testspec2 <4.3", "testspecs 1.1*"]) actions = plan.get_actions_for_dists(dists_for_prefix, None, self.res.index, None, False, False, True, True) expected_output = defaultdict(list) expected_output["PREFIX"] = "root/prefix" expected_output["op_order"] = ('CHECK_FETCH', 'RM_FETCHED', 'FETCH', 'CHECK_EXTRACT', 'RM_EXTRACTED', 'EXTRACT', 'UNLINK', 'LINK', 'SYMLINK_CONDA') expected_output["LINK"] = [ Dist("testspec2-4.3.0-1"), Dist("testspecs-1.1.1-4") ] expected_output["SYMLINK_CONDA"] = [context.root_dir] assert actions == expected_output @patch("conda.core.linked_data.load_linked_data", return_value=[Dist("testspec1-0.9.1-py27_2")]) def test_get_actions_multiple_dists_and_unlink(self, load_linked_data): install = [Dist("testspec2-4.3.0-2"), Dist("testspec1-1.1.1-py27_0")] r = generate_mocked_resolve(self.pkgs, install) dists_for_prefix = plan.SpecsForPrefix( prefix="root/prefix", r=r, specs=["testspec2 <4.3", "testspec1 1.1*"]) test_link_data = { "root/prefix": { Dist("testspec1-0.9.1-py27_2"): True } } with patch("conda.core.linked_data.linked_data_", test_link_data): actions = plan.get_actions_for_dists(dists_for_prefix, None, self.res.index, None, False, False, True, True) expected_output = defaultdict(list) expected_output["PREFIX"] = "root/prefix" expected_output["op_order"] = ('CHECK_FETCH', 'RM_FETCHED', 'FETCH', 'CHECK_EXTRACT', 'RM_EXTRACTED', 'EXTRACT', 'UNLINK', 'LINK', 'SYMLINK_CONDA') expected_output["LINK"] = [ Dist("testspec2-4.3.0-2"), Dist("testspec1-1.1.1-py27_0") ] expected_output["UNLINK"] = [Dist("testspec1-0.9.1-py27_2")] expected_output["SYMLINK_CONDA"] = [context.root_dir] assert expected_output["LINK"] == actions["LINK"] assert actions == expected_output