Merge branch 'project'

This commit is contained in:
Dave Halter
2020-03-21 02:52:51 +01:00
30 changed files with 353 additions and 133 deletions
+7
View File
@@ -9,6 +9,7 @@ import pytest
import jedi import jedi
from jedi.api.environment import get_system_environment, InterpreterEnvironment from jedi.api.environment import get_system_environment, InterpreterEnvironment
from jedi._compatibility import py_version from jedi._compatibility import py_version
from test.helpers import test_dir
collect_ignore = [ collect_ignore = [
'setup.py', 'setup.py',
@@ -109,6 +110,12 @@ def Script(environment):
return partial(jedi.Script, environment=environment) return partial(jedi.Script, environment=environment)
@pytest.fixture(scope='session')
def ScriptWithProject(Script):
project = jedi.Project(test_dir)
return partial(jedi.Script, project=project)
@pytest.fixture(scope='session') @pytest.fixture(scope='session')
def get_names(Script): def get_names(Script):
return lambda code, **kwargs: Script(code).get_names(**kwargs) return lambda code, **kwargs: Script(code).get_names(**kwargs)
+1
View File
@@ -41,6 +41,7 @@ from jedi import settings
from jedi.api.environment import find_virtualenvs, find_system_environments, \ from jedi.api.environment import find_virtualenvs, find_system_environments, \
get_default_environment, InvalidPythonEnvironment, create_environment, \ get_default_environment, InvalidPythonEnvironment, create_environment, \
get_system_environment, InterpreterEnvironment get_system_environment, InterpreterEnvironment
from jedi.api.project import Project, get_default_project
from jedi.api.exceptions import InternalError from jedi.api.exceptions import InternalError
# Finally load the internal plugins. This is only internal. # Finally load the internal plugins. This is only internal.
from jedi.plugins import registry from jedi.plugins import registry
+13 -4
View File
@@ -30,6 +30,7 @@ from jedi.api.completion import Completion
from jedi.api.keywords import KeywordName from jedi.api.keywords import KeywordName
from jedi.api.environment import InterpreterEnvironment from jedi.api.environment import InterpreterEnvironment
from jedi.api.project import get_default_project, Project from jedi.api.project import get_default_project, Project
from jedi.api.errors import parso_to_jedi_errors
from jedi.inference import InferenceState from jedi.inference import InferenceState
from jedi.inference import imports from jedi.inference import imports
from jedi.inference.references import find_references from jedi.inference.references import find_references
@@ -87,7 +88,7 @@ class Script(object):
""" """
def __init__(self, source=None, line=None, column=None, path=None, def __init__(self, source=None, line=None, column=None, path=None,
encoding='utf-8', sys_path=None, environment=None, encoding='utf-8', sys_path=None, environment=None,
_project=None): project=None):
self._orig_path = path self._orig_path = path
# An empty path (also empty string) should always result in no path. # An empty path (also empty string) should always result in no path.
self.path = os.path.abspath(path) if path else None self.path = os.path.abspath(path) if path else None
@@ -103,15 +104,20 @@ class Script(object):
if sys_path is not None and not is_py3: if sys_path is not None and not is_py3:
sys_path = list(map(force_unicode, sys_path)) sys_path = list(map(force_unicode, sys_path))
project = _project
if project is None: if project is None:
# Load the Python grammar of the current interpreter. # Load the Python grammar of the current interpreter.
project = get_default_project( project = get_default_project(
os.path.dirname(self.path)if path else os.getcwd() os.path.dirname(self.path) if path else None
) )
# TODO deprecate and remove sys_path from the Script API. # TODO deprecate and remove sys_path from the Script API.
if sys_path is not None: if sys_path is not None:
project._sys_path = sys_path project._sys_path = sys_path
warnings.warn(
"Deprecated since version 0.17.0. Use the project API instead, "
"which means Script(project=Project(dir, sys_path=sys_path)) instead.",
DeprecationWarning,
stacklevel=2
)
self._inference_state = InferenceState( self._inference_state = InferenceState(
project, environment=environment, script_path=self.path project, environment=environment, script_path=self.path
) )
@@ -500,6 +506,9 @@ class Script(object):
""" """
return self._names(**kwargs) # Python 2... return self._names(**kwargs) # Python 2...
def get_syntax_errors(self):
return parso_to_jedi_errors(self._grammar, self._module_node)
def _names(self, all_scopes=False, definitions=True, references=False): def _names(self, all_scopes=False, definitions=True, references=False):
def def_ref_filter(_def): def def_ref_filter(_def):
is_def = _def._name.tree_name.is_definition() is_def = _def._name.tree_name.is_definition()
@@ -560,7 +569,7 @@ class Interpreter(Script):
raise TypeError("The environment needs to be an InterpreterEnvironment subclass.") raise TypeError("The environment needs to be an InterpreterEnvironment subclass.")
super(Interpreter, self).__init__(source, environment=environment, super(Interpreter, self).__init__(source, environment=environment,
_project=Project(os.getcwd()), **kwds) project=Project(os.getcwd()), **kwds)
self.namespaces = namespaces self.namespaces = namespaces
self._inference_state.allow_descriptor_getattr = self._allow_descriptor_getattr_default self._inference_state.allow_descriptor_getattr = self._allow_descriptor_getattr_default
+10
View File
@@ -707,6 +707,16 @@ class Definition(BaseDefinition):
else: else:
return self._name.tree_name.is_definition() return self._name.tree_name.is_definition()
def is_side_effect(self):
"""
Checks if a name is defined as ``self.foo = 3``. In case of self, this
function would return False, for foo it would return True.
"""
tree_name = self._name.tree_name
if tree_name is None:
return False
return tree_name.is_definition() and tree_name.parent.type == 'trailer'
def __eq__(self, other): def __eq__(self, other):
return self._name.start_pos == other._name.start_pos \ return self._name.start_pos == other._name.start_pos \
and self.module_path == other.module_path \ and self.module_path == other.module_path \
+36
View File
@@ -0,0 +1,36 @@
"""
This file is about errors in Python files and not about exception handling in
Jedi.
"""
def parso_to_jedi_errors(grammar, module_node):
return [SyntaxError(e) for e in grammar.iter_errors(module_node)]
class SyntaxError(object):
def __init__(self, parso_error):
self._parso_error = parso_error
@property
def line(self):
return self._parso_error.start_pos[0]
@property
def column(self):
return self._parso_error.start_pos[1]
@property
def until_line(self):
return self._parso_error.end_pos[0]
@property
def until_column(self):
return self._parso_error.end_pos[1]
def __repr__(self):
return '<%s from=%s to=%s>' % (
self.__class__.__name__,
self._parso_error.start_pos,
self._parso_error.end_pos,
)
+50 -31
View File
@@ -1,9 +1,9 @@
import os import os
import errno
import json import json
from jedi._compatibility import FileNotFoundError, PermissionError, IsADirectoryError from jedi._compatibility import FileNotFoundError, PermissionError, IsADirectoryError
from jedi.api.environment import SameEnvironment, \ from jedi.api.environment import get_cached_default_environment, create_environment
get_cached_default_environment
from jedi.api.exceptions import WrongVersion from jedi.api.exceptions import WrongVersion
from jedi._compatibility import force_unicode from jedi._compatibility import force_unicode
from jedi.inference.sys_path import discover_buildout_paths from jedi.inference.sys_path import discover_buildout_paths
@@ -30,13 +30,15 @@ def _force_unicode_list(lst):
class Project(object): class Project(object):
# TODO serialize environment
_serializer_ignore_attributes = ('_environment',)
_environment = None _environment = None
@staticmethod
def _get_config_folder_path(base_path):
return os.path.join(base_path, _CONFIG_FOLDER)
@staticmethod @staticmethod
def _get_json_path(base_path): def _get_json_path(base_path):
return os.path.join(base_path, _CONFIG_FOLDER, 'project.json') return os.path.join(Project._get_config_folder_path(base_path), 'project.json')
@classmethod @classmethod
def load(cls, path): def load(cls, path):
@@ -47,9 +49,7 @@ class Project(object):
version, data = json.load(f) version, data = json.load(f)
if version == 1: if version == 1:
self = cls.__new__() return cls(**data)
self.__dict__.update(data)
return self
else: else:
raise WrongVersion( raise WrongVersion(
"The Jedi version of this project seems newer than what we can handle." "The Jedi version of this project seems newer than what we can handle."
@@ -58,35 +58,40 @@ class Project(object):
def __init__(self, path, **kwargs): def __init__(self, path, **kwargs):
""" """
:param path: The base path for this project. :param path: The base path for this project.
:param python_path: The Python executable path, typically the path of a
virtual environment.
:param load_unsafe_extensions: Loads extensions that are not in the
sys path and in the local directories. With this option enabled,
this is potentially unsafe if you clone a git repository and
analyze it's code, because those compiled extensions will be
important and therefore have execution privileges.
:param sys_path: list of str. You can override the sys path if you :param sys_path: list of str. You can override the sys path if you
want. By default the ``sys.path.`` is generated from the want. By default the ``sys.path.`` is generated from the
environment (virtualenvs, etc). environment (virtualenvs, etc).
:param added_sys_path: list of str. Adds these paths at the end of the
sys path.
:param smart_sys_path: If this is enabled (default), adds paths from :param smart_sys_path: If this is enabled (default), adds paths from
local directories. Otherwise you will have to rely on your packages local directories. Otherwise you will have to rely on your packages
being properly configured on the ``sys.path``. being properly configured on the ``sys.path``.
""" """
def py2_comp(path, environment=None, sys_path=None, def py2_comp(path, python_path=None, load_unsafe_extensions=False,
smart_sys_path=True, _django=False): sys_path=None, added_sys_path=(), smart_sys_path=True):
self._path = os.path.abspath(path) self._path = os.path.abspath(path)
if isinstance(environment, SameEnvironment):
self._environment = environment
self._python_path = python_path
self._sys_path = sys_path self._sys_path = sys_path
self._smart_sys_path = smart_sys_path self._smart_sys_path = smart_sys_path
self._django = _django self._load_unsafe_extensions = load_unsafe_extensions
self._django = False
self.added_sys_path = list(added_sys_path)
"""The sys path that is going to be added at the end of the """
py2_comp(path, **kwargs) py2_comp(path, **kwargs)
@inference_state_as_method_param_cache() @inference_state_as_method_param_cache()
def _get_base_sys_path(self, inference_state, environment=None): def _get_base_sys_path(self, inference_state):
if self._sys_path is not None:
return self._sys_path
# The sys path has not been set explicitly. # The sys path has not been set explicitly.
if environment is None: sys_path = list(inference_state.environment.get_sys_path())
environment = self.get_environment()
sys_path = list(environment.get_sys_path())
try: try:
sys_path.remove('') sys_path.remove('')
except ValueError: except ValueError:
@@ -94,16 +99,19 @@ class Project(object):
return sys_path return sys_path
@inference_state_as_method_param_cache() @inference_state_as_method_param_cache()
def _get_sys_path(self, inference_state, environment=None, def _get_sys_path(self, inference_state, add_parent_paths=True, add_init_paths=False):
add_parent_paths=True, add_init_paths=False):
""" """
Keep this method private for all users of jedi. However internally this Keep this method private for all users of jedi. However internally this
one is used like a public method. one is used like a public method.
""" """
suffixed = [] suffixed = list(self.added_sys_path)
prefixed = [] prefixed = []
sys_path = list(self._get_base_sys_path(inference_state, environment)) if self._sys_path is None:
sys_path = list(self._get_base_sys_path(inference_state))
else:
sys_path = list(self._sys_path)
if self._smart_sys_path: if self._smart_sys_path:
prefixed.append(self._path) prefixed.append(self._path)
@@ -136,16 +144,25 @@ class Project(object):
def save(self): def save(self):
data = dict(self.__dict__) data = dict(self.__dict__)
for attribute in self._serializer_ignore_attributes: data.pop('_environment', None)
data.pop(attribute, None) data.pop('_django', None) # TODO make django setting public?
data = {k.lstrip('_'): v for k, v in data.items()}
with open(self._get_json_path(self._path), 'wb') as f: # TODO when dropping Python 2 use pathlib.Path.mkdir(parents=True, exist_ok=True)
try:
os.makedirs(self._get_config_folder_path(self._path))
except OSError as e:
if e.errno != errno.EEXIST:
raise
with open(self._get_json_path(self._path), 'w') as f:
return json.dump((_SERIALIZER_VERSION, data), f) return json.dump((_SERIALIZER_VERSION, data), f)
def get_environment(self): def get_environment(self):
if self._environment is None: if self._environment is None:
return get_cached_default_environment() if self._python_path is not None:
self._environment = create_environment(self._python_path, safe=False)
else:
self._environment = get_cached_default_environment()
return self._environment return self._environment
def __repr__(self): def __repr__(self):
@@ -192,7 +209,9 @@ def get_default_project(path=None):
first_no_init_file = dir first_no_init_file = dir
if _is_django_path(dir): if _is_django_path(dir):
return Project(dir, _django=True) project = Project(dir)
project._django = True
return project
if probable_path is None and _is_potential_project(dir): if probable_path is None and _is_potential_project(dir):
probable_path = dir probable_path = dir
+1 -1
View File
@@ -142,7 +142,7 @@ class InferenceState(object):
def get_sys_path(self, **kwargs): def get_sys_path(self, **kwargs):
"""Convenience function""" """Convenience function"""
return self.project._get_sys_path(self, environment=self.environment, **kwargs) return self.project._get_sys_path(self, **kwargs)
def infer(self, context, name): def infer(self, context, name):
def_ = name.get_definition(import_name_always=True) def_ = name.get_definition(import_name_always=True)
+7 -2
View File
@@ -191,18 +191,19 @@ class Importer(object):
import_path = base + tuple(import_path) import_path = base + tuple(import_path)
else: else:
path = module_context.py__file__() path = module_context.py__file__()
project_path = self._inference_state.project._path
import_path = list(import_path) import_path = list(import_path)
if path is None: if path is None:
# If no path is defined, our best guess is that the current # If no path is defined, our best guess is that the current
# file is edited by a user on the current working # file is edited by a user on the current working
# directory. We need to add an initial path, because it # directory. We need to add an initial path, because it
# will get removed as the name of the current file. # will get removed as the name of the current file.
directory = os.getcwd() directory = project_path
else: else:
directory = os.path.dirname(path) directory = os.path.dirname(path)
base_import_path, base_directory = _level_to_base_import_path( base_import_path, base_directory = _level_to_base_import_path(
self._inference_state.project._path, directory, level, project_path, directory, level,
) )
if base_directory is None: if base_directory is None:
# Everything is lost, the relative import does point # Everything is lost, the relative import does point
@@ -454,8 +455,12 @@ def _load_python_module(inference_state, file_io,
def _load_builtin_module(inference_state, import_names=None, sys_path=None): def _load_builtin_module(inference_state, import_names=None, sys_path=None):
project = inference_state.project
if sys_path is None: if sys_path is None:
sys_path = inference_state.get_sys_path() sys_path = inference_state.get_sys_path()
if not project._load_unsafe_extensions:
safe_paths = project._get_base_sys_path(inference_state)
sys_path = [p for p in sys_path if p in safe_paths]
dotted_name = '.'.join(import_names) dotted_name = '.'.join(import_names)
assert dotted_name is not None assert dotted_name is not None
+2
View File
@@ -16,8 +16,10 @@ import os
import pytest import pytest
from os.path import abspath, dirname, join from os.path import abspath, dirname, join
from functools import partial, wraps from functools import partial, wraps
from jedi import Project
test_dir = dirname(abspath(__file__)) test_dir = dirname(abspath(__file__))
test_dir_project = Project(test_dir)
root_dir = dirname(test_dir) root_dir = dirname(test_dir)
example_dir = join(test_dir, 'examples') example_dir = join(test_dir, 'examples')
@@ -1,7 +1,9 @@
from os.path import join
from itertools import chain from itertools import chain
from functools import partial
import jedi import jedi
from ..helpers import cwd_at from ..helpers import test_dir
def test_import_empty(Script): def test_import_empty(Script):
@@ -47,8 +49,8 @@ def test_follow_import_incomplete(Script, environment):
assert alias == ['module'] assert alias == ['module']
@cwd_at('test/completion/import_tree')
def test_follow_definition_nested_import(Script): def test_follow_definition_nested_import(Script):
Script = partial(Script, project=jedi.Project(join(test_dir, 'completion', 'import_tree')))
types = check_follow_definition_types(Script, "import pkg.mod1; pkg") types = check_follow_definition_types(Script, "import pkg.mod1; pkg")
assert types == ['module'] assert types == ['module']
+3 -2
View File
@@ -129,10 +129,11 @@ def test_completion_docstring(Script, jedi_path):
Jedi should follow imports in certain conditions Jedi should follow imports in certain conditions
""" """
def docstr(src, result): def docstr(src, result):
c = Script(src, sys_path=[jedi_path]).complete()[0] c = Script(src, project=project).complete()[0]
assert c.docstring(raw=True, fast=False) == cleandoc(result) assert c.docstring(raw=True, fast=False) == cleandoc(result)
c = Script('import jedi\njed', sys_path=[jedi_path]).complete()[0] project = jedi.Project('.', sys_path=[jedi_path])
c = Script('import jedi\njed', project=project).complete()[0]
assert c.docstring(fast=False) == cleandoc(jedi_doc) assert c.docstring(fast=False) == cleandoc(jedi_doc)
docstr('import jedi\njedi.Scr', cleandoc(jedi.Script.__doc__)) docstr('import jedi\njedi.Scr', cleandoc(jedi.Script.__doc__))
+3 -2
View File
@@ -97,9 +97,10 @@ def test_sub_module(Script, jedi_path):
path. path.
""" """
sys_path = [jedi_path] sys_path = [jedi_path]
defs = Script('from jedi.api import classes; classes', sys_path=sys_path).infer() project = jedi.Project('.', sys_path=sys_path)
defs = Script('from jedi.api import classes; classes', project=project).infer()
assert [d.full_name for d in defs] == ['jedi.api.classes'] assert [d.full_name for d in defs] == ['jedi.api.classes']
defs = Script('import jedi.api; jedi.api', sys_path=sys_path).infer() defs = Script('import jedi.api; jedi.api', project=project).infer()
assert [d.full_name for d in defs] == ['jedi.api'] assert [d.full_name for d in defs] == ['jedi.api']
@@ -4,6 +4,8 @@ Tests for `api.names`.
from textwrap import dedent from textwrap import dedent
import pytest
def _assert_definition_names(definitions, names): def _assert_definition_names(definitions, names):
assert [d.name for d in definitions] == names assert [d.name for d in definitions] == names
@@ -167,3 +169,23 @@ def test_no_error(get_names):
assert b.name == 'b' assert b.name == 'b'
assert a20.name == 'a' assert a20.name == 'a'
assert a20.goto() == [a20] assert a20.goto() == [a20]
@pytest.mark.parametrize(
'code, index, is_side_effect', [
('x', 0, False),
('x.x', 0, False),
('x.x', 1, False),
('x.x = 3', 0, False),
('x.x = 3', 1, True),
('def x(x): x.x = 3', 1, False),
('def x(x): x.x = 3', 3, True),
('import sys; sys.path', 0, False),
('import sys; sys.path', 1, False),
('import sys; sys.path', 2, False),
('import sys; sys.path = []', 2, True),
]
)
def test_is_side_effect(get_names, code, index, is_side_effect):
names = get_names(code, references=True, all_scopes=True)
assert names[index].is_side_effect() == is_side_effect
+16
View File
@@ -2,6 +2,7 @@ import os
from ..helpers import get_example_dir, set_cwd, root_dir from ..helpers import get_example_dir, set_cwd, root_dir
from jedi import Interpreter from jedi import Interpreter
from jedi.api import Project, get_default_project
def test_django_default_project(Script): def test_django_default_project(Script):
@@ -22,3 +23,18 @@ def test_interpreter_project_path():
with set_cwd(dir): with set_cwd(dir):
project = Interpreter('', [locals()])._inference_state.project project = Interpreter('', [locals()])._inference_state.project
assert project._path == dir assert project._path == dir
def test_added_sys_path(inference_state):
project = get_default_project()
p = '/some_random_path'
project.added_sys_path = [p]
assert p in project._get_sys_path(inference_state)
def test_load_save_project(tmpdir):
project = Project(tmpdir.strpath, added_sys_path=['/foo'])
project.save()
loaded = Project.load(tmpdir.strpath)
assert loaded.added_sys_path == ['/foo']
-2
View File
@@ -4,11 +4,9 @@ import pytest
from jedi import api from jedi import api
from jedi.inference import imports from jedi.inference import imports
from ..helpers import cwd_at
@pytest.mark.skipif('True', reason='Skip for now, test case is not really supported.') @pytest.mark.skipif('True', reason='Skip for now, test case is not really supported.')
@cwd_at('jedi')
def test_add_dynamic_mods(Script): def test_add_dynamic_mods(Script):
fname = '__main__.py' fname = '__main__.py'
api.settings.additional_dynamic_modules = [fname] api.settings.additional_dynamic_modules = [fname]
+54
View File
@@ -0,0 +1,54 @@
"""
These tests test Jedi's Parso usage. Basically there's not a lot of tests here,
because we're just checking if the API works. Bugfixes should be done in parso,
mostly.
"""
from textwrap import dedent
import pytest
@pytest.mark.parametrize(
'code, line, column, until_line, until_column', [
('?\n', 1, 0, 1, 1),
('x %% y', 1, 3, 1, 4),
('"""\n\n', 1, 0, 3, 0),
('(1, 2\n', 2, 0, 2, 0),
('foo(1, 2\ndef x(): pass', 2, 0, 2, 3),
]
)
def test_simple_syntax_errors(Script, code, line, column, until_line, until_column):
e, = Script(code).get_syntax_errors()
assert e.line == line
assert e.column == column
assert e.until_line == until_line
assert e.until_column == until_column
@pytest.mark.parametrize(
'code', [
'x % y',
'def x(x): pass',
'def x(x):\n pass',
]
)
def test_no_syntax_errors(Script, code):
assert not Script(code).get_syntax_errors()
def test_multi_syntax_error(Script):
code = dedent('''\
def x():
1
def y()
1 + 1
1 *** 3
''')
x, y, power = Script(code).get_syntax_errors()
assert x.line == 2
assert x.column == 0
assert y.line == 3
assert y.column == 7
assert power.line == 5
assert power.column == 4
+3 -1
View File
@@ -3,6 +3,7 @@
All character set and unicode related tests. All character set and unicode related tests.
""" """
from jedi._compatibility import u, unicode from jedi._compatibility import u, unicode
from jedi import Project
def test_unicode_script(Script): def test_unicode_script(Script):
@@ -70,7 +71,8 @@ def test_wrong_encoding(Script, tmpdir):
# Use both latin-1 and utf-8 (a really broken file). # Use both latin-1 and utf-8 (a really broken file).
x.write_binary(u'foobar = 1\nä'.encode('latin-1') + u'ä'.encode('utf-8')) x.write_binary(u'foobar = 1\nä'.encode('latin-1') + u'ä'.encode('utf-8'))
c, = Script('import x; x.foo', sys_path=[tmpdir.strpath]).complete() project = Project('.', sys_path=[tmpdir.strpath])
c, = Script('import x; x.foo', project=project).complete()
assert c.name == 'foobar' assert c.name == 'foobar'
+1 -1
View File
@@ -6,7 +6,7 @@ def test_import_references(Script):
def test_exclude_builtin_modules(Script): def test_exclude_builtin_modules(Script):
def get(include): def get(include):
from jedi.api.project import Project from jedi.api.project import Project
script = Script(source, _project=Project('', sys_path=[], smart_sys_path=False)) script = Script(source, project=Project('', sys_path=[], smart_sys_path=False))
references = script.get_references(column=8, include_builtins=include) references = script.get_references(column=8, include_builtins=include)
return [(d.line, d.column) for d in references] return [(d.line, d.column) for d in references]
source = '''import sys\nprint(sys.path)''' source = '''import sys\nprint(sys.path)'''
+3 -2
View File
@@ -2,10 +2,11 @@
Tests ``from __future__ import absolute_import`` (only important for Tests ``from __future__ import absolute_import`` (only important for
Python 2.X) Python 2.X)
""" """
from jedi import Project
from .. import helpers from .. import helpers
@helpers.cwd_at("test/examples/absolute_import")
def test_can_complete_when_shadowing(Script): def test_can_complete_when_shadowing(Script):
script = Script(path="unittest.py") path = helpers.get_example_dir('absolute_import', 'unittest.py')
script = Script(path=path, project=Project(helpers.get_example_dir('absolute_import')))
assert script.complete() assert script.complete()
+7 -10
View File
@@ -5,7 +5,7 @@ from jedi._compatibility import force_unicode
from jedi.inference.sys_path import _get_parent_dir_with_file, \ from jedi.inference.sys_path import _get_parent_dir_with_file, \
_get_buildout_script_paths, check_sys_path_modifications _get_buildout_script_paths, check_sys_path_modifications
from ..helpers import cwd_at from ..helpers import get_example_dir
def check_module_test(Script, code): def check_module_test(Script, code):
@@ -13,20 +13,18 @@ def check_module_test(Script, code):
return check_sys_path_modifications(module_context) return check_sys_path_modifications(module_context)
@cwd_at('test/examples/buildout_project/src/proj_name')
def test_parent_dir_with_file(Script): def test_parent_dir_with_file(Script):
parent = _get_parent_dir_with_file( path = get_example_dir('buildout_project', 'src', 'proj_name')
os.path.abspath(os.curdir), 'buildout.cfg') parent = _get_parent_dir_with_file(path, 'buildout.cfg')
assert parent is not None assert parent is not None
assert parent.endswith(os.path.join('test', 'examples', 'buildout_project')) assert parent.endswith(os.path.join('test', 'examples', 'buildout_project'))
@cwd_at('test/examples/buildout_project/src/proj_name')
def test_buildout_detection(Script): def test_buildout_detection(Script):
scripts = list(_get_buildout_script_paths(os.path.abspath('./module_name.py'))) path = get_example_dir('buildout_project', 'src', 'proj_name')
scripts = list(_get_buildout_script_paths(os.path.join(path, 'module_name.py')))
assert len(scripts) == 1 assert len(scripts) == 1
curdir = os.path.abspath(os.curdir) appdir_path = os.path.normpath(os.path.join(path, '../../bin/app'))
appdir_path = os.path.normpath(os.path.join(curdir, '../../bin/app'))
assert scripts[0] == appdir_path assert scripts[0] == appdir_path
@@ -53,13 +51,12 @@ def test_path_from_invalid_sys_path_assignment(Script):
assert 'invalid' not in paths assert 'invalid' not in paths
@cwd_at('test/examples/buildout_project/src/proj_name/')
def test_sys_path_with_modifications(Script): def test_sys_path_with_modifications(Script):
path = get_example_dir('buildout_project', 'src', 'proj_name', 'module_name.py')
code = dedent(""" code = dedent("""
import os import os
""") """)
path = os.path.abspath(os.path.join(os.curdir, 'module_name.py'))
paths = Script(code, path=path)._inference_state.get_sys_path() paths = Script(code, path=path)._inference_state.get_sys_path()
assert '/tmp/.buildout/eggs/important_package.egg' in paths assert '/tmp/.buildout/eggs/important_package.egg' in paths
+25 -7
View File
@@ -4,7 +4,7 @@ Test compiled module
import os import os
import jedi import jedi
from ..helpers import cwd_at from ..helpers import get_example_dir
import pytest import pytest
@@ -34,9 +34,9 @@ def test_get_signatures_stdlib(Script):
# Check only on linux 64 bit platform and Python3.4. # Check only on linux 64 bit platform and Python3.4.
@pytest.mark.parametrize('load_unsafe_extensions', [False, True])
@pytest.mark.skipif('sys.platform != "linux" or sys.maxsize <= 2**32 or sys.version_info[:2] != (3, 4)') @pytest.mark.skipif('sys.platform != "linux" or sys.maxsize <= 2**32 or sys.version_info[:2] != (3, 4)')
@cwd_at('test/examples') def test_init_extension_module(Script, load_unsafe_extensions):
def test_init_extension_module(Script):
""" """
``__init__`` extension modules are also packages and Jedi should understand ``__init__`` extension modules are also packages and Jedi should understand
that. that.
@@ -50,8 +50,26 @@ def test_init_extension_module(Script):
This is also why this test only runs on certain systems (and Python 3.4). This is also why this test only runs on certain systems (and Python 3.4).
""" """
s = jedi.Script('import init_extension_module as i\ni.', path='not_existing.py')
assert 'foo' in [c.name for c in s.complete()]
s = jedi.Script('from init_extension_module import foo\nfoo', path='not_existing.py') project = jedi.Project(get_example_dir(), load_unsafe_extensions=load_unsafe_extensions)
assert ['foo'] == [c.name for c in s.complete()] s = jedi.Script(
'import init_extension_module as i\ni.',
path='not_existing.py',
project=project,
)
if load_unsafe_extensions:
assert 'foo' in [c.name for c in s.complete()]
else:
assert 'foo' not in [c.name for c in s.complete()]
s = jedi.Script(
'from init_extension_module import foo\nfoo',
path='not_existing.py',
project=project,
)
c, = s.complete()
assert c.name == 'foo'
if load_unsafe_extensions:
assert c.infer()
else:
assert not c.infer()
@@ -28,10 +28,10 @@ def test_sqlite3_conversion(Script):
def test_conversion_of_stub_only(Script): def test_conversion_of_stub_only(Script):
project = Project(os.path.join(root_dir, 'test', 'completion', 'stub_folder')) project = Project(os.path.join(root_dir, 'test', 'completion', 'stub_folder'))
code = 'import stub_only; stub_only.in_stub_only' code = 'import stub_only; stub_only.in_stub_only'
d1, = Script(code, _project=project).goto() d1, = Script(code, project=project).goto()
assert d1.is_stub() assert d1.is_stub()
script = Script(path=d1.module_path, _project=project) script = Script(path=d1.module_path, project=project)
d2, = script.goto(line=d1.line, column=d1.column) d2, = script.goto(line=d1.line, column=d1.column)
assert d2.is_stub() assert d2.is_stub()
assert d2.module_path == d1.module_path assert d2.module_path == d1.module_path
@@ -42,7 +42,7 @@ def test_conversion_of_stub_only(Script):
def test_goto_on_file(Script): def test_goto_on_file(Script):
project = Project(os.path.join(root_dir, 'test', 'completion', 'stub_folder')) project = Project(os.path.join(root_dir, 'test', 'completion', 'stub_folder'))
script = Script('import stub_only; stub_only.Foo', _project=project) script = Script('import stub_only; stub_only.Foo', project=project)
d1, = script.goto() d1, = script.goto()
v, = d1._name.infer() v, = d1._name.infer()
foo, bar, obj = v.py__mro__() foo, bar, obj = v.py__mro__()
@@ -51,7 +51,7 @@ def test_goto_on_file(Script):
assert obj.py__name__() == 'object' assert obj.py__name__() == 'object'
# Make sure we go to Bar, because Foo is a bit before: `class Foo(Bar):` # Make sure we go to Bar, because Foo is a bit before: `class Foo(Bar):`
script = Script(path=d1.module_path, _project=project) script = Script(path=d1.module_path, project=project)
d2, = script.goto(line=d1.line, column=d1.column + 4) d2, = script.goto(line=d1.line, column=d1.column + 4)
assert d2.name == 'Bar' assert d2.name == 'Bar'
@@ -9,7 +9,7 @@ import pytest
def ScriptInStubFolder(Script): def ScriptInStubFolder(Script):
path = get_example_dir('stub_packages') path = get_example_dir('stub_packages')
project = Project(path, sys_path=[path], smart_sys_path=False) project = Project(path, sys_path=[path], smart_sys_path=False)
return partial(Script, _project=project) return partial(Script, project=project)
@pytest.mark.parametrize( @pytest.mark.parametrize(
@@ -54,7 +54,7 @@ def test_infer_and_goto(Script, code, full_name, has_stub, has_python, way,
has_python = False has_python = False
project = Project(os.path.join(root_dir, 'test', 'completion', 'stub_folder')) project = Project(os.path.join(root_dir, 'test', 'completion', 'stub_folder'))
s = Script(code, _project=project) s = Script(code, project=project)
prefer_stubs = kwargs['prefer_stubs'] prefer_stubs = kwargs['prefer_stubs']
only_stubs = kwargs['only_stubs'] only_stubs = kwargs['only_stubs']
@@ -3,6 +3,7 @@ from os.path import dirname
import pytest import pytest
from test.helpers import get_example_dir, example_dir from test.helpers import get_example_dir, example_dir
from jedi import Project
@pytest.fixture(autouse=True) @pytest.fixture(autouse=True)
@@ -14,9 +15,10 @@ def skip_not_supported_versions(environment):
def test_implicit_namespace_package(Script): def test_implicit_namespace_package(Script):
sys_path = [get_example_dir('implicit_namespace_package', 'ns1'), sys_path = [get_example_dir('implicit_namespace_package', 'ns1'),
get_example_dir('implicit_namespace_package', 'ns2')] get_example_dir('implicit_namespace_package', 'ns2')]
project = Project('.', sys_path=sys_path)
def script_with_path(*args, **kwargs): def script_with_path(*args, **kwargs):
return Script(sys_path=sys_path, *args, **kwargs) return Script(project=project, *args, **kwargs)
# goto definition # goto definition
assert script_with_path('from pkg import ns1_file').infer() assert script_with_path('from pkg import ns1_file').infer()
@@ -55,15 +57,14 @@ def test_implicit_namespace_package(Script):
def test_implicit_nested_namespace_package(Script): def test_implicit_nested_namespace_package(Script):
code = 'from implicit_nested_namespaces.namespace.pkg.module import CONST' code = 'from implicit_nested_namespaces.namespace.pkg.module import CONST'
sys_path = [example_dir] project = Project('.', sys_path=[example_dir])
script = Script(project=project, source=code, line=1, column=61)
script = Script(sys_path=sys_path, source=code, line=1, column=61)
result = script.infer() result = script.infer()
assert len(result) == 1 assert len(result) == 1
implicit_pkg, = Script(code, sys_path=sys_path).infer(column=10) implicit_pkg, = Script(code, project=project).infer(column=10)
assert implicit_pkg.type == 'module' assert implicit_pkg.type == 'module'
assert implicit_pkg.module_path is None assert implicit_pkg.module_path is None
@@ -71,9 +72,8 @@ def test_implicit_nested_namespace_package(Script):
def test_implicit_namespace_package_import_autocomplete(Script): def test_implicit_namespace_package_import_autocomplete(Script):
CODE = 'from implicit_name' CODE = 'from implicit_name'
sys_path = [example_dir] project = Project('.', sys_path=[example_dir])
script = Script(project=project, source=CODE)
script = Script(sys_path=sys_path, source=CODE)
compl = script.complete() compl = script.complete()
assert [c.name for c in compl] == ['implicit_namespace_package'] assert [c.name for c in compl] == ['implicit_namespace_package']
@@ -83,7 +83,8 @@ def test_namespace_package_in_multiple_directories_autocompletion(Script):
sys_path = [get_example_dir('implicit_namespace_package', 'ns1'), sys_path = [get_example_dir('implicit_namespace_package', 'ns1'),
get_example_dir('implicit_namespace_package', 'ns2')] get_example_dir('implicit_namespace_package', 'ns2')]
script = Script(sys_path=sys_path, source=CODE) project = Project('.', sys_path=sys_path)
script = Script(project=project, source=CODE)
compl = script.complete() compl = script.complete()
assert set(c.name for c in compl) == set(['ns1_file', 'ns2_file']) assert set(c.name for c in compl) == set(['ns1_file', 'ns2_file'])
@@ -92,7 +93,8 @@ def test_namespace_package_in_multiple_directories_goto_definition(Script):
CODE = 'from pkg import ns1_file' CODE = 'from pkg import ns1_file'
sys_path = [get_example_dir('implicit_namespace_package', 'ns1'), sys_path = [get_example_dir('implicit_namespace_package', 'ns1'),
get_example_dir('implicit_namespace_package', 'ns2')] get_example_dir('implicit_namespace_package', 'ns2')]
script = Script(sys_path=sys_path, source=CODE) project = Project('.', sys_path=sys_path)
script = Script(project=project, source=CODE)
result = script.infer() result = script.infer()
assert len(result) == 1 assert len(result) == 1
@@ -102,6 +104,7 @@ def test_namespace_name_autocompletion_full_name(Script):
sys_path = [get_example_dir('implicit_namespace_package', 'ns1'), sys_path = [get_example_dir('implicit_namespace_package', 'ns1'),
get_example_dir('implicit_namespace_package', 'ns2')] get_example_dir('implicit_namespace_package', 'ns2')]
script = Script(sys_path=sys_path, source=CODE) project = Project('.', sys_path=sys_path)
script = Script(project=project, source=CODE)
compl = script.complete() compl = script.complete()
assert set(c.full_name for c in compl) == set(['pkg']) assert set(c.full_name for c in compl) == set(['pkg'])
+48 -38
View File
@@ -6,15 +6,15 @@ Tests".
import os import os
import pytest import pytest
from jedi.file_io import FileIO, KnownContentFileIO
from jedi.file_io import FileIO, KnownContentFileIO
from jedi._compatibility import find_module_py33, find_module from jedi._compatibility import find_module_py33, find_module
from jedi.inference import compiled from jedi.inference import compiled
from jedi.inference import imports from jedi.inference import imports
from jedi.api.project import Project from jedi.api.project import Project
from jedi.inference.gradual.conversion import _stub_to_python_value_set from jedi.inference.gradual.conversion import _stub_to_python_value_set
from jedi.inference.references import get_module_contexts_containing_name from jedi.inference.references import get_module_contexts_containing_name
from ..helpers import cwd_at, get_example_dir, test_dir, root_dir from ..helpers import get_example_dir, test_dir, test_dir_project, root_dir
THIS_DIR = os.path.dirname(__file__) THIS_DIR = os.path.dirname(__file__)
@@ -44,7 +44,9 @@ pkg_zip_path = get_example_dir('zipped_imports', 'pkg.zip')
def test_find_module_package_zipped(Script, inference_state, environment): def test_find_module_package_zipped(Script, inference_state, environment):
sys_path = environment.get_sys_path() + [pkg_zip_path] sys_path = environment.get_sys_path() + [pkg_zip_path]
script = Script('import pkg; pkg.mod', sys_path=sys_path)
project = Project('.', sys_path=sys_path)
script = Script('import pkg; pkg.mod', project=project)
assert len(script.complete()) == 1 assert len(script.complete()) == 1
file_io, is_package = inference_state.compiled_subprocess.get_module_info( file_io, is_package = inference_state.compiled_subprocess.get_module_info(
@@ -86,7 +88,7 @@ def test_find_module_package_zipped(Script, inference_state, environment):
def test_correct_zip_package_behavior(Script, inference_state, environment, code, def test_correct_zip_package_behavior(Script, inference_state, environment, code,
file, package, path, skip_python2): file, package, path, skip_python2):
sys_path = environment.get_sys_path() + [pkg_zip_path] sys_path = environment.get_sys_path() + [pkg_zip_path]
pkg, = Script(code, sys_path=sys_path).infer() pkg, = Script(code, project=Project('.', sys_path=sys_path)).infer()
value, = pkg._name.infer() value, = pkg._name.infer()
assert value.py__file__() == os.path.join(pkg_zip_path, 'pkg', file) assert value.py__file__() == os.path.join(pkg_zip_path, 'pkg', file)
assert '.'.join(value.py__package__()) == package assert '.'.join(value.py__package__()) == package
@@ -98,7 +100,7 @@ def test_correct_zip_package_behavior(Script, inference_state, environment, code
def test_find_module_not_package_zipped(Script, inference_state, environment): def test_find_module_not_package_zipped(Script, inference_state, environment):
path = get_example_dir('zipped_imports', 'not_pkg.zip') path = get_example_dir('zipped_imports', 'not_pkg.zip')
sys_path = environment.get_sys_path() + [path] sys_path = environment.get_sys_path() + [path]
script = Script('import not_pkg; not_pkg.val', sys_path=sys_path) script = Script('import not_pkg; not_pkg.val', project=Project('.', sys_path=sys_path))
assert len(script.complete()) == 1 assert len(script.complete()) == 1
file_io, is_package = inference_state.compiled_subprocess.get_module_info( file_io, is_package = inference_state.compiled_subprocess.get_module_info(
@@ -110,19 +112,24 @@ def test_find_module_not_package_zipped(Script, inference_state, environment):
assert is_package is False assert is_package is False
@cwd_at('test/examples/not_in_sys_path/pkg') def test_import_not_in_sys_path(Script, environment):
def test_import_not_in_sys_path(Script):
""" """
non-direct imports (not in sys.path) non-direct imports (not in sys.path)
This is in the end just a fallback. This is in the end just a fallback.
""" """
a = Script(path='module.py').infer(line=5) path = get_example_dir()
module_path = os.path.join(path, 'not_in_sys_path', 'pkg', 'module.py')
# This project tests the smart path option of Project. The sys_path is
# explicitly given to make sure that the path is just dumb and only
# includes non-folder dependencies.
project = Project(path, sys_path=environment.get_sys_path())
a = Script(path=module_path, project=project).infer(line=5)
assert a[0].name == 'int' assert a[0].name == 'int'
a = Script(path='module.py').infer(line=6) a = Script(path=module_path, project=project).infer(line=6)
assert a[0].name == 'str' assert a[0].name == 'str'
a = Script(path='module.py').infer(line=7) a = Script(path=module_path, project=project).infer(line=7)
assert a[0].name == 'str' assert a[0].name == 'str'
@@ -144,14 +151,13 @@ def test_flask_ext(Script, code, name):
"""flask.ext.foo is really imported from flaskext.foo or flask_foo. """flask.ext.foo is really imported from flaskext.foo or flask_foo.
""" """
path = get_example_dir('flask-site-packages') path = get_example_dir('flask-site-packages')
completions = Script(code, sys_path=[path]).complete() completions = Script(code, project=Project('.', sys_path=[path])).complete()
assert name in [c.name for c in completions] assert name in [c.name for c in completions]
@cwd_at('test/test_inference/')
def test_not_importable_file(Script): def test_not_importable_file(Script):
src = 'import not_importable_file as x; x.' src = 'import not_importable_file as x; x.'
assert not Script(src, path='example.py').complete() assert not Script(src, path='example.py', project=test_dir_project).complete()
def test_import_unique(Script): def test_import_unique(Script):
@@ -166,10 +172,14 @@ def test_cache_works_with_sys_path_param(Script, tmpdir):
bar_path = tmpdir.join('bar') bar_path = tmpdir.join('bar')
foo_path.join('module.py').write('foo = 123', ensure=True) foo_path.join('module.py').write('foo = 123', ensure=True)
bar_path.join('module.py').write('bar = 123', ensure=True) bar_path.join('module.py').write('bar = 123', ensure=True)
foo_completions = Script('import module; module.', foo_completions = Script(
sys_path=[foo_path.strpath]).complete() 'import module; module.',
bar_completions = Script('import module; module.', project=Project('.', sys_path=[foo_path.strpath]),
sys_path=[bar_path.strpath]).complete() ).complete()
bar_completions = Script(
'import module; module.',
project=Project('.', sys_path=[bar_path.strpath]),
).complete()
assert 'foo' in [c.name for c in foo_completions] assert 'foo' in [c.name for c in foo_completions]
assert 'bar' not in [c.name for c in foo_completions] assert 'bar' not in [c.name for c in foo_completions]
@@ -194,29 +204,29 @@ def test_goto_definition_on_import(Script):
assert len(Script("import sys").infer(1, 8)) == 1 assert len(Script("import sys").infer(1, 8)) == 1
@cwd_at('jedi') def test_complete_on_empty_import(ScriptWithProject):
def test_complete_on_empty_import(Script): path = os.path.join(test_dir, 'whatever.py')
assert Script("from datetime import").complete()[0].name == 'import' assert ScriptWithProject("from datetime import").complete()[0].name == 'import'
# should just list the files in the directory # should just list the files in the directory
assert 10 < len(Script("from .", path='whatever.py').complete()) < 30 assert 10 < len(ScriptWithProject("from .", path=path).complete()) < 30
# Global import # Global import
assert len(Script("from . import", 'whatever.py').complete(1, 5)) > 30 assert len(ScriptWithProject("from . import", path=path).complete(1, 5)) > 30
# relative import # relative import
assert 10 < len(Script("from . import", 'whatever.py').complete(1, 6)) < 30 assert 10 < len(ScriptWithProject("from . import", path=path).complete(1, 6)) < 30
# Global import # Global import
assert len(Script("from . import classes", 'whatever.py').complete(1, 5)) > 30 assert len(ScriptWithProject("from . import classes", path=path).complete(1, 5)) > 30
# relative import # relative import
assert 10 < len(Script("from . import classes", 'whatever.py').complete(1, 6)) < 30 assert 10 < len(ScriptWithProject("from . import classes", path=path).complete(1, 6)) < 30
wanted = {'ImportError', 'import', 'ImportWarning'} wanted = {'ImportError', 'import', 'ImportWarning'}
assert {c.name for c in Script("import").complete()} == wanted assert {c.name for c in ScriptWithProject("import").complete()} == wanted
assert len(Script("import import", path='').complete()) > 0 assert len(ScriptWithProject("import import", path=path).complete()) > 0
# 111 # 111
assert Script("from datetime import").complete()[0].name == 'import' assert ScriptWithProject("from datetime import").complete()[0].name == 'import'
assert Script("from datetime import ").complete() assert ScriptWithProject("from datetime import ").complete()
def test_imports_on_global_namespace_without_path(Script): def test_imports_on_global_namespace_without_path(Script):
@@ -363,7 +373,7 @@ def test_relative_imports_with_multiple_similar_directories(Script, path, empty_
script = Script( script = Script(
"from . ", "from . ",
path=os.path.join(dir, path), path=os.path.join(dir, path),
_project=project, project=project,
) )
name, import_ = script.complete() name, import_ = script.complete()
assert import_.name == 'import' assert import_.name == 'import'
@@ -376,28 +386,28 @@ def test_relative_imports_with_outside_paths(Script):
script = Script( script = Script(
"from ...", "from ...",
path=os.path.join(dir, 'api/whatever/test_this.py'), path=os.path.join(dir, 'api/whatever/test_this.py'),
_project=project, project=project,
) )
assert [c.name for c in script.complete()] == ['api', 'whatever'] assert [c.name for c in script.complete()] == ['api', 'whatever']
script = Script( script = Script(
"from " + '.' * 100, "from " + '.' * 100,
path=os.path.join(dir, 'api/whatever/test_this.py'), path=os.path.join(dir, 'api/whatever/test_this.py'),
_project=project, project=project,
) )
assert not script.complete() assert not script.complete()
@cwd_at('test/examples/issue1209/api/whatever/')
def test_relative_imports_without_path(Script): def test_relative_imports_without_path(Script):
project = Project('.', sys_path=[], smart_sys_path=False) path = get_example_dir('issue1209', 'api', 'whatever')
script = Script("from . ", _project=project) project = Project(path, sys_path=[], smart_sys_path=False)
script = Script("from . ", project=project)
assert [c.name for c in script.complete()] == ['api_test1', 'import'] assert [c.name for c in script.complete()] == ['api_test1', 'import']
script = Script("from .. ", _project=project) script = Script("from .. ", project=project)
assert [c.name for c in script.complete()] == ['import', 'whatever'] assert [c.name for c in script.complete()] == ['import', 'whatever']
script = Script("from ... ", _project=project) script = Script("from ... ", project=project)
assert [c.name for c in script.complete()] == ['api', 'import', 'whatever'] assert [c.name for c in script.complete()] == ['api', 'import', 'whatever']
@@ -460,7 +470,7 @@ def test_import_needed_modules_by_jedi(Script, environment, tmpdir, name):
script = Script( script = Script(
'import ' + name, 'import ' + name,
path=tmpdir.join('something.py').strpath, path=tmpdir.join('something.py').strpath,
sys_path=[tmpdir.strpath] + environment.get_sys_path(), project=Project('.', sys_path=[tmpdir.strpath] + environment.get_sys_path()),
) )
module, = script.infer() module, = script.infer()
assert module._inference_state.builtins_module.py__file__() != module_path assert module._inference_state.builtins_module.py__file__() != module_path
@@ -4,6 +4,7 @@ import pytest
import py import py
from ..helpers import get_example_dir, example_dir from ..helpers import get_example_dir, example_dir
from jedi import Project
SYS_PATH = [get_example_dir('namespace_package', 'ns1'), SYS_PATH = [get_example_dir('namespace_package', 'ns1'),
@@ -11,7 +12,7 @@ SYS_PATH = [get_example_dir('namespace_package', 'ns1'),
def script_with_path(Script, *args, **kwargs): def script_with_path(Script, *args, **kwargs):
return Script(sys_path=SYS_PATH, *args, **kwargs) return Script(project=Project('.', sys_path=SYS_PATH), *args, **kwargs)
def test_goto_definition(Script): def test_goto_definition(Script):
@@ -69,8 +70,8 @@ def test_nested_namespace_package(Script):
code = 'from nested_namespaces.namespace.pkg import CONST' code = 'from nested_namespaces.namespace.pkg import CONST'
sys_path = [example_dir] sys_path = [example_dir]
project = Project('.', sys_path=sys_path)
script = Script(sys_path=sys_path, source=code) script = Script(project=project, source=code)
result = script.infer(line=1, column=45) result = script.infer(line=1, column=45)
+10 -3
View File
@@ -55,7 +55,8 @@ def pyc_project_path(tmpdir):
shutil.rmtree(path) shutil.rmtree(path)
def test_pyc(pyc_project_path, environment): @pytest.mark.parametrize('load_unsafe_extensions', [False, True])
def test_pyc(pyc_project_path, environment, load_unsafe_extensions):
""" """
The list of completion must be greater than 2. The list of completion must be greater than 2.
""" """
@@ -66,8 +67,14 @@ def test_pyc(pyc_project_path, environment):
# we also have the same version and it's easier to debug. # we also have the same version and it's easier to debug.
environment = SameEnvironment() environment = SameEnvironment()
environment = environment environment = environment
project = jedi.Project(pyc_project_path, load_unsafe_extensions=load_unsafe_extensions)
s = jedi.Script( s = jedi.Script(
"from dummy_package import dummy; dummy.", "from dummy_package import dummy; dummy.",
path=path, path=path,
environment=environment) environment=environment,
assert len(s.complete()) >= 2 project=project,
)
if load_unsafe_extensions:
assert len(s.complete()) >= 2
else:
assert not s.complete()
+1 -2
View File
@@ -6,7 +6,7 @@ should.
import time import time
import functools import functools
from .helpers import cwd_at, get_example_dir from .helpers import get_example_dir
import jedi import jedi
@@ -44,7 +44,6 @@ def test_scipy_speed(Script):
@_check_speed(0.8) @_check_speed(0.8)
@cwd_at('test')
def test_precedence_slowdown(Script): def test_precedence_slowdown(Script):
""" """
Precedence calculation can slow down things significantly in edge Precedence calculation can slow down things significantly in edge
+2 -3
View File
@@ -5,7 +5,7 @@ except ImportError:
from jedi import utils from jedi import utils
from .helpers import unittest, cwd_at from .helpers import unittest
@unittest.skipIf(not readline, "readline not found") @unittest.skipIf(not readline, "readline not found")
@@ -86,9 +86,8 @@ class TestSetupReadline(unittest.TestCase):
# (posix and nt) librariesare included. # (posix and nt) librariesare included.
assert len(difference) < 20 assert len(difference) < 20
@cwd_at('test')
def test_local_import(self): def test_local_import(self):
s = 'import test_utils' s = 'import test.test_utils'
assert self.complete(s) == [s] assert self.complete(s) == [s]
def test_preexisting_values(self): def test_preexisting_values(self):