def activate(self): """Activate the environment. Manipulate the ``PYTHONPATH`` and patches ``pip`` to be aware of local packages. This method acts like a context manager. :param site_packages: whether to inject base site-packages into the sub env. """ paths = self.get_paths() with temp_environ(): working_set = self.get_working_set() _old_ws = pkg_resources.working_set pkg_resources.working_set = working_set.pkg_ws # HACK: Replace the is_local with environment version so that packages can # be removed correctly. _old_sitepackages = misc.site_packages misc.site_packages = paths["purelib"] _is_local = misc.is_local misc.is_local = req_uninstall.is_local = self.is_local _evaluate_marker = pkg_resources.evaluate_marker pkg_resources.evaluate_marker = self.evaluate_marker sys_executable = sys.executable sys.executable = self.python_executable yield sys.executable = sys_executable pkg_resources.evaluate_marker = _evaluate_marker misc.is_local = req_uninstall.is_local = _is_local misc.site_packages = _old_sitepackages pkg_resources.working_set = _old_ws
def test_run_expand_env_vars(project, invoke, capfd): (project.root / "test_script.py").write_text("import os; print(os.getenv('FOO'))") project.tool_settings["scripts"] = { "test_cmd": 'python -c "foo, bar = 0, 1;print($FOO)"', "test_cmd_no_expand": "python -c 'print($FOO)'", "test_script": "python test_script.py", "test_cmd_array": ["python", "test_script.py"], "test_shell": { "shell": "echo $FOO" }, } project.write_pyproject() capfd.readouterr() with cd(project.root), temp_environ(): os.environ["FOO"] = "bar" invoke(["run", "test_cmd"], obj=project) assert capfd.readouterr()[0].strip() == "1" result = invoke(["run", "test_cmd_no_expand"], obj=project) assert result.exit_code == 1 invoke(["run", "test_script"], obj=project) assert capfd.readouterr()[0].strip() == "bar" invoke(["run", "test_cmd_array"], obj=project) assert capfd.readouterr()[0].strip() == "bar" invoke(["run", "test_shell"], obj=project) assert capfd.readouterr()[0].strip() == "bar"
def test_ignore_saved_python(project): project.project_config["use_venv"] = True scripts = "Scripts" if os.name == "nt" else "bin" suffix = ".exe" if os.name == "nt" else "" venv.create(project.root / "venv") with temp_environ(): os.environ["PDM_IGNORE_SAVED_PYTHON"] = "1" assert Path( project.python_executable) != project.project_config["python.path"] assert (Path(project.python_executable) == project.root / "venv" / scripts / f"python{suffix}")
def project_no_init(tmp_path, mocker): p = TestProject(tmp_path.as_posix()) p.core = main mocker.patch("pdm.utils.get_finder", get_local_finder) mocker.patch("pdm.models.environment.get_finder", get_local_finder) mocker.patch("pdm.project.core.Config.HOME_CONFIG", tmp_path) old_config_map = Config._config_map.copy() p.global_config["cache_dir"] = tmp_path.joinpath("caches").as_posix() do_use(p, sys.executable) with temp_environ(): os.environ.pop("VIRTUAL_ENV", None) yield p # Restore the config items Config._config_map = old_config_map
def test_config_env_var_shadowing(project, invoke): with temp_environ(): os.environ["PDM_PYPI_URL"] = "https://example.org/simple" result = invoke(["config", "pypi.url"], obj=project) assert result.output.strip() == "https://example.org/simple" result = invoke(["config", "pypi.url", "https://testpypi.org/pypi"], obj=project) assert "config is shadowed by env var 'PDM_PYPI_URL'" in result.output result = invoke(["config", "pypi.url"], obj=project) assert result.output.strip() == "https://example.org/simple" del os.environ["PDM_PYPI_URL"] result = invoke(["config", "pypi.url"], obj=project) assert result.output.strip() == "https://testpypi.org/pypi"
def test_project_python_with_pyenv_support(project, mocker): from pythonfinder.environment import PYENV_ROOT del project.project_config["python.path"] pyenv_python = Path(PYENV_ROOT, "shims", "python") with temp_environ(): os.environ["PDM_IGNORE_SAVED_PYTHON"] = "1" mocker.patch("pdm.project.core.PYENV_INSTALLED", True) mocker.patch("pdm.project.core.get_python_version", return_value=("3.8", True)) assert Path(project.python_executable) == pyenv_python # Clean cache del project.__dict__["python_executable"] project.project_config["python.use_pyenv"] = False assert Path(project.python_executable) != pyenv_python
def project_no_init(tmp_path, mocker): p = main.create_project(tmp_path) mocker.patch("pdm.utils.get_finder", get_local_finder) mocker.patch("pdm.models.environment.get_finder", get_local_finder) mocker.patch("pdm.project.core.Config.HOME_CONFIG", tmp_path) old_config_map = Config._config_map.copy() p.global_config["cache_dir"] = tmp_path.joinpath("caches").as_posix() do_use(p, getattr(sys, "_base_executable", sys.executable)) with temp_environ(): os.environ.pop("VIRTUAL_ENV", None) os.environ.pop("PEP582_PACKAGES", None) pythonpath = os.environ.pop("PYTHONPATH", "") pythonpath = remove_pep582_path_from_pythonpath(pythonpath) if pythonpath: os.environ["PYTHONPATH"] = pythonpath yield p # Restore the config items Config._config_map = old_config_map
def test_project_python_with_pyenv_support(project, mocker): del project.project_config["python.path"] project._python = None with temp_environ(): os.environ["PDM_IGNORE_SAVED_PYTHON"] = "1" mocker.patch("pdm.project.core.PYENV_INSTALLED", True) mocker.patch("pdm.project.core.PYENV_ROOT", str(project.root)) pyenv_python = project.root / "shims/python" pyenv_python.parent.mkdir() pyenv_python.touch() mocker.patch( "pythonfinder.models.python.get_python_version", return_value="3.8.0", ) assert Path(project.python.executable) == pyenv_python # Clean cache project._python = None project.project_config["python.use_pyenv"] = False assert Path(project.python.executable) != pyenv_python
def activate(self, site_packages: bool = False): """Activate the environment. Manipulate the ``PYTHONPATH`` and patches ``pip`` to be aware of local packages. This method acts like a context manager. :param site_packages: whether to inject base site-packages into the sub env. """ paths = self.get_paths() with temp_environ(): old_paths = os.getenv("PYTHONPATH") if old_paths: new_paths = os.pathsep.join([paths["purelib"], old_paths]) else: new_paths = paths["purelib"] os.environ["PYTHONPATH"] = new_paths python_root = os.path.dirname(self.python_executable) os.environ["PATH"] = os.pathsep.join( [python_root, paths["scripts"], os.environ["PATH"]]) if site_packages: os.environ["PDM_SITE_PACKAGES"] = "1" working_set = self.get_working_set() _old_ws = pkg_resources.working_set pkg_resources.working_set = working_set.pkg_ws # HACK: Replace the is_local with environment version so that packages can # be removed correctly. _old_sitepackages = misc.site_packages misc.site_packages = paths["purelib"] _is_local = misc.is_local misc.is_local = req_uninstall.is_local = self.is_local _evaluate_marker = pkg_resources.evaluate_marker pkg_resources.evaluate_marker = self.evaluate_marker sys_executable = sys.executable sys.executable = self.python_executable yield sys.executable = sys_executable pkg_resources.evaluate_marker = _evaluate_marker misc.is_local = req_uninstall.is_local = _is_local misc.site_packages = _old_sitepackages pkg_resources.working_set = _old_ws