forked from VimPlug/jedi
Make it possible to search folders __init__ files
This commit is contained in:
@@ -10,9 +10,10 @@ from jedi.api.exceptions import WrongVersion
|
|||||||
from jedi.api.completion import search_in_module
|
from jedi.api.completion import search_in_module
|
||||||
from jedi.api.helpers import split_search_string, get_module_names
|
from jedi.api.helpers import split_search_string, get_module_names
|
||||||
from jedi._compatibility import force_unicode
|
from jedi._compatibility import force_unicode
|
||||||
|
from jedi.inference.imports import load_module_from_path
|
||||||
from jedi.inference.sys_path import discover_buildout_paths
|
from jedi.inference.sys_path import discover_buildout_paths
|
||||||
from jedi.inference.cache import inference_state_as_method_param_cache
|
from jedi.inference.cache import inference_state_as_method_param_cache
|
||||||
from jedi.inference.references import recurse_find_python_files, search_in_file_ios
|
from jedi.inference.references import recurse_find_python_folders_and_files, search_in_file_ios
|
||||||
from jedi.inference import InferenceState
|
from jedi.inference import InferenceState
|
||||||
from jedi.file_io import FolderIO
|
from jedi.file_io import FolderIO
|
||||||
from jedi.common.utils import traverse_parents
|
from jedi.common.utils import traverse_parents
|
||||||
@@ -184,8 +185,43 @@ class Project(object):
|
|||||||
wanted_type, wanted_names = split_search_string(string)
|
wanted_type, wanted_names = split_search_string(string)
|
||||||
name = wanted_names[0]
|
name = wanted_names[0]
|
||||||
|
|
||||||
file_io_iterator = recurse_find_python_files(FolderIO(self._path))
|
ios = recurse_find_python_folders_and_files(FolderIO(self._path))
|
||||||
for module_context in search_in_file_ios(inference_state, file_io_iterator, name):
|
file_ios = []
|
||||||
|
|
||||||
|
for folder_io, file_io in ios:
|
||||||
|
if file_io is None:
|
||||||
|
file_name = folder_io.get_base_name()
|
||||||
|
if file_name == name:
|
||||||
|
f = folder_io.get_file_io('__init__.py')
|
||||||
|
try:
|
||||||
|
m = load_module_from_path(inference_state, f).as_context()
|
||||||
|
except FileNotFoundError:
|
||||||
|
f = folder_io.get_file_io('__init__.py')
|
||||||
|
try:
|
||||||
|
m = load_module_from_path(inference_state, f).as_context()
|
||||||
|
except FileNotFoundError:
|
||||||
|
m = namespace
|
||||||
|
else:
|
||||||
|
continue
|
||||||
|
else:
|
||||||
|
file_ios.append(file_io)
|
||||||
|
file_name = os.path.basename(file_io.path)
|
||||||
|
if file_name in (name + '.py', name + 'pyi'):
|
||||||
|
m = load_module_from_path(inference_state, file_io).as_context()
|
||||||
|
else:
|
||||||
|
continue
|
||||||
|
|
||||||
|
for x in search_in_module(
|
||||||
|
inference_state,
|
||||||
|
m,
|
||||||
|
names=[m.name],
|
||||||
|
wanted_type=wanted_type,
|
||||||
|
wanted_names=wanted_names,
|
||||||
|
complete=complete
|
||||||
|
):
|
||||||
|
yield x # Python 2...
|
||||||
|
|
||||||
|
for module_context in search_in_file_ios(inference_state, file_ios, name):
|
||||||
names = get_module_names(module_context.tree_node, all_scopes=all_scopes)
|
names = get_module_names(module_context.tree_node, all_scopes=all_scopes)
|
||||||
for x in search_in_module(
|
for x in search_in_module(
|
||||||
inference_state,
|
inference_state,
|
||||||
|
|||||||
@@ -7,6 +7,9 @@ class AbstractFolderIO(object):
|
|||||||
def __init__(self, path):
|
def __init__(self, path):
|
||||||
self.path = path
|
self.path = path
|
||||||
|
|
||||||
|
def get_base_name(self):
|
||||||
|
raise NotImplementedError
|
||||||
|
|
||||||
def list(self):
|
def list(self):
|
||||||
raise NotImplementedError
|
raise NotImplementedError
|
||||||
|
|
||||||
|
|||||||
@@ -193,14 +193,15 @@ def gitignored_lines(folder_io, file_io):
|
|||||||
return ignored_paths, ignored_names
|
return ignored_paths, ignored_names
|
||||||
|
|
||||||
|
|
||||||
def recurse_find_python_files(folder_io, except_paths=()):
|
def recurse_find_python_folders_and_files(folder_io, except_paths=()):
|
||||||
|
except_paths = set(except_paths)
|
||||||
for root_folder_io, folder_ios, file_ios in folder_io.walk():
|
for root_folder_io, folder_ios, file_ios in folder_io.walk():
|
||||||
# Delete folders that we don't want to iterate over.
|
# Delete folders that we don't want to iterate over.
|
||||||
for file_io in file_ios:
|
for file_io in file_ios:
|
||||||
path = file_io.path
|
path = file_io.path
|
||||||
if path.endswith('.py') or path.endswith('.pyi'):
|
if path.endswith('.py') or path.endswith('.pyi'):
|
||||||
if path not in except_paths:
|
if path not in except_paths:
|
||||||
yield file_io
|
yield None, file_io
|
||||||
|
|
||||||
if path.endswith('.gitignore'):
|
if path.endswith('.gitignore'):
|
||||||
ignored_paths, ignored_names = \
|
ignored_paths, ignored_names = \
|
||||||
@@ -213,6 +214,14 @@ def recurse_find_python_files(folder_io, except_paths=()):
|
|||||||
if folder_io.path not in except_paths
|
if folder_io.path not in except_paths
|
||||||
and folder_io.get_base_name() not in _IGNORE_FOLDERS
|
and folder_io.get_base_name() not in _IGNORE_FOLDERS
|
||||||
]
|
]
|
||||||
|
for folder_io in folder_ios:
|
||||||
|
yield folder_io, None
|
||||||
|
|
||||||
|
|
||||||
|
def recurse_find_python_files(folder_io, except_paths=()):
|
||||||
|
for folder_io, file_io in recurse_find_python_folders_and_files(folder_io, except_paths):
|
||||||
|
if file_io is not None:
|
||||||
|
yield file_io
|
||||||
|
|
||||||
|
|
||||||
def _find_python_files_in_sys_path(inference_state, module_contexts):
|
def _find_python_files_in_sys_path(inference_state, module_contexts):
|
||||||
|
|||||||
@@ -46,7 +46,7 @@ def test_load_save_project(tmpdir):
|
|||||||
@pytest.mark.parametrize(
|
@pytest.mark.parametrize(
|
||||||
'string, full_names, kwargs', [
|
'string, full_names, kwargs', [
|
||||||
('test_load_save_project', ['test_api.test_project.test_load_save_project'], {}),
|
('test_load_save_project', ['test_api.test_project.test_load_save_project'], {}),
|
||||||
('test_load_savep', [], {'complete': True}),
|
('test_load_savep', [], dict(complete=True)),
|
||||||
('test_load_save_p', ['test_api.test_project.test_load_save_project'],
|
('test_load_save_p', ['test_api.test_project.test_load_save_project'],
|
||||||
dict(complete=True)),
|
dict(complete=True)),
|
||||||
('test_load_save_p', ['test_api.test_project.test_load_save_project'],
|
('test_load_save_p', ['test_api.test_project.test_load_save_project'],
|
||||||
@@ -66,6 +66,13 @@ def test_load_save_project(tmpdir):
|
|||||||
('foo sample_int.real', [], {}),
|
('foo sample_int.real', [], {}),
|
||||||
('def sample_int.real', ['builtins.int.real'], {}),
|
('def sample_int.real', ['builtins.int.real'], {}),
|
||||||
('function sample_int.real', ['builtins.int.real'], {}),
|
('function sample_int.real', ['builtins.int.real'], {}),
|
||||||
|
|
||||||
|
# With modules
|
||||||
|
('test_project.test_search', ['test_api.test_project.test_search'], {}),
|
||||||
|
('test_project.test_searc', ['test_api.test_project.test_search'], dict(complete=True)),
|
||||||
|
('test_api.test_project.test_search', ['test_api.test_project.test_search'], {}),
|
||||||
|
('test_api.test_project.test_sear', ['test_api.test_project.test_search'],
|
||||||
|
dict(complete=True)),
|
||||||
]
|
]
|
||||||
)
|
)
|
||||||
@pytest.mark.skipif(sys.version_info < (3, 6), reason="Ignore Python 2, because EOL")
|
@pytest.mark.skipif(sys.version_info < (3, 6), reason="Ignore Python 2, because EOL")
|
||||||
|
|||||||
Reference in New Issue
Block a user