diff --git a/jedi/inference/__init__.py b/jedi/inference/__init__.py index 47c95648..e8b788d3 100644 --- a/jedi/inference/__init__.py +++ b/jedi/inference/__init__.py @@ -75,7 +75,7 @@ from jedi.inference import recursion from jedi.inference.cache import inference_state_function_cache from jedi.inference import helpers from jedi.inference.names import TreeNameDefinition -from jedi.inference.base_value import ContextualizedName, ContextualizedNode, \ +from jedi.inference.base_value import ContextualizedNode, \ ValueSet, NO_VALUES, iterate_values from jedi.inference.value import ClassValue, FunctionValue from jedi.inference.context import CompForContext @@ -256,8 +256,8 @@ class InferenceState(object): container_types = context.infer_node(def_.children[3]) cn = ContextualizedNode(context, def_.children[3]) for_types = iterate_values(container_types, cn) - c_node = ContextualizedName(context, name) - return check_tuple_assignments(c_node, for_types) + n = TreeNameDefinition(context, name) + return check_tuple_assignments(n, for_types) if type_ in ('import_from', 'import_name'): return imports.infer_import(context, name) else: diff --git a/jedi/inference/base_value.py b/jedi/inference/base_value.py index a1dbbe95..2395dcb5 100644 --- a/jedi/inference/base_value.py +++ b/jedi/inference/base_value.py @@ -329,54 +329,6 @@ class ContextualizedNode(object): return '<%s: %s in %s>' % (self.__class__.__name__, self.node, self.context) -class ContextualizedName(ContextualizedNode): - # TODO merge with TreeNameDefinition?! - @property - def name(self): - return self.node - - def assignment_indexes(self): - """ - Returns an array of tuple(int, node) of the indexes that are used in - tuple assignments. - - For example if the name is ``y`` in the following code:: - - x, (y, z) = 2, '' - - would result in ``[(1, xyz_node), (0, yz_node)]``. - - When searching for b in the case ``a, *b, c = [...]`` it will return:: - - [(slice(1, -1), abc_node)] - """ - indexes = [] - is_star_expr = False - node = self.node.parent - compare = self.node - while node is not None: - if node.type in ('testlist', 'testlist_comp', 'testlist_star_expr', 'exprlist'): - for i, child in enumerate(node.children): - if child == compare: - index = int(i / 2) - if is_star_expr: - from_end = int((len(node.children) - i) / 2) - index = slice(index, -from_end) - indexes.insert(0, (index, node)) - break - else: - raise LookupError("Couldn't find the assignment.") - is_star_expr = False - elif node.type == 'star_expr': - is_star_expr = True - elif isinstance(node, (ExprStmt, SyncCompFor)): - break - - compare = node - node = node.parent - return indexes - - def _getitem(value, index_values, contextualized_node): # The actual getitem call. result = NO_VALUES diff --git a/jedi/inference/names.py b/jedi/inference/names.py index eb4ad6b5..3c34e9f9 100644 --- a/jedi/inference/names.py +++ b/jedi/inference/names.py @@ -175,6 +175,46 @@ class TreeNameDefinition(AbstractTreeName): return 'statement' return self._API_TYPES.get(definition.type, 'statement') + def assignment_indexes(self): + """ + Returns an array of tuple(int, node) of the indexes that are used in + tuple assignments. + + For example if the name is ``y`` in the following code:: + + x, (y, z) = 2, '' + + would result in ``[(1, xyz_node), (0, yz_node)]``. + + When searching for b in the case ``a, *b, c = [...]`` it will return:: + + [(slice(1, -1), abc_node)] + """ + indexes = [] + is_star_expr = False + node = self.tree_name.parent + compare = self.tree_name + while node is not None: + if node.type in ('testlist', 'testlist_comp', 'testlist_star_expr', 'exprlist'): + for i, child in enumerate(node.children): + if child == compare: + index = int(i / 2) + if is_star_expr: + from_end = int((len(node.children) - i) / 2) + index = slice(index, -from_end) + indexes.insert(0, (index, node)) + break + else: + raise LookupError("Couldn't find the assignment.") + is_star_expr = False + elif node.type == 'star_expr': + is_star_expr = True + elif node.type in ('expr_stmt', 'sync_comp_for'): + break + + compare = node + node = node.parent + return indexes class _ParamMixin(object): def maybe_positional_argument(self, include_star=True): diff --git a/jedi/inference/syntax_tree.py b/jedi/inference/syntax_tree.py index fe007f32..743c4b0a 100644 --- a/jedi/inference/syntax_tree.py +++ b/jedi/inference/syntax_tree.py @@ -9,7 +9,7 @@ from jedi._compatibility import force_unicode, unicode from jedi import debug from jedi import parser_utils from jedi.inference.base_value import ValueSet, NO_VALUES, ContextualizedNode, \ - ContextualizedName, iterator_to_value_set, iterate_values + iterator_to_value_set, iterate_values from jedi.inference.lazy_value import LazyTreeValue from jedi.inference import compiled from jedi.inference import recursion @@ -25,6 +25,7 @@ from jedi.inference.compiled.access import COMPARISON_OPERATORS from jedi.inference.cache import inference_state_method_cache from jedi.inference.gradual.stub_value import VersionInfo from jedi.inference.gradual import annotation +from jedi.inference.names import TreeNameDefinition from jedi.inference.value.decorator import Decoratee from jedi.plugins import plugin_manager @@ -301,8 +302,8 @@ def _infer_expr_stmt(context, stmt, seek_name=None): value_set = context.infer_node(rhs) if seek_name: - c_node = ContextualizedName(context, seek_name) - value_set = check_tuple_assignments(c_node, value_set) + n = TreeNameDefinition(context, seek_name) + value_set = check_tuple_assignments(n, value_set) first_operator = next(stmt.yield_operators(), None) is_setitem, subscriptlist = check_setitem(stmt) @@ -614,8 +615,8 @@ def tree_name_to_values(inference_state, context, tree_name): contextualized_node=cn, is_async=node.parent.type == 'async_stmt', ) - c_node = ContextualizedName(context, tree_name) - types = check_tuple_assignments(c_node, for_types) + n = TreeNameDefinition(context, tree_name) + types = check_tuple_assignments(n, for_types) elif typ == 'expr_stmt': types = _remove_statements(context, node, tree_name) elif typ == 'with_stmt': @@ -687,13 +688,13 @@ def _apply_decorators(context, node): return values -def check_tuple_assignments(contextualized_name, value_set): +def check_tuple_assignments(name, value_set): """ Checks if tuples are assigned. """ lazy_value = None - for index, node in contextualized_name.assignment_indexes(): - cn = ContextualizedNode(contextualized_name.context, node) + for index, node in name.assignment_indexes(): + cn = ContextualizedNode(name.parent_context, node) iterated = value_set.iterate(cn) if isinstance(index, slice): # For no star unpacking is not possible.