Some improvements towards iterators.

This commit is contained in:
Dave Halter
2016-11-12 03:53:25 +01:00
parent 9369d264d4
commit 7848be97ab
5 changed files with 27 additions and 25 deletions

View File

@@ -152,8 +152,7 @@ class Evaluator(object):
operator = copy.copy(first_operation) operator = copy.copy(first_operation)
operator.value = operator.value[:-1] operator.value = operator.value[:-1]
name = str(stmt.get_defined_names()[0]) name = str(stmt.get_defined_names()[0])
parent = self.wrap(stmt.get_parent_scope()) left = self.find_types(context, name, stmt.start_pos, search_global=True)
left = self.find_types(parent, name, stmt.start_pos, search_global=True)
for_stmt = stmt.get_parent_until(tree.ForStmt) for_stmt = stmt.get_parent_until(tree.ForStmt)
if isinstance(for_stmt, tree.ForStmt) and types \ if isinstance(for_stmt, tree.ForStmt) and types \
@@ -351,7 +350,7 @@ class Evaluator(object):
elif c[0] == '(' and not len(c) == 2 \ elif c[0] == '(' and not len(c) == 2 \
and not(tree.is_node(c[1], 'testlist_comp') and not(tree.is_node(c[1], 'testlist_comp')
and len(c[1].children) > 1): and len(c[1].children) > 1):
return self.eval_element(c[1]) return self.eval_element(context, c[1])
try: try:
comp_for = c[1].children[1] comp_for = c[1].children[1]

View File

@@ -13,7 +13,7 @@ from jedi.cache import underscore_memoization, memoize_method
from jedi.parser.tree import Param, Operator from jedi.parser.tree import Param, Operator
from jedi.evaluate.helpers import FakeName from jedi.evaluate.helpers import FakeName
from jedi.evaluate.filters import AbstractFilter, AbstractNameDefinition from jedi.evaluate.filters import AbstractFilter, AbstractNameDefinition
from jedi.evaluate.context import Context from jedi.evaluate.context import Context, LazyKnownContext
from . import fake from . import fake
@@ -202,7 +202,7 @@ class CompiledObject(Context):
return return
for part in self.obj: for part in self.obj:
yield set([create(self.evaluator, part)]) yield LazyKnownContext(create(self.evaluator, part))
@property @property
def name(self): def name(self):

View File

@@ -370,7 +370,7 @@ def _name_to_types(evaluator, context, name, scope):
elif node.isinstance(tree.ExprStmt): elif node.isinstance(tree.ExprStmt):
types = _remove_statements(evaluator, context, node, name) types = _remove_statements(evaluator, context, node, name)
elif node.isinstance(tree.WithStmt): elif node.isinstance(tree.WithStmt):
types = evaluator.eval_element(node.node_from_name(name)) types = context.eval_node(node.node_from_name(name))
elif isinstance(node, tree.Import): elif isinstance(node, tree.Import):
types = imports.ImportWrapper(context, name).follow() types = imports.ImportWrapper(context, name).follow()
elif node.type in ('funcdef', 'classdef'): elif node.type in ('funcdef', 'classdef'):

View File

@@ -1,10 +1,11 @@
from abc import abstractproperty from abc import abstractproperty
from jedi._compatibility import is_py3
from jedi.common import unite from jedi.common import unite
from jedi import debug from jedi import debug
from jedi.evaluate import compiled from jedi.evaluate import compiled
from jedi.evaluate import filters from jedi.evaluate import filters
from jedi.evaluate.context import Context, LazyKnownContext from jedi.evaluate.context import Context, LazyKnownContext, get_merged_lazy_context
from jedi.evaluate.cache import memoize_default from jedi.evaluate.cache import memoize_default
from jedi.cache import memoize_method from jedi.cache import memoize_method
from jedi.evaluate import representation as er from jedi.evaluate import representation as er
@@ -117,24 +118,24 @@ class AbstractInstanceContext(Context):
return unite(name.execute_evaluated(index_obj) for name in names) return unite(name.execute_evaluated(index_obj) for name in names)
def py__iter__(self): def py__iter__(self):
try: iter_slot_names = self.get_function_slot_names('__iter__')
method = self.get_subscope_by_name('__iter__') if not iter_slot_names:
except KeyError:
debug.warning('No __iter__ on %s.' % self) debug.warning('No __iter__ on %s.' % self)
return return
else:
iters = self.evaluator.execute(method) for generator in self.execute_function_slots(iter_slot_names):
for generator in iters: if isinstance(generator, AbstractInstanceContext):
if isinstance(generator, Instance): # `__next__` logic.
# `__next__` logic. name = '__next__' if is_py3 else 'next'
name = '__next__' if is_py3 else 'next' try:
try: yield get_merged_lazy_context(
yield generator.execute_subscope_by_name(name) generator.execute_subscope_by_name(name)
except KeyError: )
debug.warning('Instance has no __next__ function in %s.', generator) except KeyError:
else: debug.warning('Instance has no __next__ function in %s.', generator)
for typ in generator.py__iter__(): else:
yield typ for lazy_context in generator.py__iter__():
yield lazy_context
@abstractproperty @abstractproperty
def name(self): def name(self):

View File

@@ -611,8 +611,10 @@ def py__iter__(evaluator, types, node=None):
else: else:
type_iters.append(iter_method()) type_iters.append(iter_method())
for lazy_contexts in zip_longest(*type_iters, fillvalue=set()): for lazy_contexts in zip_longest(*type_iters, fillvalue=None):
yield context.get_merged_lazy_context(lazy_contexts) yield context.get_merged_lazy_context(
[l for l in lazy_contexts if l is not None]
)
def py__iter__types(evaluator, types, node=None): def py__iter__types(evaluator, types, node=None):