From d1199024963410f4d7cc46dcac420f52bef73fc0 Mon Sep 17 00:00:00 2001 From: Dave Halter Date: Tue, 21 Oct 2014 13:36:56 +0200 Subject: [PATCH] Slices --- jedi/evaluate/__init__.py | 7 +++++-- jedi/evaluate/iterable.py | 26 ++++++++++++++++++++------ 2 files changed, 25 insertions(+), 8 deletions(-) diff --git a/jedi/evaluate/__init__.py b/jedi/evaluate/__init__.py index 4b27e5f6..316f5379 100644 --- a/jedi/evaluate/__init__.py +++ b/jedi/evaluate/__init__.py @@ -160,6 +160,7 @@ class Evaluator(object): for ass_expression_list, op in ass_details: new_result += finder.find_assignments(ass_expression_list[0], result, seek_name) result = new_result + debug.dbg('eval_statement result %s', result) return result def eval_element(self, element): @@ -170,7 +171,8 @@ class Evaluator(object): for trailer in element.children[1:]: if trailer == '**': # has a power operation. raise NotImplementedError - types = self.eval_trailer(types, trailer) + types = self._eval_trailer(types, trailer) + return types else: left, operator, right = element.children @@ -193,12 +195,13 @@ class Evaluator(object): else: return [iterable.Array(self, atom.children[1], pr.Array.LIST)] - def eval_trailer(self, types, trailer): + def _eval_trailer(self, types, trailer): trailer_op, node = trailer.children[:2] if node == ')': # `arglist` is optional. node = () new_types = [] for typ in types: + debug.dbg('_eval_trailer: %s in scope %s', trailer, typ) if trailer_op == '.': raise NotImplementedError elif trailer_op == '(': diff --git a/jedi/evaluate/iterable.py b/jedi/evaluate/iterable.py index ef9dc24d..00f0dc6e 100644 --- a/jedi/evaluate/iterable.py +++ b/jedi/evaluate/iterable.py @@ -131,7 +131,7 @@ class Array(use_metaclass(CachedMetaClass, IterableWrapper)): @property def name(self): - return helpers.FakeName(self._array.type, parent=self) + return helpers.FakeName(self.type, parent=self) def py__bool__(self): return None # We don't know the length, because of appends. @@ -144,13 +144,13 @@ class Array(use_metaclass(CachedMetaClass, IterableWrapper)): :param index: A subscriptlist node (or subnode). """ indexes = create_indexes_or_slices(self._evaluator, index) - if [i for i in indexes if isinstance(index, Slice)]: - return [self] - lookup_done = False types = [] for index in indexes: - if isinstance(index, compiled.CompiledObject) \ + if isinstance(index, Slice): + types += [self] + lookup_done = True + elif isinstance(index, compiled.CompiledObject) \ and isinstance(index.obj, (int, str, unicode)): with common.ignored(KeyError, IndexError, TypeError): types += self.get_exact_index_types(index.obj) @@ -212,7 +212,7 @@ class Array(use_metaclass(CachedMetaClass, IterableWrapper)): return compiled.builtin def __getattr__(self, name): - if name not in ['type', 'start_pos', 'get_only_subelement', 'parent', + if name not in ['start_pos', 'get_only_subelement', 'parent', 'get_parent_until', 'items']: raise AttributeError('Strange access on %s: %s.' % (self, name)) return getattr(self._array, name) @@ -489,6 +489,20 @@ class Slice(object): def create_indexes_or_slices(evaluator, index): + if pr.is_node(index, 'subscript'): # subscript is a slice operation. + start, stop, step = None, None, None + result = [] + for el in index.children: + if el == ':' and not result: + result.append(None) + elif pr.is_node(el, 'sliceop'): + if len(el.children) == 2: + result.append(el.children[1]) + else: + result.append(result) + result += [None] * (3 - len(result)) + + return (Slice(evaluator, *result),) return evaluator.eval_element(index) # TODO delete the rest?