def check_file(dirname): filename = os.path.join(dirname, DEFAULT_PROJECT_LOCK_FILENAME) assert os.path.exists(filename) lock_file = ProjectLockFile.load_for_directory(dirname) # we have the global enabled flag off; individual # env spec settings override that; foo has no setting. foo_lock_set = _get_lock_set(lock_file, 'foo') assert lock_file.get_value(['env_specs', 'foo', 'locked'], None) is None assert foo_lock_set.disabled bar_lock_set = _get_lock_set(lock_file, 'bar') assert bar_lock_set.disabled all_names = ['foo', 'bar'] lock_set = CondaLockSet( {'all': ['something=3.0=0']}, platforms=['linux-32', 'linux-64', 'osx-64', 'win-32', 'win-64']) lock_set.env_spec_hash = "hash-hash-hash" lock_file._set_lock_set('bar', lock_set, all_names=all_names) # "foo" should have been DISABLED since we had to # enable the global flag in order to enable "bar" foo_lock_set = _get_lock_set(lock_file, 'foo') assert lock_file.get_value(['env_specs', 'foo', 'locked']) is False assert foo_lock_set.disabled assert foo_lock_set.env_spec_hash is None bar_lock_set = _get_lock_set(lock_file, 'bar') assert bar_lock_set.enabled assert ('something=3.0=0', ) == bar_lock_set.package_specs_for_current_platform assert "hash-hash-hash" == bar_lock_set.env_spec_hash # and now we should enable "foo" when we set it to something lock_file._set_lock_set('foo', lock_set, all_names=all_names) foo_lock_set = _get_lock_set(lock_file, 'foo') assert foo_lock_set.enabled assert ('something=3.0=0', ) == foo_lock_set.package_specs_for_current_platform # be sure we can save lock_file.save() reloaded = ProjectLockFile.load_for_directory(dirname) assert ('something=3.0=0', ) == _get_lock_set( reloaded, 'bar').package_specs_for_current_platform assert ('something=3.0=0', ) == _get_lock_set( reloaded, 'foo').package_specs_for_current_platform # Check _set_lock_set_hash lock_file._set_lock_set_hash('bar', 'hash2.0') lock_file.save() reloaded = ProjectLockFile.load_for_directory(dirname) bar_lock_set = _get_lock_set(reloaded, 'bar') assert bar_lock_set.env_spec_hash == 'hash2.0'
def test_lock_set_properties(monkeypatch): lock_set = CondaLockSet( { 'all': ["something=0.5=2", "bokeh=0.12.4=1"], 'linux-64': ["linux-thing=1.0=0"], 'unix': ["unix-thing=5=1"], 'win': ["windows-cross-bit-thing=3.2"], 'win-32': ["windows-thing=2.0=3", "bokeh=2.3=7"] }, platforms=['linux-64', 'win-32']) # it is part of the API definition that we need to APPEND the # per-platform stuff, so it overrides. assert lock_set.package_specs_for_platform('win-32') == ( "something=0.5=2", "windows-cross-bit-thing=3.2", "windows-thing=2.0=3", "bokeh=2.3=7") # on Linux-64, test that it works without monkeypatch if conda_api.current_platform() != 'linux-64': monkeypatch.setattr( 'anaconda_project.internal.conda_api.current_platform', lambda: 'linux-64') assert lock_set.package_specs_for_current_platform == ("something=0.5=2", "bokeh=0.12.4=1", "unix-thing=5=1", "linux-thing=1.0=0") assert lock_set.platforms == ('linux-64', 'win-32')
def _get_lock_set(lock_file, env_spec_name): """Library-internal method.""" # TODO no validation here, we'll do that by moving this # into project.py soon enabled = _get_locking_enabled(lock_file, env_spec_name) packages = lock_file.get_value(['env_specs', env_spec_name, 'packages'], {}) platforms = lock_file.get_value(['env_specs', env_spec_name, 'platforms'], []) env_spec_hash = lock_file.get_value( ['env_specs', env_spec_name, 'env_spec_hash'], None) lock_set = CondaLockSet(packages, platforms, enabled=enabled) lock_set.env_spec_hash = env_spec_hash return lock_set
def test_lock_set_to_yaml(monkeypatch): lock_set = CondaLockSet( { 'all': ['a', 'b'], 'linux': ['x'], 'win': ['y'], 'linux-64': ['z', 'q'], 'osx-64': ['s'] }, platforms=['linux-64', 'win-64', 'osx-64']) # Mostly our interest here is that the ordering of the dict # is deterministic j = lock_set.to_json() assert _dump_string(j) == """locked: true
def test_overwrite_packages_with_lock_set(): lock_set = CondaLockSet({'all': ['a=1.0=1']}, platforms=['linux-32', 'linux-64', 'osx-64', 'win-32', 'win-64']) spec = EnvSpec( name="foo", conda_packages=['a', 'b'], pip_packages=['c', 'd'], channels=['x', 'y'], lock_set=lock_set) # package "b" is now ignored assert ('a=1.0=1', ) == spec.conda_packages_for_create
def resolve_dependencies(self, package_specs, channels, platforms): by_platform = {} current = conda_api.current_platform() resolve_for_platforms = list(platforms) # always resolve "current" first because it's confusing if # an error says resolution failed on another platform when # the real issue is that resolution will fail on all platforms. if current in resolve_for_platforms: resolve_for_platforms.remove(current) resolve_for_platforms = [current] + resolve_for_platforms for conda_platform in resolve_for_platforms: try: self._log_info("Resolving conda packages for %s" % conda_platform) deps = conda_api.resolve_dependencies(pkgs=package_specs, platform=conda_platform, channels=channels) except conda_api.CondaError as e: raise CondaManagerError("Error resolving for {}: {}".format( conda_platform, str(e))) locked_specs = ["%s=%s=%s" % dep for dep in deps] by_platform[conda_platform] = sorted(locked_specs) by_platform = _extract_common(by_platform) lock_set = CondaLockSet(package_specs_by_platform=by_platform, platforms=resolve_for_platforms) return lock_set
def check_file(dirname): filename = os.path.join(dirname, DEFAULT_PROJECT_LOCK_FILENAME) assert os.path.exists(filename) lock_file = ProjectLockFile.load_for_directory(dirname) all_names = ['foo', 'bar'] lock_set = CondaLockSet( {'all': ['something=3.0=0']}, platforms=['linux-32', 'linux-64', 'osx-64', 'win-32', 'win-64']) # so the point of this test is that we need to create env_specs # dict and the 'foo' entry as a side effect of setting 'bar', # in order to mark 'foo' disabled. lock_file._set_lock_set('bar', lock_set, all_names=all_names) # "foo" should have been DISABLED since we had to # enable the global flag in order to enable "bar" foo_lock_set = _get_lock_set(lock_file, 'foo') assert lock_file.get_value(['env_specs', 'foo', 'locked']) is False assert foo_lock_set.disabled bar_lock_set = _get_lock_set(lock_file, 'bar') assert bar_lock_set.enabled assert ('something=3.0=0', ) == bar_lock_set.package_specs_for_current_platform # be sure we can save lock_file.save() reloaded = ProjectLockFile.load_for_directory(dirname) assert ('something=3.0=0', ) == _get_lock_set( reloaded, 'bar').package_specs_for_current_platform assert _get_lock_set(reloaded, 'foo').disabled
def test_current_platform_unsupported_by_lock_set(monkeypatch): lock_set = CondaLockSet(package_specs_by_platform={'all': []}, platforms=[]) spec = EnvSpec(name='myenv', conda_packages=['ipython'], pip_packages=['flake8'], channels=[], platforms=conda_api.default_platforms_with_current(), lock_set=lock_set) def do_test(dirname): envdir = os.path.join(dirname, spec.name) manager = DefaultCondaManager(frontend=NullFrontend()) deviations = manager.find_environment_deviations(envdir, spec) error = "Env spec 'myenv' does not have the current platform %s in the lock file" % conda_api.current_platform( ) assert error == deviations.summary with pytest.raises(CondaManagerError) as excinfo: manager.fix_environment_deviations(envdir, spec, deviations=deviations) assert str( excinfo.value).startswith("Unable to update environment at ") with_directory_contents(dict(), do_test)
def test_lock_set_affects_hash(): lock_set = CondaLockSet({'all': ['a=1.0=1']}, platforms=[ 'linux-32', 'linux-64', 'osx-64', 'osx-arm64', 'win-32', 'win-64' ]) with_lock_spec = EnvSpec(name="foo", conda_packages=['a', 'b'], pip_packages=['c', 'd'], channels=['x', 'y'], lock_set=lock_set) without_lock_spec = EnvSpec(name=with_lock_spec.name, conda_packages=with_lock_spec.conda_packages, pip_packages=with_lock_spec.pip_packages, channels=with_lock_spec.channels, lock_set=None) assert with_lock_spec.conda_packages != with_lock_spec.conda_packages_for_create assert without_lock_spec.conda_packages == without_lock_spec.conda_packages_for_create assert without_lock_spec.logical_hash == without_lock_spec.locked_hash assert with_lock_spec.logical_hash != with_lock_spec.locked_hash assert with_lock_spec.logical_hash == without_lock_spec.logical_hash assert without_lock_spec.locked_hash == without_lock_spec.import_hash assert with_lock_spec.locked_hash != with_lock_spec.import_hash
def test_lock_set_to_json(monkeypatch): lock_set = CondaLockSet( { 'all': ["something=0.5=2", "bokeh=0.12.4=1"], 'linux-64': ["linux-thing=1.0=0"], 'win-32': ["windows-thing=2.0=3", "bokeh=2.3=7"] }, platforms=['linux-64', 'win-32']) assert { 'locked': True, 'packages': { 'all': ['something=0.5=2', 'bokeh=0.12.4=1'], 'linux-64': ['linux-thing=1.0=0'], 'win-32': ['windows-thing=2.0=3', 'bokeh=2.3=7'] }, 'platforms': ['linux-64', 'win-32'] } == lock_set.to_json()
def test_lock_set_affects_name_sets(): lock_set = CondaLockSet({ 'all': ['a=1.0=1', 'q=2.0=2'] }, platforms=['linux-32', 'linux-64', 'osx-64', 'win-32', 'win-64']) spec = EnvSpec( name="foo", conda_packages=['a', 'b'], pip_packages=['c', 'd'], channels=['x', 'y'], lock_set=lock_set) assert ('a', 'b') == spec.conda_packages assert ('a=1.0=1', 'q=2.0=2') == spec.conda_packages_for_create assert set(['a', 'b']) == spec.conda_package_names_set assert set(['a', 'q']) == spec.conda_package_names_for_create_set
def resolve_dependencies(self, package_specs, channels, platforms): return CondaLockSet({})
def test_lock_set_diff_and_equivalent(): old_lock_set = CondaLockSet( { 'all': ['a', 'b'], 'linux': ['x'], 'win': ['y'], 'linux-64': ['z', 'q'], 'osx-64': ['s'] }, platforms=['linux-64', 'osx-64']) new_lock_set = CondaLockSet( { 'all': ['a', 'b', 'c'], 'linux': ['x', 'h'], 'win': ['y'], 'linux-64': ['q', 'w'], 'osx-64': ['s'], 'win-64': ['j'] }, platforms=['linux-64', 'win-64']) assert """ platforms: - osx-64 + win-64 packages: all: + c linux: + h linux-64: - z + w + win-64: + j""" == new_lock_set.diff_from(old_lock_set) assert """ platforms: - win-64 + osx-64 packages: all: - c linux: - h linux-64: + z - w - win-64: - j""" == old_lock_set.diff_from(new_lock_set) assert "" == new_lock_set.diff_from(new_lock_set) assert "" == old_lock_set.diff_from(old_lock_set) assert old_lock_set.equivalent_to(old_lock_set) assert new_lock_set.equivalent_to(new_lock_set) assert not old_lock_set.equivalent_to(new_lock_set) assert not new_lock_set.equivalent_to(old_lock_set) assert """ platforms: + linux-64 + win-64 packages: + all: + a + b + c + linux: + x + h + win: + y + linux-64: + q + w + osx-64: + s + win-64: + j""" == new_lock_set.diff_from(None)