def test_env_export_json(self): """ Test conda env export """ run_conda_command(Commands.CREATE, test_env_name_2, "flask") assert env_is_created(test_env_name_2) snowflake, e, = run_env_command(Commands.ENV_EXPORT, test_env_name_2, '--json') with Utf8NamedTemporaryFile(mode="w", suffix=".yml", delete=False) as env_json: env_json.write(snowflake) env_json.flush() env_json.close() run_env_command(Commands.ENV_REMOVE, test_env_name_2) self.assertFalse(env_is_created(test_env_name_2)) # regression test for #6220 snowflake, e, = run_env_command(Commands.ENV_EXPORT, test_env_name_2, '--no-builds', '--json') assert not e.strip() env_description = odict(json.loads(snowflake)) assert len(env_description['dependencies']) for spec_str in env_description['dependencies']: assert spec_str.count('=') == 1 run_env_command(Commands.ENV_REMOVE, test_env_name_2) assert not env_is_created(test_env_name_2)
def test_export_multi_channel(self): """ Test conda env export """ from conda.core.prefix_data import PrefixData PrefixData._cache_.clear() run_conda_command(Commands.CREATE, test_env_name_2, "python=3.5") self.assertTrue(env_is_created(test_env_name_2)) # install something from other channel not in config file run_conda_command(Commands.INSTALL, test_env_name_2, "-c", "conda-test", "test_timestamp_sort") snowflake, e, = run_env_command(Commands.ENV_EXPORT, test_env_name_2) assert 'conda-test' in snowflake check1, e = run_conda_command(Commands.LIST, test_env_name_2, "--explicit") with Utf8NamedTemporaryFile(mode="w", suffix=".yml", delete=False) as env_yaml: env_yaml.write(snowflake) env_yaml.flush() env_yaml.close() o, e = run_env_command(Commands.ENV_REMOVE, test_env_name_2) self.assertFalse(env_is_created(test_env_name_2)) o, e = run_env_command(Commands.ENV_CREATE, None, "--file", env_yaml.name) self.assertTrue(env_is_created(test_env_name_2)) # check explicit that we have same file check2, e = run_conda_command(Commands.LIST, test_env_name_2, "--explicit") self.assertEqual(check1, check2)
def test_env_export(self): """ Test conda env export """ run_conda_command(Commands.CREATE, test_env_name_2, "flask") assert env_is_created(test_env_name_2) snowflake, e, = run_env_command(Commands.ENV_EXPORT, test_env_name_2) with Utf8NamedTemporaryFile(mode="w", suffix=".yml", delete=False) as env_yaml: env_yaml.write(snowflake) env_yaml.flush() env_yaml.close() run_env_command(Commands.ENV_REMOVE, test_env_name_2) self.assertFalse(env_is_created(test_env_name_2)) run_env_command(Commands.ENV_CREATE, None, "--file", env_yaml.name) self.assertTrue(env_is_created(test_env_name_2)) # regression test for #6220 snowflake, e, = run_env_command(Commands.ENV_EXPORT, test_env_name_2, '--no-builds') assert not e.strip() env_description = yaml_safe_load(snowflake) assert len(env_description["dependencies"]) for spec_str in env_description["dependencies"]: assert spec_str.count("=") == 1 run_env_command(Commands.ENV_REMOVE, test_env_name_2) assert not env_is_created(test_env_name_2)
def test_env_export_with_variables(self): """ Test conda env export """ run_conda_command(Commands.CREATE, test_env_name_2, "flask") assert env_is_created(test_env_name_2) run_env_command(Commands.ENV_CONFIG, test_env_name_2, "vars", "set", "DUDE=woah", "SWEET=yaaa", "-n", test_env_name_2) snowflake, e, = run_env_command(Commands.ENV_EXPORT, test_env_name_2) with Utf8NamedTemporaryFile(mode="w", suffix=".yml", delete=False) as env_yaml: env_yaml.write(snowflake) env_yaml.flush() env_yaml.close() run_env_command(Commands.ENV_REMOVE, test_env_name_2) self.assertFalse(env_is_created(test_env_name_2)) run_env_command(Commands.ENV_CREATE, None, "--file", env_yaml.name) self.assertTrue(env_is_created(test_env_name_2)) snowflake, e = run_env_command(Commands.ENV_EXPORT, test_env_name_2, '--no-builds') assert not e.strip() env_description = yaml_safe_load(snowflake) assert len(env_description['variables']) assert env_description['variables'].keys() run_env_command(Commands.ENV_REMOVE, test_env_name_2) assert not env_is_created(test_env_name_2)
def test_multi_channel_export(self): """ When try to import from txt every package should come from same channel """ with make_temp_env("python=3.5") as prefix: assert exists(join(prefix, PYTHON_BINARY)) assert package_is_installed(prefix, 'python=3') run_command(Commands.INSTALL, prefix, "six", "-c", "conda-forge") assert package_is_installed(prefix, "six") output, error, _ = run_command(Commands.LIST, prefix, "-e") self.assertIn("conda-forge", output) try: with Utf8NamedTemporaryFile(mode="w", suffix="txt", delete=False) as env_txt: env_txt.write(output) env_txt.close() prefix2 = make_temp_prefix() run_command(Commands.CREATE, prefix2, "--file", env_txt.name) assert package_is_installed(prefix2, "python") output2, error, _ = run_command(Commands.LIST, prefix2, "-e") self.assertEqual(output, output2) finally: rm_rf(env_txt.name)
def test_ssl_verify_set_filename(): with make_temp_condarc() as rc, Utf8NamedTemporaryFile() as tf: stdout, stderr, _ = run_command(Commands.CONFIG, '--file', rc, '--set', 'ssl_verify', tf.name) assert stdout == stderr == '' reset_context([rc]) assert context.ssl_verify == tf.name
def running_a_python_capable_of_unicode_subprocessing(): name = None # try: # UNICODE_CHARACTERS + os.sep + with Utf8NamedTemporaryFile(mode="w", suffix=UNICODE_CHARACTERS + ".bat", delete=False) as batch_file: batch_file.write("@echo Hello World\n") batch_file.write("@exit 0\n") name = batch_file.name if name: try: out = check_output(name, cwd=dirname(name), stderr=None, shell=False) out = out.decode("utf-8") if hasattr(out, "decode") else out if out.startswith("Hello World"): return True return False except Exception: return False finally: os.unlink(name) return False
def make_temp_condarc(value=None): try: tempfile = Utf8NamedTemporaryFile(suffix='.yml', delete=False) tempfile.close() temp_path = tempfile.name if value: with open(temp_path, 'w') as f: f.write(value) reset_context([temp_path]) yield temp_path finally: rm_rf(temp_path)
def test_permission_file(): """ Test when lock cannot be created due to permission Make sure no exception raised """ from conda.auxlib.compat import Utf8NamedTemporaryFile with Utf8NamedTemporaryFile(mode='r') as f: if not isinstance(f.name, str): return with FileLock(f.name) as lock: path = basename(lock.lock_file_path) assert not exists(join(f.name, path))
def test_local_file_adapter_200(self): test_path = None try: with Utf8NamedTemporaryFile(delete=False) as fh: test_path = fh.name fh.write(ensure_binary('{"content": "file content"}')) test_url = path_to_url(test_path) session = CondaSession() r = session.get(test_url) r.raise_for_status() assert r.status_code == 200 assert r.json()['content'] == "file content" finally: if test_path is not None: rm_rf(test_path)
def _pip_install_via_requirements(prefix, specs, args, *_, **kwargs): """ Installs the pip dependencies in specs using a temporary pip requirements file. Args ---- prefix: string The path to the python and pip executables. specs: iterable of strings Each element should be a valid pip dependency. See: https://pip.pypa.io/en/stable/user_guide/#requirements-files https://pip.pypa.io/en/stable/reference/pip_install/#requirements-file-format """ url_scheme = args.file.split("://", 1)[0] if url_scheme in CONDA_SESSION_SCHEMES: pip_workdir = None else: try: pip_workdir = op.dirname(op.abspath(args.file)) except AttributeError: pip_workdir = None requirements = None try: # Generate the temporary requirements file requirements = Utf8NamedTemporaryFile(mode='w', prefix='condaenv.', suffix='.requirements.txt', dir=pip_workdir, delete=False) requirements.write('\n'.join(specs)) requirements.close() # pip command line... pip_cmd = ['install', '-U', '-r', requirements.name] stdout, stderr = pip_subprocess(pip_cmd, prefix, cwd=pip_workdir) finally: # Win/Appveyor does not like it if we use context manager + delete=True. # So we delete the temporary file in a finally block. if requirements is not None and op.isfile(requirements.name): if 'CONDA_TEST_SAVE_TEMPS' not in os.environ: os.remove(requirements.name) else: log.warning( 'CONDA_TEST_SAVE_TEMPS :: retaining pip requirements.txt {}' .format(requirements.name)) return get_pip_installed_packages(stdout)
def test_basic(self): with make_temp_env("python=3.5") as prefix: assert exists(join(prefix, PYTHON_BINARY)) assert package_is_installed(prefix, 'python=3') output, error, _ = run_command(Commands.LIST, prefix, "-e") with Utf8NamedTemporaryFile(mode="w", suffix="txt", delete=False) as env_txt: env_txt.write(output) env_txt.flush() env_txt.close() prefix2 = make_temp_prefix() run_command(Commands.CREATE, prefix2, "--file", env_txt.name) assert package_is_installed(prefix2, "python") output2, error, _ = run_command(Commands.LIST, prefix2, "-e") self.assertEqual(output, output2)
def test_list(self): """ Test conda list -e and conda create from txt """ run_conda_command(Commands.CREATE, test_env_name_2) self.assertTrue(env_is_created(test_env_name_2)) snowflake, e = run_conda_command(Commands.LIST, test_env_name_2, "-e") with Utf8NamedTemporaryFile(mode="w", suffix=".txt", delete=False) as env_txt: env_txt.write(snowflake) env_txt.flush() env_txt.close() run_env_command(Commands.ENV_REMOVE, test_env_name_2) self.assertFalse(env_is_created(test_env_name_2)) run_conda_command(Commands.CREATE, test_env_name_2, "--file " + env_txt.name) self.assertTrue(env_is_created(test_env_name_2)) snowflake2, e = run_conda_command(Commands.LIST, test_env_name_2, "-e") self.assertEqual(snowflake, snowflake2)
def test_multi_channel_explicit(self): """ When try to import from txt every package should come from same channel """ with make_temp_env("python=3.5") as prefix: assert exists(join(prefix, PYTHON_BINARY)) assert package_is_installed(prefix, 'python=3') run_command(Commands.INSTALL, prefix, "six", "-c", "conda-forge") assert package_is_installed(prefix, "conda-forge::six") output, error, _ = run_command(Commands.LIST, prefix, "--explicit") assert not error assert "conda-forge" in output urls1 = set(url for url in output.split() if url.startswith("http")) try: with Utf8NamedTemporaryFile(mode="w", suffix="txt", delete=False) as env_txt: env_txt.write(output) env_txt.close() prefix2 = make_temp_prefix() run_command(Commands.CREATE, prefix2, "--file", env_txt.name) assert package_is_installed(prefix2, "python") assert package_is_installed(prefix2, "six") output2, error2, _ = run_command(Commands.LIST, prefix2, "--explicit") assert not error2 urls2 = set(url for url in output2.split() if url.startswith("http")) assert urls1 == urls2 finally: rm_rf(env_txt.name)
def test_invalid_extensions(self): with Utf8NamedTemporaryFile(mode="w", suffix=".ymla", delete=False) as env_yaml: with self.assertRaises(EnvironmentFileExtensionNotValid): run_env_command(Commands.ENV_CREATE, None, "--file", env_yaml.name)
def rmtree(path, *args, **kwargs): # subprocessing to delete large folders can be quite a bit faster path = normpath(path) if on_win: try: # the fastest way seems to be using DEL to recursively delete files # https://www.ghacks.net/2017/07/18/how-to-delete-large-folders-in-windows-super-fast/ # However, this is not entirely safe, as it can end up following symlinks to folders # https://superuser.com/a/306618/184799 # so, we stick with the slower, but hopefully safer way. Maybe if we figured out how # to scan for any possible symlinks, we could do the faster way. # out = check_output('DEL /F/Q/S *.* > NUL 2> NUL'.format(path), shell=True, # stderr=STDOUT, cwd=path) out = check_output('RD /S /Q "{}" > NUL 2> NUL'.format(path), shell=True, stderr=STDOUT) except: try: # Try to delete in Unicode name = None from conda.auxlib.compat import Utf8NamedTemporaryFile from conda.utils import quote_for_shell with Utf8NamedTemporaryFile(mode="w", suffix=".bat", delete=False) as batch_file: batch_file.write("RD /S {}\n".format( quote_for_shell(path))) batch_file.write("chcp 65001\n") batch_file.write("RD /S {}\n".format( quote_for_shell(path))) batch_file.write("EXIT 0\n") name = batch_file.name # If the above is bugged we can end up deleting hard-drives, so we check # that 'path' appears in it. This is not bulletproof but it could save you (me). with open(name, 'r') as contents: content = contents.read() assert path in content comspec = environ['COMSPEC'] CREATE_NO_WINDOW = 0x08000000 # It is essential that we `pass stdout=None, stderr=None, stdin=None` here because # if we do not, then the standard console handles get attached and chcp affects the # parent process (and any which share those console handles!) out = check_output([comspec, '/d', '/c', name], shell=False, stdout=None, stderr=None, stdin=None, creationflags=CREATE_NO_WINDOW) except CalledProcessError as e: if e.returncode != 5: log.error( "Removing folder {} the fast way failed. Output was: {}" .format(name, out)) raise else: log.debug( "removing dir contents the fast way failed. Output was: {}" .format(out)) else: try: makedirs('.empty') except: pass # yes, this looks strange. See # https://unix.stackexchange.com/a/79656/34459 # https://web.archive.org/web/20130929001850/http://linuxnote.net/jianingy/en/linux/a-fast-way-to-remove-huge-number-of-files.html # NOQA if isdir('.empty'): rsync = which('rsync') if rsync: try: out = check_output([ rsync, '-a', '--force', '--delete', join(getcwd(), '.empty') + "/", path + "/" ], stderr=STDOUT) except CalledProcessError: log.debug( f"removing dir contents the fast way failed. Output was: {out}" ) shutil.rmtree('.empty') shutil.rmtree(path)