diff --git a/jedi/inference/base_value.py b/jedi/inference/base_value.py index 084fe4ab..8e14ddca 100644 --- a/jedi/inference/base_value.py +++ b/jedi/inference/base_value.py @@ -76,8 +76,8 @@ class HelperValueMixin(object): """ if name_context is None: name_context = self - names, f = self._goto(name_or_str, name_context, analysis_errors) - values = f.find(names, attribute_lookup=True) + names = self.goto(name_or_str, name_context, analysis_errors) + values = ValueSet.from_sets(name.infer() for name in names) if not values: n = name_or_str.value if isinstance(name_or_str, Name) else name_or_str values = self.py__getattribute__alternatives(n) @@ -87,21 +87,17 @@ class HelperValueMixin(object): from jedi.inference import analysis analysis.add_attribute_error( name_context, self, name_or_str) + debug.dbg('context.names_to_types: %s -> %s', names, values) return values - def goto(self, *args, **kwargs): - return self._goto(*args, **kwargs)[0] - - def _goto(self, name_or_str, name_context=None, analysis_errors=True): + def goto(self, name_or_str, name_context=None, analysis_errors=True): if name_context is None: name_context = self from jedi.inference import finder - f = finder.NameFinder(self, name_context, name_or_str, - analysis_errors=analysis_errors) filters = self._get_value_filters(name_or_str) - names = f.filter_name(filters) + names = finder.filter_name(filters, name_or_str) debug.dbg('Context.goto %s in (%s): %s', name_or_str, self, names) - return names, f + return names def py__await__(self): await_value_set = self.py__getattribute__(u"__await__") diff --git a/jedi/inference/context.py b/jedi/inference/context.py index 723daec8..7cdc7926 100644 --- a/jedi/inference/context.py +++ b/jedi/inference/context.py @@ -6,7 +6,7 @@ from parso.python.tree import Name from jedi.inference.filters import ParserTreeFilter, MergedFilter, \ GlobalNameFilter -from jedi.inference.base_value import NO_VALUES +from jedi.inference.base_value import NO_VALUES, ValueSet from jedi.parser_utils import get_parent_scope from jedi import debug from jedi import parser_utils @@ -24,17 +24,13 @@ class AbstractContext(object): raise NotImplementedError def goto(self, name_or_str, position): - return self._goto(name_or_str, position)[0] - - def _goto(self, name_or_str, position): from jedi.inference import finder - f = finder.NameFinder(self, self, name_or_str, position) filters = _get_global_filters_for_name( self, name_or_str if isinstance(name_or_str, Name) else None, position, ) - names = f.filter_name(filters) + names = finder.filter_name(filters, name_or_str) debug.dbg('Context.goto %s in (%s): %s', name_or_str, self, names) - return names, f + return names def py__getattribute__(self, name_or_str, name_context=None, position=None, analysis_errors=True): @@ -43,7 +39,7 @@ class AbstractContext(object): """ if name_context is None: name_context = self - names, f = self._goto(name_or_str, position) + names = self.goto(name_or_str, position) string_name = name_or_str.value if isinstance(name_or_str, Name) else name_or_str @@ -75,12 +71,15 @@ class AbstractContext(object): else: values = found_predefined_types else: - values = f.find(names, attribute_lookup=False) + values = ValueSet.from_sets(name.infer() for name in names) + if not names and not values and analysis_errors: if isinstance(name_or_str, Name): from jedi.inference import analysis message = ("NameError: name '%s' is not defined." % string_name) analysis.add(name_context, 'name-error', name_or_str, message) + + debug.dbg('context.names_to_types: %s -> %s', names, values) if values: return values return self._check_for_additional_knowledge(name_or_str, name_context, position) diff --git a/jedi/inference/finder.py b/jedi/inference/finder.py index 969ae02d..1bbaa528 100644 --- a/jedi/inference/finder.py +++ b/jedi/inference/finder.py @@ -15,52 +15,30 @@ Unfortunately every other thing is being ignored (e.g. a == '' would be easy to check for -> a is a string). There's big potential in these checks. """ -from parso.python import tree from parso.tree import search_ancestor -from jedi import debug +from parso.python.tree import Name + from jedi import settings from jedi.inference.arguments import TreeArguments from jedi.inference import helpers from jedi.inference.value import iterable -from jedi.inference.base_value import ValueSet, NO_VALUES +from jedi.inference.base_value import NO_VALUES from jedi.parser_utils import is_scope -class NameFinder(object): - def __init__(self, context, name_context, name_or_str, - position=None, analysis_errors=True): - # Make sure that it's not just a syntax tree node. - self._context = context - self._name_context = name_context - self._name = name_or_str - if isinstance(name_or_str, tree.Name): - self._string_name = name_or_str.value - else: - self._string_name = name_or_str - self._position = position - self._analysis_errors = analysis_errors +def filter_name(filters, name_or_str): + """ + Searches names that are defined in a scope (the different + ``filters``), until a name fits. + """ + string_name = name_or_str.value if isinstance(name_or_str, Name) else name_or_str + names = [] + for filter in filters: + names = filter.get(string_name) + if names: + break - def find(self, names, attribute_lookup): - """ - :params bool attribute_lookup: Tell to logic if we're accessing the - attribute or the contents of e.g. a function. - """ - values = ValueSet.from_sets(name.infer() for name in names) - debug.dbg('finder._names_to_types: %s -> %s', names, values) - return values - - def filter_name(self, filters): - """ - Searches names that are defined in a scope (the different - ``filters``), until a name fits. - """ - names = [] - for filter in filters: - names = filter.get(self._string_name) - if names: - break - - return list(names) + return list(names) def check_flow_information(value, flow, search_name, pos): diff --git a/jedi/inference/syntax_tree.py b/jedi/inference/syntax_tree.py index 2580083e..d2b0d0a0 100644 --- a/jedi/inference/syntax_tree.py +++ b/jedi/inference/syntax_tree.py @@ -19,7 +19,7 @@ from jedi.inference import arguments from jedi.inference.value import ClassValue, FunctionValue from jedi.inference.value import iterable from jedi.inference.value import TreeInstance -from jedi.inference.finder import NameFinder +from jedi.inference.finder import filter_name from jedi.inference.helpers import is_string, is_literal, is_number from jedi.inference.compiled.access import COMPARISON_OPERATORS from jedi.inference.cache import inference_state_method_cache @@ -570,11 +570,11 @@ def tree_name_to_values(inference_state, context, tree_name): node = tree_name.parent if node.type == 'global_stmt': c = context.create_context(tree_name) - finder = NameFinder(c, c, tree_name.value) # For global_stmt lookups, we only need the first possible scope, # which means the function itself. filters = [next(c.get_filters())] - return finder.find(finder.filter_name(filters), attribute_lookup=False) + names = filter_name(filters, tree_name) + return ValueSet.from_sets(name.infer() for name in names) elif node.type not in ('import_from', 'import_name'): c = context.create_context(tree_name) return infer_atom(c, tree_name)