forked from VimPlug/jedi
Fix: py__iter__ in dynamic list/set usages with empy params.
This commit is contained in:
@@ -198,6 +198,17 @@ class CompiledObject(Base):
|
||||
pass # self.obj maynot have an __iter__ method.
|
||||
return result
|
||||
|
||||
def py__iter__(self):
|
||||
if not hasattr(self.obj, '__iter__'):
|
||||
debug.warning('Tried to call __getitem__ on non-iterable.')
|
||||
return
|
||||
if type(self.obj) not in (str, list, tuple, unicode, bytes, bytearray, dict):
|
||||
# Get rid of side effects, we won't call custom `__getitem__`s.
|
||||
return
|
||||
|
||||
for obj in self.obj:
|
||||
yield set([CompiledObject(obj)])
|
||||
|
||||
@property
|
||||
def name(self):
|
||||
# might not exist sometimes (raises AttributeError)
|
||||
|
||||
@@ -298,28 +298,27 @@ class NameFinder(object):
|
||||
|
||||
@memoize_default(set(), evaluator_is_first_arg=True)
|
||||
def _name_to_types(evaluator, name, scope):
|
||||
types = set()
|
||||
typ = name.get_definition()
|
||||
if typ.isinstance(tree.ForStmt, tree.CompFor):
|
||||
container_types = evaluator.eval_element(typ.children[3])
|
||||
for_types = common.unite(iterable.py__iter__(evaluator, container_types))
|
||||
types |= check_tuple_assignments(for_types, name)
|
||||
types = check_tuple_assignments(for_types, name)
|
||||
elif isinstance(typ, tree.Param):
|
||||
types |= _eval_param(evaluator, typ, scope)
|
||||
types = _eval_param(evaluator, typ, scope)
|
||||
elif typ.isinstance(tree.ExprStmt):
|
||||
types |= _remove_statements(evaluator, typ, name)
|
||||
types = _remove_statements(evaluator, typ, name)
|
||||
elif typ.isinstance(tree.WithStmt):
|
||||
types |= evaluator.eval_element(typ.node_from_name(name))
|
||||
types = evaluator.eval_element(typ.node_from_name(name))
|
||||
elif isinstance(typ, tree.Import):
|
||||
types |= imports.ImportWrapper(evaluator, name).follow()
|
||||
types = imports.ImportWrapper(evaluator, name).follow()
|
||||
elif isinstance(typ, tree.GlobalStmt):
|
||||
# TODO theoretically we shouldn't be using search_global here, it
|
||||
# doesn't make sense, because it's a local search (for that name)!
|
||||
# However, globals are not that important and resolving them doesn't
|
||||
# guarantee correctness in any way, because we don't check for when
|
||||
# something is executed.
|
||||
types |= evaluator.find_types(typ.get_parent_scope(), str(name),
|
||||
search_global=True)
|
||||
types = evaluator.find_types(typ.get_parent_scope(), str(name),
|
||||
search_global=True)
|
||||
elif isinstance(typ, tree.TryStmt):
|
||||
# TODO an exception can also be a tuple. Check for those.
|
||||
# TODO check for types that are not classes and add it to
|
||||
@@ -329,7 +328,7 @@ def _name_to_types(evaluator, name, scope):
|
||||
else:
|
||||
if typ.isinstance(er.Function):
|
||||
typ = typ.get_decorated_func()
|
||||
types.add(typ)
|
||||
types = set([typ])
|
||||
return types
|
||||
|
||||
|
||||
|
||||
@@ -316,6 +316,8 @@ class Array(IterableWrapper, ArrayMixin):
|
||||
for value in iterate:
|
||||
yield self._evaluator.eval_element(value)
|
||||
|
||||
yield check_array_additions(self._evaluator, self)
|
||||
|
||||
def _values(self):
|
||||
"""Returns a list of a list of node."""
|
||||
if self.type == 'dict':
|
||||
@@ -485,9 +487,15 @@ def unpack_tuple_to_dict(evaluator, types, exprlist):
|
||||
|
||||
|
||||
def py__iter__(evaluator, types):
|
||||
debug.dbg('py__iter__')
|
||||
for typ in types:
|
||||
for result in typ.py__iter__():
|
||||
yield result
|
||||
try:
|
||||
iter_method = typ.py__iter__
|
||||
except AttributeError:
|
||||
raise NotImplementedError
|
||||
else:
|
||||
for result in iter_method():
|
||||
yield result
|
||||
|
||||
|
||||
def get_iterator_types(evaluator, element):
|
||||
@@ -690,15 +698,18 @@ class _ArrayInstance(IterableWrapper):
|
||||
return items
|
||||
|
||||
def py__iter__(self):
|
||||
_, first_nodes = next(self.var_args.unpack())
|
||||
types = unite(self._evaluator.eval_element(node) for node in first_nodes)
|
||||
try:
|
||||
_, first_nodes = next(self.var_args.unpack())
|
||||
except StopIteration:
|
||||
types = set()
|
||||
else:
|
||||
types = unite(self._evaluator.eval_element(node) for node in first_nodes)
|
||||
|
||||
for typ in py__iter__(self._evaluator, types):
|
||||
yield typ
|
||||
for types in py__iter__(self._evaluator, types):
|
||||
yield types
|
||||
module = self.var_args.get_parent_until()
|
||||
is_list = str(self.instance.name) == 'list'
|
||||
for typ in _check_array_additions(self._evaluator, self.instance, module, is_list):
|
||||
yield typ
|
||||
yield _check_array_additions(self._evaluator, self.instance, module, is_list)
|
||||
|
||||
|
||||
class Slice(object):
|
||||
|
||||
Reference in New Issue
Block a user