forked from VimPlug/jedi
Improve virtualenv support & egg-link resolution
- add sys_path= kwarg to Script & Evaluator constructors - store sys_path for each evaluator instance - replace get_sys_path with get_venv_path - get_venv_path: use addsitedir to load .pth extension files - get_venv_path: look for egg-link files in all directories in path
This commit is contained in:
@@ -1,55 +1,53 @@
|
||||
import jedi
|
||||
import sys
|
||||
from os.path import dirname, join
|
||||
|
||||
|
||||
def test_namespace_package():
|
||||
sys.path.insert(0, join(dirname(__file__), 'namespace_package/ns1'))
|
||||
sys.path.insert(1, join(dirname(__file__), 'namespace_package/ns2'))
|
||||
try:
|
||||
# goto definition
|
||||
assert jedi.Script('from pkg import ns1_file').goto_definitions()
|
||||
assert jedi.Script('from pkg import ns2_file').goto_definitions()
|
||||
assert not jedi.Script('from pkg import ns3_file').goto_definitions()
|
||||
sys_path = [join(dirname(__file__), d)
|
||||
for d in ['namespace_package/ns1', 'namespace_package/ns2']]
|
||||
|
||||
# goto assignment
|
||||
tests = {
|
||||
'from pkg.ns2_folder.nested import foo': 'nested!',
|
||||
'from pkg.ns2_folder import foo': 'ns2_folder!',
|
||||
'from pkg.ns2_file import foo': 'ns2_file!',
|
||||
'from pkg.ns1_folder import foo': 'ns1_folder!',
|
||||
'from pkg.ns1_file import foo': 'ns1_file!',
|
||||
'from pkg import foo': 'ns1!',
|
||||
}
|
||||
for source, solution in tests.items():
|
||||
ass = jedi.Script(source).goto_assignments()
|
||||
assert len(ass) == 1
|
||||
assert ass[0].description == "foo = '%s'" % solution
|
||||
def script_with_path(*args, **kwargs):
|
||||
return jedi.Script(sys_path=sys_path, *args, **kwargs)
|
||||
|
||||
# completion
|
||||
completions = jedi.Script('from pkg import ').completions()
|
||||
names = [str(c.name) for c in completions] # str because of unicode
|
||||
compare = ['foo', 'ns1_file', 'ns1_folder', 'ns2_folder', 'ns2_file',
|
||||
'pkg_resources', 'pkgutil', '__name__', '__path__',
|
||||
'__package__', '__file__', '__doc__']
|
||||
# must at least contain these items, other items are not important
|
||||
assert set(compare) == set(names)
|
||||
# goto definition
|
||||
assert script_with_path('from pkg import ns1_file').goto_definitions()
|
||||
assert script_with_path('from pkg import ns2_file').goto_definitions()
|
||||
assert not script_with_path('from pkg import ns3_file').goto_definitions()
|
||||
|
||||
tests = {
|
||||
'from pkg import ns2_folder as x': 'ns2_folder!',
|
||||
'from pkg import ns2_file as x': 'ns2_file!',
|
||||
'from pkg.ns2_folder import nested as x': 'nested!',
|
||||
'from pkg import ns1_folder as x': 'ns1_folder!',
|
||||
'from pkg import ns1_file as x': 'ns1_file!',
|
||||
'import pkg as x': 'ns1!',
|
||||
}
|
||||
for source, solution in tests.items():
|
||||
for c in jedi.Script(source + '; x.').completions():
|
||||
if c.name == 'foo':
|
||||
completion = c
|
||||
solution = "statement: foo = '%s'" % solution
|
||||
assert completion.description == solution
|
||||
# goto assignment
|
||||
tests = {
|
||||
'from pkg.ns2_folder.nested import foo': 'nested!',
|
||||
'from pkg.ns2_folder import foo': 'ns2_folder!',
|
||||
'from pkg.ns2_file import foo': 'ns2_file!',
|
||||
'from pkg.ns1_folder import foo': 'ns1_folder!',
|
||||
'from pkg.ns1_file import foo': 'ns1_file!',
|
||||
'from pkg import foo': 'ns1!',
|
||||
}
|
||||
for source, solution in tests.items():
|
||||
ass = script_with_path(source).goto_assignments()
|
||||
assert len(ass) == 1
|
||||
assert ass[0].description == "foo = '%s'" % solution
|
||||
|
||||
finally:
|
||||
sys.path.pop(0)
|
||||
sys.path.pop(0)
|
||||
# completion
|
||||
completions = script_with_path('from pkg import ').completions()
|
||||
names = [str(c.name) for c in completions] # str because of unicode
|
||||
compare = ['foo', 'ns1_file', 'ns1_folder', 'ns2_folder', 'ns2_file',
|
||||
'pkg_resources', 'pkgutil', '__name__', '__path__',
|
||||
'__package__', '__file__', '__doc__']
|
||||
# must at least contain these items, other items are not important
|
||||
assert set(compare) == set(names)
|
||||
|
||||
tests = {
|
||||
'from pkg import ns2_folder as x': 'ns2_folder!',
|
||||
'from pkg import ns2_file as x': 'ns2_file!',
|
||||
'from pkg.ns2_folder import nested as x': 'nested!',
|
||||
'from pkg import ns1_folder as x': 'ns1_folder!',
|
||||
'from pkg import ns1_file as x': 'ns1_file!',
|
||||
'import pkg as x': 'ns1!',
|
||||
}
|
||||
for source, solution in tests.items():
|
||||
for c in script_with_path(source + '; x.').completions():
|
||||
if c.name == 'foo':
|
||||
completion = c
|
||||
solution = "statement: foo = '%s'" % solution
|
||||
assert completion.description == solution
|
||||
|
||||
@@ -1,4 +1,8 @@
|
||||
import os
|
||||
from glob import glob
|
||||
import sys
|
||||
|
||||
import pytest
|
||||
|
||||
from jedi._compatibility import unicode
|
||||
from jedi.parser import Parser, load_grammar
|
||||
@@ -19,13 +23,30 @@ def test_paths_from_assignment():
|
||||
assert paths('sys.path, other = ["a"], 2') == []
|
||||
|
||||
|
||||
def test_get_sys_path(monkeypatch):
|
||||
monkeypatch.setenv('VIRTUAL_ENV', os.path.join(os.path.dirname(__file__),
|
||||
'egg-link', 'venv'))
|
||||
def sitepackages_dir(venv):
|
||||
return os.path.join(venv, 'lib', 'python3.4', 'site-packages')
|
||||
# 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,
|
||||
'venvs/venv%d%d' % sys.version_info[:2])))
|
||||
|
||||
monkeypatch.setattr('jedi.evaluate.sys_path._get_venv_sitepackages',
|
||||
sitepackages_dir)
|
||||
|
||||
assert '/path/from/egg-link' in sys_path.get_sys_path()
|
||||
@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]
|
||||
ETALON = [
|
||||
site_pkgs,
|
||||
pjoin(site_pkgs, '.', 'relative', 'egg-link', 'path'),
|
||||
pjoin('/path', 'from', 'egg-link'),
|
||||
pjoin(site_pkgs, 'dir-from-foo-pth'),
|
||||
pjoin('/path', 'from', 'smth.py'),
|
||||
pjoin('/path', 'from', 'smth.py:extend_path')
|
||||
]
|
||||
assert venv_path[:len(ETALON)] == ETALON
|
||||
|
||||
@@ -0,0 +1,2 @@
|
||||
# This file is here to force git to create the directory, as *.pth files only
|
||||
# add existing directories.
|
||||
@@ -0,0 +1 @@
|
||||
./dir-from-foo-pth
|
||||
@@ -0,0 +1 @@
|
||||
import smth; smth.extend_path()
|
||||
@@ -0,0 +1 @@
|
||||
./relative/egg-link/path
|
||||
@@ -0,0 +1,6 @@
|
||||
import sys
|
||||
sys.path.append('/path/from/smth.py')
|
||||
|
||||
|
||||
def extend_path():
|
||||
sys.path.append('/path/from/smth.py:extend_path')
|
||||
@@ -0,0 +1,2 @@
|
||||
# This file is here to force git to create the directory, as *.pth files only
|
||||
# add existing directories.
|
||||
@@ -0,0 +1 @@
|
||||
/path/from/egg-link
|
||||
@@ -0,0 +1 @@
|
||||
./dir-from-foo-pth
|
||||
@@ -0,0 +1 @@
|
||||
import smth; smth.extend_path()
|
||||
@@ -0,0 +1 @@
|
||||
./relative/egg-link/path
|
||||
@@ -0,0 +1,6 @@
|
||||
import sys
|
||||
sys.path.append('/path/from/smth.py')
|
||||
|
||||
|
||||
def extend_path():
|
||||
sys.path.append('/path/from/smth.py:extend_path')
|
||||
Reference in New Issue
Block a user