forked from VimPlug/jedi
Move iterate logic to the context.
This commit is contained in:
@@ -1,7 +1,7 @@
|
|||||||
from parso.python.tree import ExprStmt, CompFor
|
from parso.python.tree import ExprStmt, CompFor
|
||||||
|
|
||||||
from jedi import debug
|
from jedi import debug
|
||||||
from jedi._compatibility import Python3Method
|
from jedi._compatibility import Python3Method, zip_longest
|
||||||
from jedi.parser_utils import clean_scope_docstring, get_doc_with_call_signature
|
from jedi.parser_utils import clean_scope_docstring, get_doc_with_call_signature
|
||||||
from jedi.common import BaseContextSet
|
from jedi.common import BaseContextSet
|
||||||
|
|
||||||
@@ -66,6 +66,22 @@ class Context(object):
|
|||||||
|
|
||||||
return self.evaluator.execute(self, arguments)
|
return self.evaluator.execute(self, arguments)
|
||||||
|
|
||||||
|
def iterate(self, contextualized_node=None):
|
||||||
|
debug.dbg('iterate')
|
||||||
|
try:
|
||||||
|
iter_method = self.py__iter__
|
||||||
|
except AttributeError:
|
||||||
|
if contextualized_node is not None:
|
||||||
|
from jedi.evaluate import analysis
|
||||||
|
analysis.add(
|
||||||
|
contextualized_node.context,
|
||||||
|
'type-error-not-iterable',
|
||||||
|
contextualized_node._node,
|
||||||
|
message="TypeError: '%s' object is not iterable" % self)
|
||||||
|
return iter([])
|
||||||
|
else:
|
||||||
|
return iter_method()
|
||||||
|
|
||||||
def execute_evaluated(self, *value_list):
|
def execute_evaluated(self, *value_list):
|
||||||
"""
|
"""
|
||||||
Execute a function with already executed arguments.
|
Execute a function with already executed arguments.
|
||||||
@@ -248,6 +264,13 @@ class ContextSet(BaseContextSet):
|
|||||||
def py__class__(self):
|
def py__class__(self):
|
||||||
return ContextSet.from_iterable(c.py__class__() for c in self._set)
|
return ContextSet.from_iterable(c.py__class__() for c in self._set)
|
||||||
|
|
||||||
|
def iterate(self, contextualized_node=None):
|
||||||
|
type_iters = [c.iterate(contextualized_node) for c in self._set]
|
||||||
|
for lazy_contexts in zip_longest(*type_iters):
|
||||||
|
yield get_merged_lazy_context(
|
||||||
|
[l for l in lazy_contexts if l is not None]
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
NO_CONTEXTS = ContextSet()
|
NO_CONTEXTS = ContextSet()
|
||||||
|
|
||||||
|
|||||||
@@ -23,7 +23,7 @@ It is important to note that:
|
|||||||
from jedi import debug
|
from jedi import debug
|
||||||
from jedi import settings
|
from jedi import settings
|
||||||
from jedi.evaluate.utils import safe_property
|
from jedi.evaluate.utils import safe_property
|
||||||
from jedi._compatibility import unicode, zip_longest, is_py3
|
from jedi._compatibility import unicode, is_py3
|
||||||
from jedi.evaluate.utils import to_list
|
from jedi.evaluate.utils import to_list
|
||||||
from jedi.evaluate import compiled
|
from jedi.evaluate import compiled
|
||||||
from jedi.evaluate import helpers
|
from jedi.evaluate import helpers
|
||||||
@@ -240,14 +240,13 @@ class Comprehension(AbstractSequence):
|
|||||||
return CompForContext.from_comp_for(parent_context, comp_for)
|
return CompForContext.from_comp_for(parent_context, comp_for)
|
||||||
|
|
||||||
def _nested(self, comp_fors, parent_context=None):
|
def _nested(self, comp_fors, parent_context=None):
|
||||||
evaluator = self.evaluator
|
|
||||||
comp_for = comp_fors[0]
|
comp_for = comp_fors[0]
|
||||||
input_node = comp_for.children[3]
|
input_node = comp_for.children[3]
|
||||||
parent_context = parent_context or self._defining_context
|
parent_context = parent_context or self._defining_context
|
||||||
input_types = parent_context.eval_node(input_node)
|
input_types = parent_context.eval_node(input_node)
|
||||||
|
|
||||||
cn = context.ContextualizedNode(parent_context, input_node)
|
cn = context.ContextualizedNode(parent_context, input_node)
|
||||||
iterated = py__iter__(evaluator, input_types, cn)
|
iterated = input_types.iterate(cn)
|
||||||
exprlist = comp_for.children[1]
|
exprlist = comp_for.children[1]
|
||||||
for i, lazy_context in enumerate(iterated):
|
for i, lazy_context in enumerate(iterated):
|
||||||
types = lazy_context.infer()
|
types = lazy_context.infer()
|
||||||
@@ -587,7 +586,7 @@ def unpack_tuple_to_dict(context, types, exprlist):
|
|||||||
dct = {}
|
dct = {}
|
||||||
parts = iter(exprlist.children[::2])
|
parts = iter(exprlist.children[::2])
|
||||||
n = 0
|
n = 0
|
||||||
for lazy_context in py__iter__(context.evaluator, types, exprlist):
|
for lazy_context in types.iterate(exprlist):
|
||||||
n += 1
|
n += 1
|
||||||
try:
|
try:
|
||||||
part = next(parts)
|
part = next(parts)
|
||||||
@@ -614,36 +613,14 @@ def unpack_tuple_to_dict(context, types, exprlist):
|
|||||||
raise NotImplementedError
|
raise NotImplementedError
|
||||||
|
|
||||||
|
|
||||||
def py__iter__(evaluator, types, contextualized_node=None):
|
def py__iter__types(evaluator, contexts, contextualized_node=None):
|
||||||
debug.dbg('py__iter__')
|
|
||||||
type_iters = []
|
|
||||||
for typ in types:
|
|
||||||
try:
|
|
||||||
iter_method = typ.py__iter__
|
|
||||||
except AttributeError:
|
|
||||||
if contextualized_node is not None:
|
|
||||||
analysis.add(
|
|
||||||
contextualized_node.context,
|
|
||||||
'type-error-not-iterable',
|
|
||||||
contextualized_node._node,
|
|
||||||
message="TypeError: '%s' object is not iterable" % typ)
|
|
||||||
else:
|
|
||||||
type_iters.append(iter_method())
|
|
||||||
|
|
||||||
for lazy_contexts in zip_longest(*type_iters):
|
|
||||||
yield context.get_merged_lazy_context(
|
|
||||||
[l for l in lazy_contexts if l is not None]
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
def py__iter__types(evaluator, types, contextualized_node=None):
|
|
||||||
"""
|
"""
|
||||||
Calls `py__iter__`, but ignores the ordering in the end and just returns
|
Calls `py__iter__`, but ignores the ordering in the end and just returns
|
||||||
all types that it contains.
|
all types that it contains.
|
||||||
"""
|
"""
|
||||||
return ContextSet.from_sets(
|
return ContextSet.from_sets(
|
||||||
lazy_context.infer()
|
lazy_context.infer()
|
||||||
for lazy_context in py__iter__(evaluator, types, contextualized_node)
|
for lazy_context in contexts.iterate(contextualized_node)
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
@@ -682,7 +659,8 @@ def py__getitem__(evaluator, context, types, trailer):
|
|||||||
if isinstance(typ, AbstractSequence) and typ.array_type == 'dict':
|
if isinstance(typ, AbstractSequence) and typ.array_type == 'dict':
|
||||||
types.remove(typ)
|
types.remove(typ)
|
||||||
result |= typ.dict_values()
|
result |= typ.dict_values()
|
||||||
return result | py__iter__types(evaluator, types)
|
cs = ContextSet.from_set(types)
|
||||||
|
return result | py__iter__types(evaluator, cs)
|
||||||
|
|
||||||
for typ in types:
|
for typ in types:
|
||||||
# The actual getitem call.
|
# The actual getitem call.
|
||||||
@@ -739,7 +717,7 @@ def _check_array_additions(context, sequence):
|
|||||||
result.add(whatever)
|
result.add(whatever)
|
||||||
elif add_name in ['extend', 'update']:
|
elif add_name in ['extend', 'update']:
|
||||||
for key, lazy_context in params:
|
for key, lazy_context in params:
|
||||||
result |= set(py__iter__(context.evaluator, lazy_context.infer()))
|
result |= set(lazy_context.infer().iterate())
|
||||||
return result
|
return result
|
||||||
|
|
||||||
temp_param_add, settings.dynamic_params_for_other_modules = \
|
temp_param_add, settings.dynamic_params_for_other_modules = \
|
||||||
@@ -827,7 +805,7 @@ class _ArrayInstance(object):
|
|||||||
except StopIteration:
|
except StopIteration:
|
||||||
pass
|
pass
|
||||||
else:
|
else:
|
||||||
for lazy in py__iter__(self.instance.evaluator, lazy_context.infer()):
|
for lazy in lazy_context.infer().iterate():
|
||||||
yield lazy
|
yield lazy
|
||||||
|
|
||||||
from jedi.evaluate import param
|
from jedi.evaluate import param
|
||||||
@@ -836,6 +814,9 @@ class _ArrayInstance(object):
|
|||||||
for addition in additions:
|
for addition in additions:
|
||||||
yield addition
|
yield addition
|
||||||
|
|
||||||
|
def iterate(self, contextualized_node=None):
|
||||||
|
return self.py__iter__()
|
||||||
|
|
||||||
|
|
||||||
class Slice(context.Context):
|
class Slice(context.Context):
|
||||||
def __init__(self, context, start, stop, step):
|
def __init__(self, context, start, stop, step):
|
||||||
|
|||||||
@@ -360,7 +360,7 @@ class FunctionExecutionContext(context.TreeContext):
|
|||||||
node = yield_expr.children[1]
|
node = yield_expr.children[1]
|
||||||
if node.type == 'yield_arg': # It must be a yield from.
|
if node.type == 'yield_arg': # It must be a yield from.
|
||||||
cn = ContextualizedNode(self, node.children[1])
|
cn = ContextualizedNode(self, node.children[1])
|
||||||
for lazy_context in iterable.py__iter__(self.evaluator, cn.infer(), cn):
|
for lazy_context in cn.infer().iterate(cn):
|
||||||
yield lazy_context
|
yield lazy_context
|
||||||
else:
|
else:
|
||||||
yield context.LazyTreeContext(self, node)
|
yield context.LazyTreeContext(self, node)
|
||||||
@@ -395,7 +395,6 @@ class FunctionExecutionContext(context.TreeContext):
|
|||||||
return
|
return
|
||||||
last_for_stmt = for_stmt
|
last_for_stmt = for_stmt
|
||||||
|
|
||||||
evaluator = self.evaluator
|
|
||||||
for for_stmt, yields in yields_order:
|
for for_stmt, yields in yields_order:
|
||||||
if for_stmt is None:
|
if for_stmt is None:
|
||||||
# No for_stmt, just normal yields.
|
# No for_stmt, just normal yields.
|
||||||
@@ -405,7 +404,7 @@ class FunctionExecutionContext(context.TreeContext):
|
|||||||
else:
|
else:
|
||||||
input_node = for_stmt.get_testlist()
|
input_node = for_stmt.get_testlist()
|
||||||
cn = ContextualizedNode(self, input_node)
|
cn = ContextualizedNode(self, input_node)
|
||||||
ordered = iterable.py__iter__(evaluator, cn.infer(), cn)
|
ordered = cn.infer().iterate(cn)
|
||||||
ordered = list(ordered)
|
ordered = list(ordered)
|
||||||
for lazy_context in ordered:
|
for lazy_context in ordered:
|
||||||
dct = {str(for_stmt.children[1].value): lazy_context.infer()}
|
dct = {str(for_stmt.children[1].value): lazy_context.infer()}
|
||||||
|
|||||||
@@ -12,7 +12,6 @@ compiled module that returns the types for C-builtins.
|
|||||||
import collections
|
import collections
|
||||||
import re
|
import re
|
||||||
|
|
||||||
from jedi.evaluate.utils import unite
|
|
||||||
from jedi.evaluate import compiled
|
from jedi.evaluate import compiled
|
||||||
from jedi.evaluate import representation as er
|
from jedi.evaluate import representation as er
|
||||||
from jedi.evaluate.instance import InstanceFunctionExecution, \
|
from jedi.evaluate.instance import InstanceFunctionExecution, \
|
||||||
@@ -200,7 +199,7 @@ def builtins_reversed(evaluator, sequences, obj, arguments):
|
|||||||
if isinstance(lazy_context, LazyTreeContext):
|
if isinstance(lazy_context, LazyTreeContext):
|
||||||
# TODO access private
|
# TODO access private
|
||||||
cn = ContextualizedNode(lazy_context._context, lazy_context.data)
|
cn = ContextualizedNode(lazy_context._context, lazy_context.data)
|
||||||
ordered = list(iterable.py__iter__(evaluator, sequences, cn))
|
ordered = list(sequences.iterate(cn))
|
||||||
|
|
||||||
rev = list(reversed(ordered))
|
rev = list(reversed(ordered))
|
||||||
# Repack iterator values and then run it the normal way. This is
|
# Repack iterator values and then run it the normal way. This is
|
||||||
@@ -232,9 +231,9 @@ def builtins_isinstance(evaluator, objects, types, arguments):
|
|||||||
elif cls_or_tup.name.string_name == 'tuple' \
|
elif cls_or_tup.name.string_name == 'tuple' \
|
||||||
and cls_or_tup.get_root_context() == evaluator.BUILTINS:
|
and cls_or_tup.get_root_context() == evaluator.BUILTINS:
|
||||||
# Check for tuples.
|
# Check for tuples.
|
||||||
classes = unite(
|
classes = ContextSet.from_sets(
|
||||||
lazy_context.infer()
|
lazy_context.infer()
|
||||||
for lazy_context in cls_or_tup.py__iter__()
|
for lazy_context in cls_or_tup.iterate()
|
||||||
)
|
)
|
||||||
bool_results.add(any(cls in mro for cls in classes))
|
bool_results.add(any(cls in mro for cls in classes))
|
||||||
else:
|
else:
|
||||||
|
|||||||
@@ -243,8 +243,7 @@ def _eval_expr_stmt(context, stmt, seek_name=None):
|
|||||||
# predictable. Also only do it, if the variable is not a tuple.
|
# predictable. Also only do it, if the variable is not a tuple.
|
||||||
node = for_stmt.get_testlist()
|
node = for_stmt.get_testlist()
|
||||||
cn = ContextualizedNode(context, node)
|
cn = ContextualizedNode(context, node)
|
||||||
from jedi.evaluate import iterable
|
ordered = list(cn.infer().iterate(cn))
|
||||||
ordered = list(iterable.py__iter__(context.evaluator, cn.infer(), cn))
|
|
||||||
|
|
||||||
for lazy_context in ordered:
|
for lazy_context in ordered:
|
||||||
dct = {for_stmt.children[1].value: lazy_context.infer()}
|
dct = {for_stmt.children[1].value: lazy_context.infer()}
|
||||||
@@ -551,8 +550,7 @@ def check_tuple_assignments(evaluator, contextualized_name, context_set):
|
|||||||
lazy_context = None
|
lazy_context = None
|
||||||
for index, node in contextualized_name.assignment_indexes():
|
for index, node in contextualized_name.assignment_indexes():
|
||||||
cn = ContextualizedNode(contextualized_name.context, node)
|
cn = ContextualizedNode(contextualized_name.context, node)
|
||||||
from jedi.evaluate import iterable
|
iterated = context_set.iterate(cn)
|
||||||
iterated = iterable.py__iter__(evaluator, context_set, cn)
|
|
||||||
for _ in range(index + 1):
|
for _ in range(index + 1):
|
||||||
try:
|
try:
|
||||||
lazy_context = next(iterated)
|
lazy_context = next(iterated)
|
||||||
|
|||||||
@@ -120,10 +120,9 @@ def _paths_from_assignment(module_context, expr_stmt):
|
|||||||
except AssertionError:
|
except AssertionError:
|
||||||
continue
|
continue
|
||||||
|
|
||||||
from jedi.evaluate.iterable import py__iter__
|
|
||||||
from jedi.evaluate.syntax_tree import is_string
|
from jedi.evaluate.syntax_tree import is_string
|
||||||
cn = ContextualizedNode(module_context.create_context(expr_stmt), expr_stmt)
|
cn = ContextualizedNode(module_context.create_context(expr_stmt), expr_stmt)
|
||||||
for lazy_context in py__iter__(module_context.evaluator, cn.infer(), cn):
|
for lazy_context in cn.infer().iterate(cn):
|
||||||
for context in lazy_context.infer():
|
for context in lazy_context.infer():
|
||||||
if is_string(context):
|
if is_string(context):
|
||||||
yield context.obj
|
yield context.obj
|
||||||
|
|||||||
Reference in New Issue
Block a user