Fix: iterators are working smoothly now. Finally tests are passing again.

This commit is contained in:
Dave Halter
2015-12-10 04:37:23 +01:00
parent e23f453a11
commit 9bd6e6c340
7 changed files with 45 additions and 33 deletions

View File

@@ -631,6 +631,7 @@ class Interpreter(Script):
if isinstance(user_stmt, tree.Import) or not is_simple_path:
return super(Interpreter, self)._simple_complete(path, dot, like)
else:
# TODO Remove this branch? The above branch should be fast enough IMO.
class NamespaceModule(object):
def __getattr__(_, name):
for n in self.namespaces:

View File

@@ -10,16 +10,15 @@ CODES = {
'attribute-error': (1, AttributeError, 'Potential AttributeError.'),
'name-error': (2, NameError, 'Potential NameError.'),
'import-error': (3, ImportError, 'Potential ImportError.'),
'type-error-generator': (4, TypeError, "TypeError: 'generator' object is not subscriptable."),
'type-error-too-many-arguments': (5, TypeError, None),
'type-error-too-few-arguments': (6, TypeError, None),
'type-error-keyword-argument': (7, TypeError, None),
'type-error-multiple-values': (8, TypeError, None),
'type-error-star-star': (9, TypeError, None),
'type-error-star': (10, TypeError, None),
'type-error-operation': (11, TypeError, None),
'type-error-not-iterable': (12, TypeError, None),
'type-error-isinstance': (13, TypeError, None),
'type-error-too-many-arguments': (4, TypeError, None),
'type-error-too-few-arguments': (5, TypeError, None),
'type-error-keyword-argument': (6, TypeError, None),
'type-error-multiple-values': (7, TypeError, None),
'type-error-star-star': (8, TypeError, None),
'type-error-star': (9, TypeError, None),
'type-error-operation': (10, TypeError, None),
'type-error-not-iterable': (11, TypeError, None),
'type-error-isinstance': (12, TypeError, None),
'type-error-not-subscriptable': (13, TypeError, None),
}

View File

@@ -250,6 +250,7 @@ class NameFinder(object):
def _names_to_types(self, names, search_global):
types = set()
debug.warning('start nt %s', names)
# Add isinstance and other if/assert knowledge.
if isinstance(self.name_str, tree.Name):
# Ignore FunctionExecution parents for now.

View File

