Fix calculate_dotted_path_from_sys_path. It was broken beyond stupid.

This commit is contained in:
Dave Halter
2018-12-18 09:30:49 +01:00
parent 881ffadb5c
commit fcda62862c
5 changed files with 38 additions and 11 deletions

View File

@@ -32,7 +32,7 @@ from jedi.evaluate import imports
from jedi.evaluate import usages from jedi.evaluate import usages
from jedi.evaluate.arguments import try_iter_content from jedi.evaluate.arguments import try_iter_content
from jedi.evaluate.helpers import get_module_names, evaluate_call_of_leaf from jedi.evaluate.helpers import get_module_names, evaluate_call_of_leaf
from jedi.evaluate.sys_path import dotted_path_in_sys_path from jedi.evaluate.sys_path import calculate_dotted_path_from_sys_path
from jedi.evaluate.filters import TreeNameDefinition, ParamName from jedi.evaluate.filters import TreeNameDefinition, ParamName
from jedi.evaluate.syntax_tree import tree_name_to_contexts from jedi.evaluate.syntax_tree import tree_name_to_contexts
from jedi.evaluate.context import ModuleContext from jedi.evaluate.context import ModuleContext
@@ -149,7 +149,10 @@ class Script(object):
def _get_module(self): def _get_module(self):
names = ('__main__',) names = ('__main__',)
if self.path is not None: if self.path is not None:
import_names = dotted_path_in_sys_path(self._evaluator.get_sys_path(), self.path) import_names = calculate_dotted_path_from_sys_path(
self._evaluator.get_sys_path(),
self.path
)
if import_names is not None: if import_names is not None:
names = import_names names = import_names

View File

@@ -145,7 +145,6 @@ class ModuleContext(ModuleMixin, TreeContext):
self._path = path self._path = path
self._string_names = string_names self._string_names = string_names
self.code_lines = code_lines self.code_lines = code_lines
#print(self._path)
def _get_init_directory(self): def _get_init_directory(self):
""" """

View File

@@ -517,7 +517,7 @@ def get_modules_containing_name(evaluator, modules, name):
code = python_bytes_to_unicode(f.read(), errors='replace') code = python_bytes_to_unicode(f.read(), errors='replace')
if name in code: if name in code:
e_sys_path = evaluator.get_sys_path() e_sys_path = evaluator.get_sys_path()
import_names = sys_path.dotted_path_in_sys_path(e_sys_path, path) import_names = sys_path.calculate_dotted_path_from_sys_path(e_sys_path, path)
module = _load_module( module = _load_module(
evaluator, path, code, evaluator, path, code,
sys_path=e_sys_path, sys_path=e_sys_path,

View File

@@ -197,9 +197,12 @@ def _get_buildout_script_paths(search_path):
continue continue
def dotted_path_in_sys_path(sys_path, module_path): def calculate_dotted_path_from_sys_path(sys_path, module_path):
""" """
Returns the dotted path inside a sys.path as a list of names. Returns the dotted path inside a sys.path as a list of names.
This function is supposed to be a backup plan in case there's no idea where
a file is lying.
""" """
# First remove the suffix. # First remove the suffix.
for suffix in all_suffixes(): for suffix in all_suffixes():
@@ -210,18 +213,22 @@ def dotted_path_in_sys_path(sys_path, module_path):
# There should always be a suffix in a valid Python file on the path. # There should always be a suffix in a valid Python file on the path.
return None return None
if module_path.startswith(os.path.sep): if module_path.endswith('__init__'):
# The paths in sys.path most of the times don't end with a slash. module_path = module_path[:-len('__init__') - 1]
module_path = module_path[1:]
if module_path.endswith(os.path.sep):
# The paths in sys.path may end with a slash.
module_path = module_path[:-1]
for p in sys_path: for p in sys_path:
if module_path.startswith(p): if module_path.startswith(p):
rest = module_path[len(p):] rest = module_path[len(p):]
if rest.startswith(os.path.sep) or rest.startswith('/'):
rest = rest[1:]
if rest: if rest:
split = rest.split(os.path.sep) split = rest.split(os.path.sep)
for string in split: for string in split:
if not string or '.' in string: if not string or '.' in string:
return None return None
return split return tuple(split)
return None return None

View File

@@ -3,6 +3,8 @@ from glob import glob
import sys import sys
import shutil import shutil
import pytest
from jedi.evaluate import sys_path from jedi.evaluate import sys_path
from jedi.api.environment import create_environment from jedi.api.environment import create_environment
@@ -59,3 +61,19 @@ def test_venv_and_pths(venv_path):
# Ensure that none of venv dirs leaked to the interpreter. # Ensure that none of venv dirs leaked to the interpreter.
assert not set(sys.path).intersection(ETALON) assert not set(sys.path).intersection(ETALON)
@pytest.mark.parametrize(('sys_path_', 'path', 'expected'), [
(['/foo'], '/foo/bar.py', ('bar',)),
(['/foo'], '/foo/bar/baz.py', ('bar', 'baz')),
(['/foo'], '/foo/bar/__init__.py', ('bar',)),
(['/foo'], '/foo/bar/baz/__init__.py', ('bar', 'baz')),
(['/foo'], '/foo/bar.so', ('bar',)),
(['/foo'], '/foo/bar/__init__.so', ('bar',)),
(['/foo'], '/x/bar.py', None),
(['/foo'], '/foo/bar.xyz', None),
])
def test_calculate_dotted_path_from_sys_path(path, sys_path_, expected):
assert sys_path.calculate_dotted_path_from_sys_path(sys_path_, path) == expected