diff --git a/jedi/evaluate/iterable.py b/jedi/evaluate/iterable.py index c8d8e64d..afe953c1 100644 --- a/jedi/evaluate/iterable.py +++ b/jedi/evaluate/iterable.py @@ -180,14 +180,11 @@ class Array(use_metaclass(CachedMetaClass, pr.Base)): raise AttributeError('Strange access on %s: %s.' % (self, name)) return getattr(self._array, name) - def __getitem__(self): - return self._array.__getitem__() - def __iter__(self): - return self._array.__iter__() + return iter(self._array) def __len__(self): - return self._array.__len__() + return len(self._array) def __repr__(self): return "" % (type(self).__name__, self._array) @@ -215,6 +212,26 @@ class ArrayMethod(object): return "<%s of %s>" % (type(self).__name__, self.name) +class MergedArray(Array): + def __init__(self, evaluator, arrays): + super(MergedArray, self).__init__(evaluator, arrays[-1]._array) + self._arrays = arrays + + def get_index_types(self, mixed_index): + return list(chain(*(a.values() for a in self._arrays))) + + def get_exact_index_types(self, mixed_index): + raise IndexError + + def __iter__(self): + for array in self._arrays: + for a in array: + yield a + + def __len__(self): + return sum(len(a) for a in self._arrays) + + def get_iterator_types(inputs): """Returns the types of any iterator (arrays, yields, __iter__, etc).""" iterators = [] diff --git a/jedi/evaluate/precedence.py b/jedi/evaluate/precedence.py index 437ac431..bbfe7246 100644 --- a/jedi/evaluate/precedence.py +++ b/jedi/evaluate/precedence.py @@ -232,15 +232,27 @@ def is_literal(obj): return _is_number(obj) or _is_string(obj) +def _is_tuple(obj): + from jedi.evaluate import iterable + return isinstance(obj, iterable.Array) and obj.type == pr.Array.TUPLE + + +def _is_list(obj): + from jedi.evaluate import iterable + return isinstance(obj, iterable.Array) and obj.type == pr.Array.LIST + + def _element_calculate(evaluator, left, operator, right): + from jedi.evaluate import iterable if operator == '*': # for iterables, ignore * operations - from jedi.evaluate import iterable if isinstance(left, iterable.Array) or _is_string(left): return [left] elif operator == '+': if _is_number(left) and _is_number(right) or _is_string(left) and _is_string(right): return [create(evaluator, left.obj + right.obj)] + elif _is_tuple(left) and _is_tuple(right) or _is_list(left) and _is_list(right): + return [iterable.MergedArray(evaluator, (left, right))] elif operator == '-': if _is_number(left) and _is_number(right): return [create(evaluator, left.obj - right.obj)]