diff --git a/jedi/api/__init__.py b/jedi/api/__init__.py index bfb2951b..3f598851 100644 --- a/jedi/api/__init__.py +++ b/jedi/api/__init__.py @@ -37,7 +37,7 @@ from jedi.inference import InferenceState from jedi.inference import imports from jedi.inference.references import find_references from jedi.inference.arguments import try_iter_content -from jedi.inference.helpers import get_module_names, infer_call_of_leaf +from jedi.inference.helpers import infer_call_of_leaf from jedi.inference.sys_path import transform_path_to_dotted from jedi.inference.syntax_tree import tree_name_to_values from jedi.inference.value import ModuleValue @@ -554,7 +554,7 @@ class Script(object): module_context = self._get_module_context() defs = [ module_context.create_name(name) - for name in get_module_names( + for name in helpers.get_module_names( self._module_node, all_scopes=all_scopes, definitions=definitions, diff --git a/jedi/api/helpers.py b/jedi/api/helpers.py index 07dcab8a..f06ab694 100644 --- a/jedi/api/helpers.py +++ b/jedi/api/helpers.py @@ -4,6 +4,7 @@ Helpers for the API import re from collections import namedtuple from textwrap import dedent +from itertools import chain from functools import wraps from parso.python.parser import Parser @@ -15,6 +16,7 @@ from jedi.inference.syntax_tree import infer_atom from jedi.inference.helpers import infer_call_of_leaf from jedi.inference.compiled import get_string_value_set from jedi.cache import signature_time_cache +from jedi.parser_utils import get_parent_scope CompletionParts = namedtuple('CompletionParts', ['path', 'has_dot', 'name']) @@ -464,6 +466,33 @@ def validate_line_column(func): return wrapper +def get_module_names(module, all_scopes, definitions=True, references=False): + """ + Returns a dictionary with name parts as keys and their call paths as + values. + """ + def def_ref_filter(name): + is_def = name.is_definition() + return definitions and is_def or references and not is_def + + names = list(chain.from_iterable(module.get_used_names().values())) + if not all_scopes: + # We have to filter all the names that don't have the module as a + # parent_scope. There's None as a parent, because nodes in the module + # node have the parent module and not suite as all the others. + # Therefore it's important to catch that case. + + def is_module_scope_name(name): + parent_scope = get_parent_scope(name) + # async functions have an extra wrapper. Strip it. + if parent_scope and parent_scope.type == 'async_stmt': + parent_scope = parent_scope.parent + return parent_scope in (module, None) + + names = [n for n in names if is_module_scope_name(n)] + return filter(def_ref_filter, names) + + def split_search_string(name): type, _, dotted_names = name.rpartition(' ') if type == 'def': diff --git a/jedi/api/project.py b/jedi/api/project.py index 7d4d841d..e3d45879 100644 --- a/jedi/api/project.py +++ b/jedi/api/project.py @@ -8,12 +8,11 @@ from jedi._compatibility import scandir from jedi.api.environment import get_cached_default_environment, create_environment from jedi.api.exceptions import WrongVersion from jedi.api.completion import search_in_module -from jedi.api.helpers import split_search_string +from jedi.api.helpers import split_search_string, get_module_names from jedi._compatibility import force_unicode from jedi.inference.sys_path import discover_buildout_paths 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.helpers import get_module_names from jedi.inference import InferenceState from jedi.file_io import FolderIO from jedi.common.utils import traverse_parents diff --git a/jedi/inference/helpers.py b/jedi/inference/helpers.py index 1e1f6914..3e4d3952 100644 --- a/jedi/inference/helpers.py +++ b/jedi/inference/helpers.py @@ -8,7 +8,6 @@ from contextlib import contextmanager from parso.python import tree from jedi._compatibility import unicode -from jedi.parser_utils import get_parent_scope def is_stdlib_path(path): @@ -122,33 +121,6 @@ def get_names_of_node(node): return list(chain.from_iterable(get_names_of_node(c) for c in children)) -def get_module_names(module, all_scopes, definitions=True, references=False): - """ - Returns a dictionary with name parts as keys and their call paths as - values. - """ - def def_ref_filter(name): - is_def = name.is_definition() - return definitions and is_def or references and not is_def - - names = list(chain.from_iterable(module.get_used_names().values())) - if not all_scopes: - # We have to filter all the names that don't have the module as a - # parent_scope. There's None as a parent, because nodes in the module - # node have the parent module and not suite as all the others. - # Therefore it's important to catch that case. - - def is_module_scope_name(name): - parent_scope = get_parent_scope(name) - # async functions have an extra wrapper. Strip it. - if parent_scope and parent_scope.type == 'async_stmt': - parent_scope = parent_scope.parent - return parent_scope in (module, None) - - names = [n for n in names if is_module_scope_name(n)] - return filter(def_ref_filter, names) - - def is_string(value): if value.inference_state.environment.version_info.major == 2: str_classes = (unicode, bytes)