Skip to content

Commit

Permalink
Feat: add support for Conda environments (#749)
Browse files Browse the repository at this point in the history
* Feat: check for conda environments

* Docs: add news item

* Refactor: remove debug stmt

* Docs: correct docstrings
  • Loading branch information
agoose77 authored Nov 22, 2021
1 parent 9ed9e07 commit 367c3c2
Show file tree
Hide file tree
Showing 5 changed files with 40 additions and 5 deletions.
1 change: 1 addition & 0 deletions news/feat-support-conda.md
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Add support for Conda environments in addition to Python virtual environments.
11 changes: 8 additions & 3 deletions pdm/models/candidates.py
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@
create_tracked_tempdir,
expand_env_vars_in_auth,
get_rev_from_url,
get_venv_like_prefix,
path_replace,
populate_link,
url_without_fragments,
Expand Down Expand Up @@ -409,10 +410,14 @@ def _populate_source_dir(self, ireq: pip_shims.InstallRequirement) -> None:
elif self.req.editable:
if self.environment.packages_path:
src_dir = self.environment.packages_path / "src"
elif os.getenv("VIRTUAL_ENV"):
src_dir = Path(os.environ["VIRTUAL_ENV"]) / "src"
else:
src_dir = Path("src")
venv_prefix = get_venv_like_prefix(
self.environment.interpreter.executable
)
if venv_prefix is not None:
src_dir = venv_prefix / "src"
else:
src_dir = Path("src")
if not src_dir.is_dir():
src_dir.mkdir()
ireq.ensure_has_source_dir(str(src_dir))
Expand Down
10 changes: 8 additions & 2 deletions pdm/project/core.py
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@
find_project_root,
find_python_in_path,
get_in_project_venv_python,
is_conda_python,
is_venv_python,
)

Expand Down Expand Up @@ -178,7 +179,9 @@ def resolve_interpreter(self) -> PythonInfo:
else:
suffix = ""
scripts = "bin"
virtual_env = os.getenv("VIRTUAL_ENV")

# Resolve virtual environments from env-vars
virtual_env = os.getenv("VIRTUAL_ENV", os.getenv("CONDA_PREFIX"))
if config["use_venv"] and virtual_env:
return PythonInfo.from_path(
os.path.join(virtual_env, scripts, f"python{suffix}")
Expand All @@ -203,7 +206,10 @@ def get_environment(self) -> Environment:
# compatible with the exact version
env.python_requires = PySpecSet(f"=={self.python.version}")
return env
if self.config["use_venv"] and is_venv_python(self.python.executable):
if self.config["use_venv"] and (
is_venv_python(self.python.executable)
or is_conda_python(self.python.executable)
):
# Only recognize venv created by python -m venv and virtualenv>20
return GlobalEnvironment(self)
return Environment(self)
Expand Down
22 changes: 22 additions & 0 deletions pdm/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -440,10 +440,32 @@ def is_venv_python(interpreter: str | Path) -> bool:
interpreter = Path(interpreter)
if interpreter.parent.parent.joinpath("pyvenv.cfg").exists():
return True

virtual_env = os.getenv("VIRTUAL_ENV")
return bool(virtual_env and is_path_relative_to(interpreter, virtual_env))


def is_conda_python(interpreter: str | Path) -> bool:
"""Check if the given interpreter path is from a Conda environment"""
virtual_env = os.getenv("CONDA_PREFIX")
return bool(virtual_env and is_path_relative_to(Path(interpreter), virtual_env))


def get_venv_like_prefix(interpreter: str | Path) -> Path | None:
"""Check if the given interpreter path is from a virtualenv,
and return the prefix if found.
"""
interpreter = Path(interpreter)
prefix = interpreter.parent.parent
if prefix.joinpath("pyvenv.cfg").exists():
return prefix

virtual_env = os.getenv("VIRTUAL_ENV", os.getenv("CONDA_PREFIX"))
if virtual_env and is_path_relative_to(interpreter, virtual_env):
return Path(virtual_env)
return None


def find_python_in_path(path: str | Path) -> Path | None:
"""Find a python interpreter from the given path, the input argument could be:
Expand Down
1 change: 1 addition & 0 deletions tests/conftest.py
Original file line number Diff line number Diff line change
Expand Up @@ -250,6 +250,7 @@ def project_no_init(tmp_path, mocker):
do_use(p, getattr(sys, "_base_executable", sys.executable))
with temp_environ():
os.environ.pop("VIRTUAL_ENV", None)
os.environ.pop("CONDA_PREFIX", None)
os.environ.pop("PEP582_PACKAGES", None)
os.environ.pop("NO_SITE_PACKAGES", None)
pythonpath = os.environ.pop("PYTHONPATH", "")
Expand Down

0 comments on commit 367c3c2

Please sign in to comment.