diff --git a/jedi/api/environment.py b/jedi/api/environment.py index 9d095bad..30d653cf 100644 --- a/jedi/api/environment.py +++ b/jedi/api/environment.py @@ -78,8 +78,8 @@ def find_virtualenvs(paths=None): paths = [] for path in paths: - executable = _get_executable_path(path) try: + executable = _get_executable_path(path) yield Environment(path, executable) except InvalidPythonEnvironment: pass @@ -123,7 +123,7 @@ def _get_executable_path(path): activate = os.path.join(bin_folder, 'activate') python = os.path.join(bin_folder, 'python') if not all(os.path.exists(p) for p in (activate, python)): - return None + raise InvalidPythonEnvironment("One of bin/activate and bin/python is missing.") return python diff --git a/test/test_evaluate/sample_venvs/venv27/lib/python2.7/site-packages/dir-from-foo-pth/__init__.py b/test/test_evaluate/sample_venvs/pth_directory/dir-from-foo-pth/__init__.py similarity index 100% rename from test/test_evaluate/sample_venvs/venv27/lib/python2.7/site-packages/dir-from-foo-pth/__init__.py rename to test/test_evaluate/sample_venvs/pth_directory/dir-from-foo-pth/__init__.py diff --git a/test/test_evaluate/sample_venvs/venv27/lib/python2.7/site-packages/egg_link.egg-link b/test/test_evaluate/sample_venvs/pth_directory/egg_link.egg-link similarity index 100% rename from test/test_evaluate/sample_venvs/venv27/lib/python2.7/site-packages/egg_link.egg-link rename to test/test_evaluate/sample_venvs/pth_directory/egg_link.egg-link diff --git a/test/test_evaluate/sample_venvs/venv27/lib/python2.7/site-packages/foo.pth b/test/test_evaluate/sample_venvs/pth_directory/foo.pth similarity index 100% rename from test/test_evaluate/sample_venvs/venv27/lib/python2.7/site-packages/foo.pth rename to test/test_evaluate/sample_venvs/pth_directory/foo.pth diff --git a/test/test_evaluate/sample_venvs/pth_directory/import_smth.pth b/test/test_evaluate/sample_venvs/pth_directory/import_smth.pth new file mode 100644 index 00000000..0a978a8f --- /dev/null +++ b/test/test_evaluate/sample_venvs/pth_directory/import_smth.pth @@ -0,0 +1 @@ +import smth; smth.extend_path_foo() diff --git a/test/test_evaluate/sample_venvs/venv27/lib/python2.7/site-packages/relative.egg-link b/test/test_evaluate/sample_venvs/pth_directory/relative.egg-link similarity index 100% rename from test/test_evaluate/sample_venvs/venv27/lib/python2.7/site-packages/relative.egg-link rename to test/test_evaluate/sample_venvs/pth_directory/relative.egg-link diff --git a/test/test_evaluate/sample_venvs/pth_directory/smth.py b/test/test_evaluate/sample_venvs/pth_directory/smth.py new file mode 100644 index 00000000..6d1eefe3 --- /dev/null +++ b/test/test_evaluate/sample_venvs/pth_directory/smth.py @@ -0,0 +1,6 @@ +import sys +sys.path.append('/foo/smth.py:module') + + +def extend_path_foo(): + sys.path.append('/foo/smth.py:from_func') diff --git a/test/test_evaluate/sample_venvs/venv27/lib/python2.7/site-packages/import_smth.pth b/test/test_evaluate/sample_venvs/venv27/lib/python2.7/site-packages/import_smth.pth deleted file mode 100644 index 72b006a6..00000000 --- a/test/test_evaluate/sample_venvs/venv27/lib/python2.7/site-packages/import_smth.pth +++ /dev/null @@ -1 +0,0 @@ -import smth; smth.extend_path() \ No newline at end of file diff --git a/test/test_evaluate/sample_venvs/venv27/lib/python2.7/site-packages/smth.py b/test/test_evaluate/sample_venvs/venv27/lib/python2.7/site-packages/smth.py deleted file mode 100644 index 3e3008dd..00000000 --- a/test/test_evaluate/sample_venvs/venv27/lib/python2.7/site-packages/smth.py +++ /dev/null @@ -1,6 +0,0 @@ -import sys -sys.path.append('/path/from/smth.py') - - -def extend_path(): - sys.path.append('/path/from/smth.py:extend_path') diff --git a/test/test_evaluate/sample_venvs/venv34/lib/python3.4/site-packages/dir-from-foo-pth/__init__.py b/test/test_evaluate/sample_venvs/venv34/lib/python3.4/site-packages/dir-from-foo-pth/__init__.py deleted file mode 100644 index 2a1d8700..00000000 --- a/test/test_evaluate/sample_venvs/venv34/lib/python3.4/site-packages/dir-from-foo-pth/__init__.py +++ /dev/null @@ -1,2 +0,0 @@ -# This file is here to force git to create the directory, as *.pth files only -# add existing directories. diff --git a/test/test_evaluate/sample_venvs/venv34/lib/python3.4/site-packages/egg_link.egg-link b/test/test_evaluate/sample_venvs/venv34/lib/python3.4/site-packages/egg_link.egg-link deleted file mode 100644 index dde9b7d5..00000000 --- a/test/test_evaluate/sample_venvs/venv34/lib/python3.4/site-packages/egg_link.egg-link +++ /dev/null @@ -1 +0,0 @@ -/path/from/egg-link diff --git a/test/test_evaluate/sample_venvs/venv34/lib/python3.4/site-packages/foo.pth b/test/test_evaluate/sample_venvs/venv34/lib/python3.4/site-packages/foo.pth deleted file mode 100644 index 88501682..00000000 --- a/test/test_evaluate/sample_venvs/venv34/lib/python3.4/site-packages/foo.pth +++ /dev/null @@ -1 +0,0 @@ -./dir-from-foo-pth diff --git a/test/test_evaluate/sample_venvs/venv34/lib/python3.4/site-packages/import_smth.pth b/test/test_evaluate/sample_venvs/venv34/lib/python3.4/site-packages/import_smth.pth deleted file mode 100644 index 72b006a6..00000000 --- a/test/test_evaluate/sample_venvs/venv34/lib/python3.4/site-packages/import_smth.pth +++ /dev/null @@ -1 +0,0 @@ -import smth; smth.extend_path() \ No newline at end of file diff --git a/test/test_evaluate/sample_venvs/venv34/lib/python3.4/site-packages/relative.egg-link b/test/test_evaluate/sample_venvs/venv34/lib/python3.4/site-packages/relative.egg-link deleted file mode 100644 index 7a9a6156..00000000 --- a/test/test_evaluate/sample_venvs/venv34/lib/python3.4/site-packages/relative.egg-link +++ /dev/null @@ -1 +0,0 @@ -./relative/egg-link/path diff --git a/test/test_evaluate/sample_venvs/venv34/lib/python3.4/site-packages/smth.py b/test/test_evaluate/sample_venvs/venv34/lib/python3.4/site-packages/smth.py deleted file mode 100644 index 3e3008dd..00000000 --- a/test/test_evaluate/sample_venvs/venv34/lib/python3.4/site-packages/smth.py +++ /dev/null @@ -1,6 +0,0 @@ -import sys -sys.path.append('/path/from/smth.py') - - -def extend_path(): - sys.path.append('/path/from/smth.py:extend_path') diff --git a/test/test_evaluate/test_sys_path.py b/test/test_evaluate/test_sys_path.py index 14bb41c9..b9fdda06 100644 --- a/test/test_evaluate/test_sys_path.py +++ b/test/test_evaluate/test_sys_path.py @@ -1,10 +1,12 @@ import os from glob import glob import sys +import shutil 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): @@ -21,37 +23,44 @@ def test_paths_from_assignment(Script): assert paths('sys.path, other = ["a"], 2') == set() -# Currently venv site-packages resolution only seeks pythonX.Y/site-packages -# that belong to the same version as the interpreter to avoid issues with -# cross-version imports. "venvs/" dir contains "venv27" and "venv34" that -# mimic venvs created for py2.7 and py3.4 respectively. If test runner is -# invoked with one of those versions, the test below will be run for the -# matching directory. -CUR_DIR = os.path.dirname(__file__) -VENVS = list(glob( - os.path.join(CUR_DIR, 'sample_venvs/venv%d%d' % sys.version_info[:2]))) +def test_venv_and_pths(tmpdir, environment): + if environment.version_info.major < 3: + pytest.skip("python -m venv does not exist in Python 2") - -@pytest.mark.parametrize('venv', VENVS) -def test_get_venv_path(venv): pjoin = os.path.join - venv_path = sys_path.get_venv_path(venv) - site_pkgs = (glob(pjoin(venv, 'lib', 'python*', 'site-packages')) + - glob(pjoin(venv, 'lib', 'site-packages')))[0] + dirname = pjoin(tmpdir.dirname, 'venv') + + # Ignore if it fails. It usually fails if it's not able to properly install + # pip. However we don't need that for this test. + os.system(environment._executable + ' -m venv ' + dirname) + + # We cannot find the virtualenv in some cases, because the virtualenv was + # not created correctly. + virtualenv = Environment(dirname, pjoin(dirname, 'bin', 'python')) + + CUR_DIR = os.path.dirname(__file__) + site_pkg_path = glob(pjoin(virtualenv._base_path, 'lib', '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 = [ - pjoin('/path', 'from', 'egg-link'), - pjoin(site_pkgs, '.', 'relative', 'egg-link', 'path'), - site_pkgs, - pjoin(site_pkgs, 'dir-from-foo-pth'), + # 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_path[:len(ETALON)] == ETALON + assert venv_paths[-len(ETALON):] == ETALON # Ensure that none of venv dirs leaked to the interpreter. assert not set(sys.path).intersection(ETALON) - - # Ensure that "import ..." lines were ignored. - assert pjoin('/path', 'from', 'smth.py') not in venv_path - assert pjoin('/path', 'from', 'smth.py:extend_path') not in venv_path