forked from VimPlug/jedi
Better tests for venvs
This commit is contained in:
@@ -31,8 +31,8 @@ class _BaseEnvironment(object):
|
||||
|
||||
class Environment(_BaseEnvironment):
|
||||
def __init__(self, path, executable):
|
||||
self._base_path = path
|
||||
self._executable = executable
|
||||
self._base_path = os.path.abspath(path)
|
||||
self._executable = os.path.abspath(executable)
|
||||
self.version_info = self._get_version()
|
||||
|
||||
def _get_version(self):
|
||||
@@ -50,7 +50,7 @@ class Environment(_BaseEnvironment):
|
||||
output = stdout + stderr
|
||||
match = re.match(br'Python (\d+)\.(\d+)\.(\d+)', output)
|
||||
if match is None:
|
||||
raise InvalidPythonEnvironment()
|
||||
raise InvalidPythonEnvironment("--version not working")
|
||||
|
||||
return _VersionInfo(*[int(m) for m in match.groups()])
|
||||
|
||||
@@ -107,7 +107,7 @@ def _get_virtual_env_from_var():
|
||||
|
||||
def get_default_environment():
|
||||
"""
|
||||
Tries to return an active VirtualEnv. If there is no VIRTUAL_ENV variable
|
||||
Tries to return an active Virtualenv. If there is no VIRTUAL_ENV variable
|
||||
set it will return the latest Python version installed on the system. This
|
||||
makes it possible to use as many new Python features as possible when using
|
||||
autocompletion and other functionality.
|
||||
@@ -122,9 +122,10 @@ def get_default_environment():
|
||||
|
||||
def find_virtualenvs(paths=None, **kwargs):
|
||||
"""
|
||||
:param paths: A list of paths in your file system that this function will
|
||||
use to search virtual env's. It will exclusively search in these paths
|
||||
and potentially execute the Python binaries on these paths.
|
||||
:param paths: A list of paths in your file system to be scanned for
|
||||
Virtualenvs. It will search in these paths and potentially execute the
|
||||
Python binaries. Also the VIRTUAL_ENV variable will be checked if it
|
||||
contains a valid Virtualenv.
|
||||
:param safe: Default True. In case this is False, it will allow this
|
||||
function to execute potential `python` environments. An attacker might
|
||||
be able to drop an executable in a path this function is searching by
|
||||
@@ -137,22 +138,30 @@ def find_virtualenvs(paths=None, **kwargs):
|
||||
|
||||
_used_paths = set()
|
||||
|
||||
# Using this variable should be safe, because attackers might be able
|
||||
# to drop files (via git) but not environment variables.
|
||||
virtual_env = _get_virtual_env_from_var()
|
||||
if virtual_env is not None:
|
||||
yield virtual_env
|
||||
_used_paths.add(virtual_env._base_path)
|
||||
|
||||
for path in paths:
|
||||
if path in _used_paths:
|
||||
# A path shouldn't be evaluated twice.
|
||||
for directory in paths:
|
||||
if not os.path.isdir(directory):
|
||||
continue
|
||||
_used_paths.add(path)
|
||||
|
||||
try:
|
||||
executable = _get_executable_path(path, safe=safe)
|
||||
yield Environment(path, executable)
|
||||
except InvalidPythonEnvironment:
|
||||
pass
|
||||
directory = os.path.abspath(directory)
|
||||
for path in os.listdir(directory):
|
||||
path = os.path.join(directory, path)
|
||||
if path in _used_paths:
|
||||
# A path shouldn't be evaluated twice.
|
||||
continue
|
||||
_used_paths.add(path)
|
||||
|
||||
try:
|
||||
executable = _get_executable_path(path, safe=safe)
|
||||
yield Environment(path, executable)
|
||||
except InvalidPythonEnvironment:
|
||||
pass
|
||||
|
||||
return py27_comp(paths, **kwargs)
|
||||
|
||||
|
||||
@@ -1,12 +1,13 @@
|
||||
import os
|
||||
from contextlib import contextmanager
|
||||
from distutils.spawn import find_executable
|
||||
|
||||
import pytest
|
||||
|
||||
import jedi
|
||||
from jedi._compatibility import py_version
|
||||
from jedi.api.environment import Environment, get_default_environment, \
|
||||
InvalidPythonEnvironment, find_python_environments
|
||||
InvalidPythonEnvironment, find_python_environments, find_virtualenvs
|
||||
|
||||
|
||||
def test_sys_path():
|
||||
@@ -30,7 +31,10 @@ def test_find_python_environments():
|
||||
['2.7', '3.3', '3.4', '3.5', '3.6', '3.7']
|
||||
)
|
||||
def test_versions(version):
|
||||
executable = 'python' + version
|
||||
executable_name = 'python' + version
|
||||
executable = find_executable(executable_name)
|
||||
if executable is None:
|
||||
executable = executable_name
|
||||
try:
|
||||
env = Environment('some path', executable)
|
||||
except InvalidPythonEnvironment:
|
||||
@@ -40,7 +44,7 @@ def test_versions(version):
|
||||
return
|
||||
|
||||
sys_path = env.get_sys_path()
|
||||
assert any(executable in p for p in sys_path)
|
||||
assert any(executable_name in p for p in sys_path)
|
||||
|
||||
|
||||
def test_load_module(evaluator):
|
||||
@@ -109,3 +113,8 @@ def test_not_existing_virtualenv():
|
||||
def test_working_venv(venv_path):
|
||||
with set_environment_variable('VIRTUAL_ENV', venv_path):
|
||||
assert get_default_environment()._base_path == venv_path
|
||||
|
||||
|
||||
def test_scanning_venvs(venv_path):
|
||||
parent_dir = os.path.dirname(venv_path)
|
||||
assert any(venv._base_path == venv_path for venv in find_virtualenvs([parent_dir]))
|
||||
|
||||
Reference in New Issue
Block a user