@@ -23,7 +23,7 @@ It is important to note that:
from jedi.common import unite, ignored, safe_property
from jedi import debug
from jedi import settings
from jedi._compatibility import use_metaclass, unicode
from jedi._compatibility import use_metaclass, unicode, zip_longest
from jedi.parser import tree
from jedi.evaluate import compiled
from jedi.evaluate import helpers
@@ -51,14 +51,12 @@ class GeneratorMixin(object):
dct[name.value] = [name]
yield dct
def get_index_types(self, evaluator, index_array):
#debug.warning('Tried to get array access on a generator: %s', self)
analysis.add(self._evaluator, 'type-error-generator', index_array)
return set()
def py__bool__(self):
return True
def get_index_types(self):
raise NotImplementedError
def py__class__(self, evaluator):
gen_obj = compiled.get_special_object(self._evaluator, 'GENERATOR_OBJECT')
return gen_obj.py__class__(evaluator)
@@ -76,6 +74,7 @@ class Generator(use_metaclass(CachedMetaClass, IterableWrapper, GeneratorMixin))
""" returns the content of __iter__ """
# Directly execute it, because with a normal call to py__call__ a
# Generator will be returned.
raise NotImplementedError
from jedi.evaluate.representation import FunctionExecution
f = FunctionExecution(self._evaluator, self.func, self.var_args)
return f.get_return_types(check_yields=True)
@@ -90,6 +89,7 @@ class Generator(use_metaclass(CachedMetaClass, IterableWrapper, GeneratorMixin))
Exact lookups are used for tuple lookups, which are perfectly fine if
used with generators.
"""
raise NotImplementedError
return list(self.py__iter__())[index]
def __getattr__(self, name):
@@ -112,7 +112,7 @@ class GeneratorMethod(IterableWrapper):
def py__call__(self, evaluator, params):
# TODO add TypeError if params are given.
return self._generator.iter_content()
return unite(self._generator.py__iter__())
def __getattr__(self, name):
return getattr(self._builtin_func, name)
@@ -152,27 +152,27 @@ class Comprehension(IterableWrapper):
return helpers.deep_ast_copy(self._get_comprehension().children[0], parent=last_comp)
def py__iter__(self):
def nested(input_types, comp_fors, node):
iterated = py__iter__(evaluator, input_types, node)
def nested(comp_fors):
comp_for = comp_fors[0]
input_node = comp_for.children[3]
input_types = evaluator.eval_element(input_node)
iterated = py__iter__(evaluator, input_types, input_node)
exprlist = comp_for.children[1]
for types in iterated:
evaluator.predefined_if_name_dict_dict[comp_for] = \
unpack_tuple_to_dict(evaluator, types, exprlist)
try:
if len(comp_fors) > 1:
for result in nested(types, comp_fors[1:], exprlist):
yield result
else:
yield evaluator.eval_element(self.eval_node())
for result in nested(comp_fors[1:]):
yield result
except IndexError:
yield evaluator.eval_element(self.eval_node())
finally:
del evaluator.predefined_if_name_dict_dict[comp_for]
evaluator = self._evaluator
comp_fors = list(self._get_comp_for().get_comp_fors())
input_node = comp_fors[0].children[3]
input_types = evaluator.eval_element(input_node)
for result in nested(input_types, comp_fors, input_node):
for result in nested(comp_fors):
yield result
def get_exact_index_types(self, index):
@@ -203,9 +203,11 @@ class ListComprehension(Comprehension, ArrayMixin):
type = 'list'
def get_index_types(self, evaluator, index):
raise NotImplementedError
return self.iter_content()
def iter_content(self):
raise NotImplementedError
return self._evaluator.eval_element(self.eval_node())
def py__getitem__(self, index):
@@ -219,6 +221,7 @@ class ListComprehension(Comprehension, ArrayMixin):
class GeneratorComprehension(Comprehension, GeneratorMixin):
def iter_content(self):
raise NotImplementedError
return self._evaluator.eval_element(self.eval_node())
@@ -251,6 +254,7 @@ class Array(IterableWrapper, ArrayMixin):
:param index: A subscriptlist node (or subnode).
"""
raise NotImplementedError
indexes = create_index_types(evaluator, index)
lookup_done = False
types = set()
@@ -296,6 +300,7 @@ class Array(IterableWrapper, ArrayMixin):
return self._evaluator.eval_element(self._items()[index])
def iter_content(self):
raise NotImplementedError
return self.values()
@safe_property
@@ -489,6 +494,7 @@ def unpack_tuple_to_dict(evaluator, types, exprlist):
def py__iter__(evaluator, types, node=None):
debug.dbg('py__iter__')
type_iters = []
for typ in types:
try:
iter_method = typ.py__iter__
@@ -497,8 +503,12 @@ def py__iter__(evaluator, types, node=None):
analysis.add(evaluator, 'type-error-not-iterable', node,
message="TypeError: '%s' object is not iterable" % typ)
else:
for result in iter_method():
yield result
type_iters.append(iter_method())
#for result in iter_method():
#yield result
for t in zip_longest(*type_iters, fillvalue=set()):
yield unite(t)
def py__iter__types(evaluator, types, node=None):
@@ -696,6 +706,7 @@ class _ArrayInstance(IterableWrapper):
The index is here just ignored, because of all the appends, etc.
lists/sets are too complicated too handle that.
"""
raise NotImplementedError
items = set()
for key, nodes in self.var_args.unpack():
for node in nodes:

View File

@@ -383,8 +383,8 @@ def _iterate_star_args(evaluator, array, input_node, func=None):
for field_stmt in array: # yield from plz!
yield field_stmt
elif isinstance(array, iterable.Generator):
for field_stmt in array.iter_content():
yield iterable.AlreadyEvaluated([field_stmt])
for types in array.py__iter__():
yield iterable.AlreadyEvaluated(types)
elif isinstance(array, Instance) and array.name.get_code() == 'tuple':
debug.warning('Ignored a tuple *args input %s' % array)
else:

View File

@@ -120,7 +120,7 @@ def gen():
a, b = next(gen())
#? int()
a
#? str()
#? str() float()
b

View File

@@ -1,7 +1,7 @@
def generator():
yield 1
#! 12 type-error-generator
#! 11 type-error-not-subscriptable
generator()[0]
list(generator())[0]