mirror of
https://github.com/davidhalter/jedi.git
synced 2025-12-06 05:54:25 +08:00
Fix: iterators are working smoothly now. Finally tests are passing again.
This commit is contained in:
@@ -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:
|
||||
|
||||
@@ -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),
|
||||
}
|
||||
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -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:
|
||||
|
||||
@@ -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:
|
||||
|
||||
@@ -120,7 +120,7 @@ def gen():
|
||||
a, b = next(gen())
|
||||
#? int()
|
||||
a
|
||||
#? str()
|
||||
#? str() float()
|
||||
b
|
||||
|
||||
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
def generator():
|
||||
yield 1
|
||||
|
||||
#! 12 type-error-generator
|
||||
#! 11 type-error-not-subscriptable
|
||||
generator()[0]
|
||||
|
||||
list(generator())[0]
|
||||
|
||||
Reference in New Issue
Block a user