mirror of
https://github.com/davidhalter/jedi.git
synced 2025-12-07 22:44:27 +08:00
Care better about stubs for code search
This commit is contained in:
@@ -20,7 +20,7 @@ from jedi.inference.helpers import infer_call_of_leaf, parse_dotted_names
|
|||||||
from jedi.inference.context import get_global_filters
|
from jedi.inference.context import get_global_filters
|
||||||
from jedi.inference.value import TreeInstance, ModuleValue
|
from jedi.inference.value import TreeInstance, ModuleValue
|
||||||
from jedi.inference.names import ParamNameWrapper
|
from jedi.inference.names import ParamNameWrapper
|
||||||
from jedi.inference.gradual.conversion import convert_values
|
from jedi.inference.gradual.conversion import convert_values, convert_names
|
||||||
from jedi.parser_utils import cut_value_at_position
|
from jedi.parser_utils import cut_value_at_position
|
||||||
from jedi.plugins import plugin_manager
|
from jedi.plugins import plugin_manager
|
||||||
|
|
||||||
@@ -577,7 +577,7 @@ def _complete_getattr(user_context, instance):
|
|||||||
|
|
||||||
def search_in_module(inference_state, module_context, names, wanted_names,
|
def search_in_module(inference_state, module_context, names, wanted_names,
|
||||||
wanted_type, complete=False, fuzzy=False,
|
wanted_type, complete=False, fuzzy=False,
|
||||||
ignore_imports=False):
|
ignore_imports=False, convert=False):
|
||||||
for s in wanted_names[:-1]:
|
for s in wanted_names[:-1]:
|
||||||
new_names = []
|
new_names = []
|
||||||
for n in names:
|
for n in names:
|
||||||
@@ -597,6 +597,10 @@ def search_in_module(inference_state, module_context, names, wanted_names,
|
|||||||
string = n.string_name.lower()
|
string = n.string_name.lower()
|
||||||
if complete and helpers.match(string, last_name, fuzzy=fuzzy) \
|
if complete and helpers.match(string, last_name, fuzzy=fuzzy) \
|
||||||
or not complete and string == last_name:
|
or not complete and string == last_name:
|
||||||
def_ = classes.Definition(inference_state, n)
|
names = [n]
|
||||||
if not wanted_type or wanted_type == def_.type:
|
if convert:
|
||||||
yield def_
|
names = convert_names(names)
|
||||||
|
for n2 in names:
|
||||||
|
def_ = classes.Definition(inference_state, n2)
|
||||||
|
if not wanted_type or wanted_type == def_.type:
|
||||||
|
yield def_
|
||||||
|
|||||||
@@ -188,9 +188,10 @@ class Project(object):
|
|||||||
raise NotImplementedError(
|
raise NotImplementedError(
|
||||||
"No support for refactorings/search on Python 2/3.5"
|
"No support for refactorings/search on Python 2/3.5"
|
||||||
)
|
)
|
||||||
debug.dbg('Search for string %s', string)
|
debug.dbg('Search for string %s, complete=%s', string, complete)
|
||||||
wanted_type, wanted_names = split_search_string(string)
|
wanted_type, wanted_names = split_search_string(string)
|
||||||
name = wanted_names[0]
|
name = wanted_names[0]
|
||||||
|
stub_folder_name = name + '-stubs'
|
||||||
|
|
||||||
ios = recurse_find_python_folders_and_files(FolderIO(self._path))
|
ios = recurse_find_python_folders_and_files(FolderIO(self._path))
|
||||||
file_ios = []
|
file_ios = []
|
||||||
@@ -199,7 +200,7 @@ class Project(object):
|
|||||||
for folder_io, file_io in ios:
|
for folder_io, file_io in ios:
|
||||||
if file_io is None:
|
if file_io is None:
|
||||||
file_name = folder_io.get_base_name()
|
file_name = folder_io.get_base_name()
|
||||||
if file_name == name:
|
if file_name == name or file_name == stub_folder_name:
|
||||||
f = folder_io.get_file_io('__init__.py')
|
f = folder_io.get_file_io('__init__.py')
|
||||||
try:
|
try:
|
||||||
m = load_module_from_path(inference_state, f).as_context()
|
m = load_module_from_path(inference_state, f).as_context()
|
||||||
@@ -226,7 +227,8 @@ class Project(object):
|
|||||||
names=[m.name],
|
names=[m.name],
|
||||||
wanted_type=wanted_type,
|
wanted_type=wanted_type,
|
||||||
wanted_names=wanted_names,
|
wanted_names=wanted_names,
|
||||||
complete=complete
|
complete=complete,
|
||||||
|
convert=True,
|
||||||
):
|
):
|
||||||
yield x # Python 2...
|
yield x # Python 2...
|
||||||
|
|
||||||
@@ -259,6 +261,7 @@ class Project(object):
|
|||||||
wanted_type=wanted_type,
|
wanted_type=wanted_type,
|
||||||
wanted_names=wanted_names,
|
wanted_names=wanted_names,
|
||||||
complete=complete,
|
complete=complete,
|
||||||
|
convert=True,
|
||||||
):
|
):
|
||||||
yield x # Python 2...
|
yield x # Python 2...
|
||||||
|
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
import os
|
import os
|
||||||
|
import re
|
||||||
|
|
||||||
from jedi._compatibility import unicode, force_unicode, all_suffixes
|
from jedi._compatibility import unicode, force_unicode, all_suffixes
|
||||||
from jedi.inference.cache import inference_state_method_cache
|
from jedi.inference.cache import inference_state_method_cache
|
||||||
@@ -254,7 +255,9 @@ def transform_path_to_dotted(sys_path, module_path):
|
|||||||
# is very strange and is probably a file that is called
|
# is very strange and is probably a file that is called
|
||||||
# `.py`.
|
# `.py`.
|
||||||
return
|
return
|
||||||
yield tuple(split)
|
# Stub folders for foo can end with foo-stubs. Just remove
|
||||||
|
# it.
|
||||||
|
yield tuple(re.sub(r'-stubs$', '', s) for s in split)
|
||||||
|
|
||||||
potential_solutions = tuple(iter_potential_solutions())
|
potential_solutions = tuple(iter_potential_solutions())
|
||||||
if not potential_solutions:
|
if not potential_solutions:
|
||||||
|
|||||||
@@ -93,17 +93,19 @@ def test_load_save_project(tmpdir):
|
|||||||
('with_python.module', ['examples.stub_packages.with_python.module'], {}),
|
('with_python.module', ['examples.stub_packages.with_python.module'], {}),
|
||||||
('with_python.modul', ['examples.stub_packages.with_python.module'],
|
('with_python.modul', ['examples.stub_packages.with_python.module'],
|
||||||
dict(complete=True)),
|
dict(complete=True)),
|
||||||
('no_python.module', ['stub:examples.stub_packages.no_python.module'], {}),
|
('no_python.foo', ['stub:examples.stub_packages.no_python.foo'], {}),
|
||||||
('no_python.modul', ['stub:examples.stub_packages.no_python.module'],
|
('no_python.fo', ['stub:examples.stub_packages.no_python.foo'],
|
||||||
dict(complete=True)),
|
dict(complete=True)),
|
||||||
('with_python-stubs.module', ['stub:examples.stub_packages.with_python-stubs.module'], {}),
|
('with_python-stubs.module', [], {}),
|
||||||
('no_python-stubs.module', ['stub:examples.stub_packages.no_python-stubs.module'], {}),
|
('no_python-stubs.foo', [], {}),
|
||||||
|
('with_python', ['stub:examples.stub_packages.with_python', 'examples.stub_packages.with_python'], {}),
|
||||||
|
('no_python', ['stub:examples.stub_packages.no_python'], {}),
|
||||||
|
|
||||||
# On sys path
|
# On sys path
|
||||||
('sys.path', ['stub:sys.path'], {}),
|
('sys.path', ['stub:sys.path'], {}),
|
||||||
('json.dumps', ['stub:json.dumps', 'json.dumps'], {}), # stdlib + stub
|
('json.dumps', ['json.dumps'], {}), # stdlib + stub
|
||||||
('multiprocessing', ['stub:multiprocessing'], {}),
|
('multiprocessing', ['multiprocessing'], {}),
|
||||||
('multiprocessin', ['stub:multiprocessing'], dict(complete=True)),
|
('multiprocessin', ['multiprocessing'], 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