diff --git a/jedi/inference/references.py b/jedi/inference/references.py index d14307b5..df47dabb 100644 --- a/jedi/inference/references.py +++ b/jedi/inference/references.py @@ -4,7 +4,7 @@ import re from parso import python_bytes_to_unicode from jedi.debug import dbg -from jedi.file_io import KnownContentFileIO +from jedi.file_io import KnownContentFileIO, FolderIO from jedi.inference.names import SubModuleName from jedi.inference.imports import load_module_from_path from jedi.inference.filters import ParserTreeFilter @@ -127,10 +127,10 @@ def find_references(module_context, tree_name, only_in_module=False): module_contexts = [module_context] if not only_in_module: - module_contexts.extend( - m for m in set(d.get_root_context() for d in found_names) - if m != module_context and m.tree_node is not None - ) + for m in set(d.get_root_context() for d in found_names): + if m != module_context and m.tree_node is not None \ + and inf.project.path in m.py__file__().parents: + module_contexts.append(m) # For param no search for other modules is necessary. if only_in_module or any(n.api_type == 'param' for n in found_names): potential_modules = module_contexts @@ -250,6 +250,11 @@ def _find_python_files_in_sys_path(inference_state, module_contexts): folder_io = folder_io.get_parent_folder() +def _find_project_modules(inference_state, module_contexts): + except_ = [m.py__file__() for m in module_contexts] + yield from recurse_find_python_files(FolderIO(inference_state.project.path), except_) + + def get_module_contexts_containing_name(inference_state, module_contexts, name, limit_reduction=1): """ @@ -269,7 +274,10 @@ def get_module_contexts_containing_name(inference_state, module_contexts, name, if len(name) <= 2: return - file_io_iterator = _find_python_files_in_sys_path(inference_state, module_contexts) + # Currently not used, because there's only `scope=project` and `scope=file` + # At the moment there is no such thing as `scope=sys.path`. + # file_io_iterator = _find_python_files_in_sys_path(inference_state, module_contexts) + file_io_iterator = _find_project_modules(inference_state, module_contexts) yield from search_in_file_ios(inference_state, file_io_iterator, name, limit_reduction=limit_reduction) diff --git a/test/completion/imports.py b/test/completion/imports.py index 150f2743..bd1bf75b 100644 --- a/test/completion/imports.py +++ b/test/completion/imports.py @@ -202,6 +202,10 @@ from keyword import not_existing1, not_existing2 from tokenize import io tokenize.generate_tokens +import socket +#? 14 ['SocketIO'] +socket.SocketIO + # ----------------- # builtins # ----------------- diff --git a/test/completion/usages.py b/test/completion/usages.py index d708297e..8afffb40 100644 --- a/test/completion/usages.py +++ b/test/completion/usages.py @@ -383,3 +383,12 @@ usage_definition = 1 if False: #< 8 (-3, 0), (0, 4), ('import_tree.references', 1, 21), ('import_tree.references', 5, 4) usage_definition() + +# ----------------- +# stdlib stuff +# ----------------- + +import socket +#< (1, 21), (0, 7), ('socket', ..., 6), ('stub:socket', ..., 4), ('imports', ..., 7) +socket.SocketIO +some_socket = socket.SocketIO() diff --git a/test/run.py b/test/run.py index 92e21d61..e9c8ab09 100755 --- a/test/run.py +++ b/test/run.py @@ -107,6 +107,7 @@ import operator from ast import literal_eval from io import StringIO from functools import reduce +from unittest.mock import ANY import parso from _pytest.outcomes import Skipped @@ -275,6 +276,8 @@ class IntegrationTestCase(BaseTestCase): for pos_tup in positions: if type(pos_tup[0]) == str: # this means that there is a module specified + if pos_tup[1] == ...: + pos_tup = pos_tup[0], ANY, pos_tup[2] wanted.append(pos_tup) else: line = pos_tup[0]