1
0
forked from VimPlug/jedi
Files
jedi-fork/test/test_evaluate/test_sys_path.py
micbou 65a8ec6abc Improve venv_and_pths test
Python is not necessarily installed in /usr/bin. Execute Python to find the
real prefix.
2018-03-24 20:52:51 +01:00

91 lines
3.2 KiB
Python

import os
from glob import glob
import sys
import shutil
import subprocess
import pytest
from jedi.evaluate import sys_path
from jedi import find_virtualenvs
from jedi.api.environment import Environment
def test_paths_from_assignment(Script):
def paths(src):
script = Script(src, path='/foo/bar.py')
expr_stmt = script._module_node.children[0]
return set(sys_path._paths_from_assignment(script._get_module(), expr_stmt))
# Normalize paths for Windows.
path_a = os.path.abspath('/foo/a')
path_b = os.path.abspath('/foo/b')
path_c = os.path.abspath('/foo/c')
assert paths('sys.path[0:0] = ["a"]') == {path_a}
assert paths('sys.path = ["b", 1, x + 3, y, "c"]') == {path_b, path_c}
assert paths('sys.path = a = ["a"]') == {path_a}
# Fail for complicated examples.
assert paths('sys.path, other = ["a"], 2') == set()
def test_venv_and_pths(tmpdir, environment):
if environment.version_info.major < 3:
pytest.skip("python -m venv does not exist in Python 2")
pjoin = os.path.join
dirname = pjoin(tmpdir.dirname, 'venv')
# We cannot use the Python from tox because tox creates virtualenvs and they
# have different site.py files that work differently than the default ones.
# Instead, we find the real Python executable by printing the value of
# sys.base_prefix or sys.real_prefix if we are in a virtualenv.
output = subprocess.check_output([
environment._executable, "-c",
"import sys; "
"print(sys.real_prefix if hasattr(sys, 'real_prefix') else "
"sys.base_prefix)"
])
prefix = output.rstrip().decode('utf8')
if os.name == 'nt':
executable_path = os.path.join(prefix, 'python')
else:
executable_name = os.path.basename(environment._executable)
executable_path = os.path.join(prefix, 'bin', executable_name)
subprocess.call([executable_path, '-m', 'venv', dirname])
bin_name = 'Scripts' if os.name == 'nt' else 'bin'
virtualenv = Environment(dirname, pjoin(dirname, bin_name, 'python'))
CUR_DIR = os.path.dirname(__file__)
site_pkg_path = pjoin(virtualenv._base_path, 'lib')
if os.name == 'nt':
site_pkg_path = pjoin(site_pkg_path, 'site-packages')
else:
site_pkg_path = glob(pjoin(site_pkg_path, 'python*', 'site-packages'))[0]
shutil.rmtree(site_pkg_path)
shutil.copytree(pjoin(CUR_DIR, 'sample_venvs', 'pth_directory'), site_pkg_path)
venv_paths = virtualenv.get_sys_path()
ETALON = [
# For now disable egg-links. I have no idea how they work... ~ dave
#pjoin('/path', 'from', 'egg-link'),
#pjoin(site_pkg_path, '.', 'relative', 'egg-link', 'path'),
site_pkg_path,
pjoin(site_pkg_path, 'dir-from-foo-pth'),
'/foo/smth.py:module',
# Not sure why it's added twice. It has to do with site.py which is not
# something we can change. However this obviously also doesn't matter.
'/foo/smth.py:from_func',
'/foo/smth.py:from_func',
]
# Ensure that pth and egg-link paths were added.
assert venv_paths[-len(ETALON):] == ETALON
# Ensure that none of venv dirs leaked to the interpreter.
assert not set(sys.path).intersection(ETALON)