forked from VimPlug/jedi
Fix get_modules_containing_name
This commit is contained in:
@@ -143,7 +143,7 @@ class ModuleContext(ModuleMixin, TreeContext):
|
||||
tree_node=module_node
|
||||
)
|
||||
self._path = path
|
||||
self._string_names = string_names
|
||||
self.string_names = string_names
|
||||
self.code_lines = code_lines
|
||||
|
||||
def _get_init_directory(self):
|
||||
@@ -160,9 +160,9 @@ class ModuleContext(ModuleMixin, TreeContext):
|
||||
return None
|
||||
|
||||
def py__name__(self):
|
||||
if self._string_names is None:
|
||||
if self.string_names is None:
|
||||
return None
|
||||
return '.'.join(self._string_names)
|
||||
return '.'.join(self.string_names)
|
||||
|
||||
def py__file__(self):
|
||||
"""
|
||||
|
||||
@@ -497,18 +497,14 @@ def get_modules_containing_name(evaluator, modules, name):
|
||||
"""
|
||||
Search a name in the directories of modules.
|
||||
"""
|
||||
def check_directories(paths):
|
||||
for p in paths:
|
||||
if p is not None:
|
||||
# We need abspath, because the seetings paths might not already
|
||||
# have been converted to absolute paths.
|
||||
d = os.path.dirname(os.path.abspath(p))
|
||||
for file_name in os.listdir(d):
|
||||
path = os.path.join(d, file_name)
|
||||
if file_name.endswith('.py'):
|
||||
yield path
|
||||
def check_directory(path):
|
||||
d = os.path.dirname(os.path.abspath(path))
|
||||
for file_name in os.listdir(d):
|
||||
path = os.path.join(d, file_name)
|
||||
if file_name.endswith('.py'):
|
||||
yield path
|
||||
|
||||
def check_fs(path):
|
||||
def check_fs(path, base_names):
|
||||
try:
|
||||
f = open(path, 'rb')
|
||||
except FileNotFoundError:
|
||||
@@ -517,7 +513,15 @@ def get_modules_containing_name(evaluator, modules, name):
|
||||
code = python_bytes_to_unicode(f.read(), errors='replace')
|
||||
if name in code:
|
||||
e_sys_path = evaluator.get_sys_path()
|
||||
import_names = sys_path.calculate_dotted_path_from_sys_path(e_sys_path, path)
|
||||
module_name = os.path.basename(path)
|
||||
if module_name.endswith('.py'):
|
||||
module_name = module_name[:-3]
|
||||
|
||||
if base_names:
|
||||
import_names = base_names + (module_name,)
|
||||
else:
|
||||
import_names = sys_path.calculate_dotted_path_from_sys_path(e_sys_path, path)
|
||||
|
||||
module = _load_module(
|
||||
evaluator, path, code,
|
||||
sys_path=e_sys_path,
|
||||
@@ -528,26 +532,32 @@ def get_modules_containing_name(evaluator, modules, name):
|
||||
|
||||
# skip non python modules
|
||||
used_mod_paths = set()
|
||||
path_with_names_to_be_checked = []
|
||||
for m in modules:
|
||||
try:
|
||||
path = m.py__file__()
|
||||
except AttributeError:
|
||||
pass
|
||||
else:
|
||||
used_mod_paths.add(path)
|
||||
if path is not None:
|
||||
if path not in used_mod_paths:
|
||||
used_mod_paths.add(path)
|
||||
string_names = m.string_names
|
||||
if not m.is_package() and string_names is not None:
|
||||
string_names = string_names[:-1]
|
||||
path_with_names_to_be_checked.append((path, string_names))
|
||||
yield m
|
||||
|
||||
if not settings.dynamic_params_for_other_modules:
|
||||
return
|
||||
|
||||
additional = set(os.path.abspath(p) for p in settings.additional_dynamic_modules)
|
||||
# Check the directories of used modules.
|
||||
paths = (additional | set(check_directories(used_mod_paths))) \
|
||||
- used_mod_paths
|
||||
for p in settings.additional_dynamic_modules:
|
||||
p = os.path.abspath(p)
|
||||
if p not in used_mod_paths:
|
||||
path_with_names_to_be_checked.append((p, None))
|
||||
|
||||
# Sort here to make issues less random.
|
||||
for p in sorted(paths):
|
||||
# make testing easier, sort it - same results on every interpreter
|
||||
m = check_fs(p)
|
||||
if m is not None and not isinstance(m, compiled.CompiledObject):
|
||||
yield m
|
||||
for p, base_names in path_with_names_to_be_checked:
|
||||
for file_path in check_directory(p):
|
||||
m = check_fs(file_path, base_names)
|
||||
if m is not None and not isinstance(m, compiled.CompiledObject):
|
||||
yield m
|
||||
|
||||
@@ -9,6 +9,7 @@ import pytest
|
||||
|
||||
from jedi._compatibility import find_module_py33, find_module
|
||||
from jedi.evaluate import compiled
|
||||
from jedi.evaluate import imports
|
||||
from ..helpers import cwd_at
|
||||
|
||||
|
||||
@@ -251,3 +252,21 @@ def test_compiled_import_none(monkeypatch, Script):
|
||||
"""
|
||||
monkeypatch.setattr(compiled, 'load_module', lambda *args, **kwargs: None)
|
||||
assert not Script('import sys').goto_definitions()
|
||||
|
||||
|
||||
@pytest.mark.parametrize(
|
||||
('path', 'goal'), [
|
||||
('test_evaluate/test_docstring.py', ('ok', 'lala', 'test_imports')),
|
||||
('test_evaluate/__init__.py', ('ok', 'lala', 'x', 'test_imports')),
|
||||
]
|
||||
)
|
||||
def test_get_modules_containing_name(evaluator, path, goal):
|
||||
module = imports._load_module(evaluator, path, import_names=('ok', 'lala', 'x'))
|
||||
assert module
|
||||
input_module, found_module = imports.get_modules_containing_name(
|
||||
evaluator,
|
||||
[module],
|
||||
'string_that_only_exists_here'
|
||||
)
|
||||
assert input_module is module
|
||||
assert found_module.string_names == goal
|
||||
|
||||
Reference in New Issue
Block a user