def test_pip_remove(setup_pip_env, mocker): env = setup_pip_env["env"] env_io = setup_pip_env["env_io"] mocker.patch("conda_env_tracker.pip.pip_remove") PipHandler(env=env).remove(packages=Packages.from_specs("pytest"), yes=True) actual = env_io.get_history() assert actual.logs[-1] == "pip uninstall pytest" assert actual.actions[-1] == "pip uninstall pytest" assert actual.packages["pip"] == { "pandas": Package(name="pandas", spec="git+ssh://[email protected]/pandas-dev/pandas") } PipHandler(env=env).remove(packages=Packages.from_specs("pandas"), yes=True) actual = env_io.get_history() assert actual.logs[-1] == "pip uninstall pandas" assert actual.actions[-1] == "pip uninstall pandas" assert "pip" not in actual.packages
def infer(cls, name: str, packages: Packages, channels: ListLike = None): """create conda_env_tracker environment by inferring to existing conda environment""" if name == "base": raise CondaEnvTrackerCondaError( "Environment can not be created using default name base" ) if name not in get_all_existing_environment(): raise CondaEnvTrackerCondaError( f"Environment {name} can not be inferred, does not exist" ) existing_packages = get_dependencies(name=name) if "r-base" in existing_packages["conda"]: existing_r_packages = get_r_dependencies(name=name) else: existing_r_packages = {} user_packages = {"conda": Packages(), "pip": Packages(), "r": Packages()} for package in packages: if package.name in existing_packages.get("conda", Packages()): user_packages["conda"].append(package) elif package.name in existing_packages.get("pip", Packages()): user_packages["pip"].append(package) elif package.name in existing_r_packages: raise RError( "Cannot infer R packages, must run follow-up R install command.\n" f"Found '{package.name}' in installed R packages {existing_r_packages}." ) else: raise CondaEnvTrackerCondaError( f"Environment {name} does not have {package.spec} installed" ) conda_create_cmd = get_conda_create_command( name, user_packages["conda"], channels ) specs = Actions.get_package_specs( packages=user_packages["conda"], dependencies=existing_packages["conda"] ) history = History( name=name, channels=Channels(channels), packages=HistoryPackages.create(user_packages["conda"]), logs=Logs.create(conda_create_cmd), actions=Actions.create(name=name, specs=specs, channels=Channels(channels)), debug=Debug.create(name=name), ) env = cls(name=name, history=history) if user_packages["pip"]: handler = PipHandler(env=env) handler.update_history_install(packages=user_packages["pip"]) env = handler.env env.export() return env
def test_pip_custom_install_github(setup_env, mocker): pip_package_url = "git+ssh://[email protected]/pandas-dev/pandas" pip_dependencies = {"pandas": Package("pandas", pip_package_url)} package = Package("pandas", pip_package_url) env = setup_env["env"] env_io = setup_env["env_io"] expected = copy.deepcopy(setup_env["expected"]) get_package_mock = setup_env["get_package_mock"] initial_conda_packages = setup_env["initial_conda_packages"] get_package_mock.configure_mock(**{ "return_value": { "conda": initial_conda_packages, "pip": pip_dependencies } }) mocker.patch("conda_env_tracker.pip.pip_custom_install") PipHandler(env=env).custom_install(package=package) install_command = f"pip install {pip_package_url}" expected["logs"].append(install_command) expected["packages"]["pip"] = pip_dependencies action_command = install_command actual = env_io.get_history() assert actual.logs == expected["logs"] assert actual.packages == expected["packages"] assert actual.actions[-1] == action_command
def test_pip_custom_install(setup_env, mocker): pip_package_url = "https://s3.amazonaws.com/h2o-release/h2o/master/4765/Python/h2o-3.26.0.4765-py2.py3-none-any.whl" pip_dependencies = {"h2o": Package("h2o", pip_package_url)} package = Package("h2o", pip_package_url) env = setup_env["env"] env_io = setup_env["env_io"] expected = copy.deepcopy(setup_env["expected"]) get_package_mock = setup_env["get_package_mock"] initial_conda_packages = setup_env["initial_conda_packages"] get_package_mock.configure_mock(**{ "return_value": { "conda": initial_conda_packages, "pip": pip_dependencies } }) mocker.patch("conda_env_tracker.pip.pip_custom_install") PipHandler(env=env).custom_install(package=package) install_command = f"pip install {pip_package_url}" expected["logs"].append(install_command) expected["packages"]["pip"] = pip_dependencies action_command = install_command actual = env_io.get_history() assert actual.logs == expected["logs"] assert actual.packages == expected["packages"] assert actual.actions[-1] == action_command
def test_pip_install(setup_env, packages, pip_dependencies, mocker): env = setup_env["env"] env_io = setup_env["env_io"] expected = copy.deepcopy(setup_env["expected"]) get_package_mock = setup_env["get_package_mock"] initial_conda_packages = setup_env["initial_conda_packages"] get_package_mock.configure_mock(**{ "return_value": { "conda": initial_conda_packages, "pip": pip_dependencies } }) mocker.patch("conda_env_tracker.pip.pip_install") PipHandler(env=env).install(packages=packages) install_command = f'pip install {" ".join(package.spec for package in packages)} --index-url {PIP_DEFAULT_INDEX_URL}' action_command = ( f'pip install {" ".join(f"{name}=={package.version}" for name, package in pip_dependencies.items())}' f" --index-url {PIP_DEFAULT_INDEX_URL}") expected["logs"].append(install_command) expected["packages"]["pip"] = pip_dependencies actual = env_io.get_history() assert actual.logs == expected["logs"] assert actual.packages == expected["packages"] assert actual.actions[-1] == action_command
def pip_remove(name: str, specs: ListLike, yes: bool = False) -> Environment: """Remove pip packages including custom packages""" env = Environment.read(name=name) check_pip(env=env) cleaned = process_specs(specs) PipHandler(env=env).remove(packages=cleaned, yes=yes) _ask_user_to_sync(name=name, yes=yes) return env
def pip_custom_install( name: str, package: str, url_path: str, yes: bool = False ) -> Environment: """Install custom pip package""" env = Environment.read(name=name) check_pip(env=env) cleaned = Package(name=package.lower(), spec=url_path) PipHandler(env=env).custom_install(package=cleaned) _ask_user_to_sync(name=name, yes=yes) return env
def pip_install( name: str, specs: ListLike, index_url: Union[str, ListLike] = PIP_DEFAULT_INDEX_URL, yes: bool = False, ) -> Environment: """Install pip packages into the environment.""" env = Environment.read(name=name) check_pip(env=env) cleaned = process_specs(specs, check_custom=True) PipHandler(env=env).install(packages=cleaned, index_url=index_url) _ask_user_to_sync(name=name, yes=yes) return env
def setup_pip_env(setup_env, mocker): """Set up for pip remove""" pip_package_url = "git+ssh://[email protected]/pandas-dev/pandas" pip_dependencies = { "pandas": Package("pandas", pip_package_url), "pytest": Package("pytest", "pytest", "4.0.0"), } env = setup_env["env"] mocker.patch("conda_env_tracker.pip.pip_install") mocker.patch("conda_env_tracker.pip.pip_custom_install") get_package_mock = setup_env["get_package_mock"] initial_conda_packages = setup_env["initial_conda_packages"] get_package_mock.configure_mock(**{ "return_value": { "conda": initial_conda_packages, "pip": pip_dependencies } }) PipHandler(env=env).install(packages=Packages.from_specs("pytest")) custom_package = Package("pandas", pip_package_url) PipHandler(env=env).custom_install(package=custom_package) return setup_env
def _handle_pip_extra_log(env: Environment, history: History, index: int) -> Environment: """Handle conda install, conda update --all and conda remove logs.""" log = history.logs[index] handler = PipHandler(env=env) if log.startswith("pip uninstall"): packages = history.logs.extra_removed_packages(index=index) handler.remove(packages=packages) else: packages = history.actions.extract_packages(index=index) index_url = history.logs.extract_index_urls(index=index) handler.install(packages=packages, index_url=index_url) env.history.logs[-1] = log return env
def test_pip_remove_package_missing_from_env(setup_pip_env): env = setup_pip_env["env"] packages = Packages.from_specs("this_is_a_nonexistant_package") with pytest.raises(PipRemoveError): PipHandler(env=env).remove(packages=packages)