diff --git a/jedi/evaluate/__init__.py b/jedi/evaluate/__init__.py index 8f620dc0..8fbacdae 100644 --- a/jedi/evaluate/__init__.py +++ b/jedi/evaluate/__init__.py @@ -83,6 +83,7 @@ from jedi.evaluate import stdlib from jedi.evaluate import finder from jedi.evaluate import compiled from jedi.evaluate import precedence +from jedi.evaluate.helpers import FakeStatement class Evaluator(object): @@ -124,6 +125,8 @@ class Evaluator(object): """ debug.dbg('eval_statement %s (%s)', stmt, seek_name) expression_list = stmt.expression_list() + if isinstance(stmt, FakeStatement): + return expression_list # Already contains the results. result = self.eval_expression_list(expression_list) diff --git a/jedi/evaluate/helpers.py b/jedi/evaluate/helpers.py index 0b04976d..409fb0ea 100644 --- a/jedi/evaluate/helpers.py +++ b/jedi/evaluate/helpers.py @@ -180,10 +180,11 @@ class FakeArray(pr.Array): class FakeStatement(pr.Statement): - def __init__(self, expression_list, start_pos=(0, 0)): + def __init__(self, expression_list, start_pos=(0, 0), parent=None): p = start_pos super(FakeStatement, self).__init__(FakeSubModule, expression_list, p, p) self.set_expression_list(expression_list) + self.parent = parent class FakeImport(pr.Import): diff --git a/jedi/evaluate/iterable.py b/jedi/evaluate/iterable.py index aad1faf5..61704978 100644 --- a/jedi/evaluate/iterable.py +++ b/jedi/evaluate/iterable.py @@ -127,16 +127,16 @@ class Array(use_metaclass(CachedMetaClass, pr.Base)): if [index for index in indexes if isinstance(index, Slice)]: return [self] - if len(indexes) == 1: - # This is indexing only one element, with a fixed index number, - # otherwise it just ignores the index (e.g. [1+1]). - index = indexes[0] + lookup_done = False + types = [] + for index in indexes: if isinstance(index, compiled.CompiledObject) \ and isinstance(index.obj, (int, str, unicode)): with common.ignored(KeyError, IndexError, TypeError): - return self.get_exact_index_types(index.obj) + types += self.get_exact_index_types(index.obj) + lookup_done = True - return self.values() + return types if lookup_done else self.values() @memoize_default(NO_DEFAULT) def values(self): diff --git a/jedi/evaluate/representation.py b/jedi/evaluate/representation.py index 4dc35c11..47252e29 100644 --- a/jedi/evaluate/representation.py +++ b/jedi/evaluate/representation.py @@ -179,8 +179,9 @@ class Instance(use_metaclass(CachedMetaClass, Executable)): # TODO support slices in a more general way. indexes = [] + index = helpers.FakeStatement(indexes, parent=compiled.builtin) try: - return self.execute_subscope_by_name('__getitem__', indexes) + return self.execute_subscope_by_name('__getitem__', [index]) except KeyError: debug.warning('No __getitem__, cannot access the array.') return [] diff --git a/jedi/evaluate/stdlib.py b/jedi/evaluate/stdlib.py index e174089c..e40fcf6b 100644 --- a/jedi/evaluate/stdlib.py +++ b/jedi/evaluate/stdlib.py @@ -97,7 +97,7 @@ def builtins_reversed(evaluator, obj, params): # would fail in certain cases like `reversed(x).__iter__` if we # just returned the result directly. stmts = [FakeStatement([r]) for r in rev] - objects = (FakeArray(stmts, objects[0].parent),) + objects = (iterable.Array(evaluator, FakeArray(stmts, objects[0].parent)),) return [er.Instance(evaluator, obj, objects)] diff --git a/test/completion/arrays.py b/test/completion/arrays.py index 70f58643..c1fbd426 100644 --- a/test/completion/arrays.py +++ b/test/completion/arrays.py @@ -276,6 +276,17 @@ class GetItem(): #? str() GetItem("")[1] +class GetItemWithList(): + def __getitem__(self, index): + return [1, 1.0, 's'][index] + +#? float() +GetItemWithList()[1] + +for i in 0, 2: + #? int() str() + GetItemWithList()[i] + # ----------------- # conversions # ----------------- diff --git a/test/completion/std.py b/test/completion/std.py index 3e6c49a3..40c798f0 100644 --- a/test/completion/std.py +++ b/test/completion/std.py @@ -12,6 +12,7 @@ sorted(arr)[0] #? str() next(reversed(arr)) +next(reversed(arr)) # should not fail if there's no return value. def yielder():