-
-
Notifications
You must be signed in to change notification settings - Fork 40
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add utilities to get info from Python environments
Most of these functions were added to Spyder first but we need to have them here now.
- Loading branch information
1 parent
c0c785c
commit 0eee303
Showing
2 changed files
with
141 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,75 @@ | ||
# -*- coding: utf-8 -*- | ||
# ----------------------------------------------------------------------------- | ||
# Copyright (c) 2009- Spyder Kernels Contributors | ||
# | ||
# Licensed under the terms of the MIT License | ||
# (see spyder_kernels/__init__.py for details) | ||
# ----------------------------------------------------------------------------- | ||
|
||
"""Utilities to get information about Python environments.""" | ||
|
||
# Standard library imports | ||
import os | ||
from pathlib import Path | ||
|
||
|
||
def add_quotes(path): | ||
"""Return quotes if needed for spaces on path.""" | ||
quotes = '"' if ' ' in path and '"' not in path else '' | ||
return '{quotes}{path}{quotes}'.format(quotes=quotes, path=path) | ||
|
||
|
||
def get_conda_env_path(pyexec, quote=False): | ||
""" | ||
Return the full path to the conda environment from a given python | ||
executable. | ||
If `quote` is True, then quotes are added if spaces are found in the path. | ||
""" | ||
pyexec = pyexec.replace('\\', '/') | ||
if os.name == 'nt': | ||
conda_env = os.path.dirname(pyexec) | ||
else: | ||
conda_env = os.path.dirname(os.path.dirname(pyexec)) | ||
|
||
if quote: | ||
conda_env = add_quotes(conda_env) | ||
|
||
return conda_env | ||
|
||
|
||
def is_conda_env(prefix=None, pyexec=None): | ||
"""Check if prefix or python executable are in a conda environment.""" | ||
if pyexec is not None: | ||
pyexec = pyexec.replace('\\', '/') | ||
|
||
if (prefix is None and pyexec is None) or (prefix and pyexec): | ||
raise ValueError('Only `prefix` or `pyexec` should be provided!') | ||
|
||
if pyexec and prefix is None: | ||
prefix = get_conda_env_path(pyexec).replace('\\', '/') | ||
|
||
return os.path.exists(os.path.join(prefix, 'conda-meta')) | ||
|
||
|
||
def is_pyenv_env(pyexec): | ||
"""Check if a python executable is a Pyenv environment.""" | ||
path = Path(pyexec) | ||
return "pyenv" in path.parts[:-1] | ||
|
||
|
||
def get_env_dir(interpreter, only_dir=False): | ||
"""Get the environment directory from the interpreter executable.""" | ||
path = Path(interpreter) | ||
|
||
if os.name == 'nt': | ||
# This is enough for Conda and Pyenv envs | ||
env_dir = path.parent | ||
|
||
# This is necessary for envs created with `python -m venv` | ||
if env_dir.parts[-1].lower() == "scripts": | ||
env_dir = path.parents[1] | ||
else: | ||
env_dir = path.parents[1] | ||
|
||
return env_dir.parts[-1] if only_dir else str(env_dir) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,66 @@ | ||
# -*- coding: utf-8 -*- | ||
# ----------------------------------------------------------------------------- | ||
# Copyright (c) 2009- Spyder Kernels Contributors | ||
# | ||
# Licensed under the terms of the MIT License | ||
# (see spyder_kernels/__init__.py for details) | ||
# ----------------------------------------------------------------------------- | ||
|
||
""" | ||
Tests for utilities in the pythonenv module | ||
""" | ||
|
||
# Standard library imports | ||
import os | ||
|
||
# Third-party imports | ||
import pytest | ||
|
||
# Local imports | ||
from spyder_kernels.utils.pythonenv import ( | ||
add_quotes, | ||
get_conda_env_path, | ||
get_env_dir, | ||
) | ||
|
||
|
||
if os.name == 'nt': | ||
TEST_PYEXEC = 'c:/miniconda/envs/foobar/python.exe' | ||
else: | ||
TEST_PYEXEC = '/miniconda/envs/foobar/bin/python' | ||
|
||
|
||
def test_add_quotes(): | ||
output = add_quotes('/some path/with spaces') | ||
assert output == '"/some path/with spaces"' | ||
|
||
output = add_quotes('/some-path/with-no-spaces') | ||
assert output == '/some-path/with-no-spaces' | ||
|
||
|
||
def test_get_conda_env_path(): | ||
output = get_conda_env_path(TEST_PYEXEC) | ||
if os.name == 'nt': | ||
assert output == 'c:/miniconda/envs/foobar' | ||
else: | ||
assert output == '/miniconda/envs/foobar' | ||
|
||
|
||
def test_get_env_dir(): | ||
output_dir = get_env_dir(TEST_PYEXEC, only_dir=False) | ||
if os.name == "nt": | ||
assert output_dir == 'c:\\miniconda\\envs\\foobar' | ||
else: | ||
assert output_dir == '/miniconda/envs/foobar' | ||
|
||
output = get_env_dir(TEST_PYEXEC, only_dir=True) | ||
assert output == "foobar" | ||
|
||
if os.name == "nt": | ||
venv_pyexec = 'C:\\Miniconda3\\envs\\foobar\\Scripts\\python.exe' | ||
output = get_env_dir(venv_pyexec, only_dir=True) | ||
assert output == "foobar" | ||
|
||
|
||
if __name__ == "__main__": | ||
pytest.main() |