forked from VimPlug/jedi
Changes for 3.8: sync_comp_for instead of comp_for
Please also look at the changes for parso in its b5d50392a4058919c0018666cdfc8c3eaaea9cb5 commit
This commit is contained in:
@@ -410,12 +410,12 @@ class Evaluator(object):
|
|||||||
if parser_utils.is_scope(node):
|
if parser_utils.is_scope(node):
|
||||||
return node
|
return node
|
||||||
elif node.type in ('argument', 'testlist_comp'):
|
elif node.type in ('argument', 'testlist_comp'):
|
||||||
if node.children[1].type == 'comp_for':
|
if node.children[1].type in ('comp_for', 'sync_comp_for'):
|
||||||
return node.children[1]
|
return node.children[1]
|
||||||
elif node.type == 'dictorsetmaker':
|
elif node.type == 'dictorsetmaker':
|
||||||
for n in node.children[1:4]:
|
for n in node.children[1:4]:
|
||||||
# In dictionaries it can be pretty much anything.
|
# In dictionaries it can be pretty much anything.
|
||||||
if n.type == 'comp_for':
|
if n.type in ('comp_for', 'sync_comp_for'):
|
||||||
return n
|
return n
|
||||||
|
|
||||||
def from_scope_node(scope_node, is_nested=True, node_is_object=False):
|
def from_scope_node(scope_node, is_nested=True, node_is_object=False):
|
||||||
@@ -441,7 +441,7 @@ class Evaluator(object):
|
|||||||
return func
|
return func
|
||||||
elif scope_node.type == 'classdef':
|
elif scope_node.type == 'classdef':
|
||||||
return ClassContext(self, parent_context, scope_node)
|
return ClassContext(self, parent_context, scope_node)
|
||||||
elif scope_node.type == 'comp_for':
|
elif scope_node.type in ('comp_for', 'sync_comp_for'):
|
||||||
if node.start_pos >= scope_node.children[-1].start_pos:
|
if node.start_pos >= scope_node.children[-1].start_pos:
|
||||||
return parent_context
|
return parent_context
|
||||||
return CompForContext.from_comp_for(parent_context, scope_node)
|
return CompForContext.from_comp_for(parent_context, scope_node)
|
||||||
|
|||||||
@@ -233,10 +233,13 @@ class TreeArguments(AbstractArguments):
|
|||||||
named_args.append((c[0].value, LazyTreeContext(self.context, c[2]),))
|
named_args.append((c[0].value, LazyTreeContext(self.context, c[2]),))
|
||||||
else: # Generator comprehension.
|
else: # Generator comprehension.
|
||||||
# Include the brackets with the parent.
|
# Include the brackets with the parent.
|
||||||
|
sync_comp_for = el.children[1]
|
||||||
|
if sync_comp_for.type == 'comp_for':
|
||||||
|
sync_comp_for = sync_comp_for.children[1]
|
||||||
comp = iterable.GeneratorComprehension(
|
comp = iterable.GeneratorComprehension(
|
||||||
self._evaluator,
|
self._evaluator,
|
||||||
defining_context=self.context,
|
defining_context=self.context,
|
||||||
comp_for_node=el.children[1],
|
sync_comp_for_node=sync_comp_for,
|
||||||
entry_node=el.children[0],
|
entry_node=el.children[0],
|
||||||
)
|
)
|
||||||
yield None, LazyKnownContext(comp)
|
yield None, LazyKnownContext(comp)
|
||||||
|
|||||||
@@ -8,7 +8,7 @@ just one.
|
|||||||
"""
|
"""
|
||||||
from functools import reduce
|
from functools import reduce
|
||||||
from operator import add
|
from operator import add
|
||||||
from parso.python.tree import ExprStmt, CompFor
|
from parso.python.tree import ExprStmt, SyncCompFor
|
||||||
|
|
||||||
from jedi import debug
|
from jedi import debug
|
||||||
from jedi._compatibility import zip_longest, unicode
|
from jedi._compatibility import zip_longest, unicode
|
||||||
@@ -330,7 +330,7 @@ class ContextualizedName(ContextualizedNode):
|
|||||||
is_star_expr = False
|
is_star_expr = False
|
||||||
elif node.type == 'star_expr':
|
elif node.type == 'star_expr':
|
||||||
is_star_expr = True
|
is_star_expr = True
|
||||||
elif isinstance(node, (ExprStmt, CompFor)):
|
elif isinstance(node, (ExprStmt, SyncCompFor)):
|
||||||
break
|
break
|
||||||
|
|
||||||
compare = node
|
compare = node
|
||||||
|
|||||||
@@ -215,7 +215,7 @@ class AbstractInstanceContext(Context):
|
|||||||
elif scope.type == 'classdef':
|
elif scope.type == 'classdef':
|
||||||
class_context = ClassContext(self.evaluator, parent_context, scope)
|
class_context = ClassContext(self.evaluator, parent_context, scope)
|
||||||
return class_context
|
return class_context
|
||||||
elif scope.type == 'comp_for':
|
elif scope.type in ('comp_for', 'sync_comp_for'):
|
||||||
# Comprehensions currently don't have a special scope in Jedi.
|
# Comprehensions currently don't have a special scope in Jedi.
|
||||||
return self.create_instance_context(class_context, scope)
|
return self.create_instance_context(class_context, scope)
|
||||||
else:
|
else:
|
||||||
|
|||||||
@@ -38,7 +38,7 @@ from jedi.evaluate.filters import ParserTreeFilter, LazyAttributeOverwrite, \
|
|||||||
publish_method
|
publish_method
|
||||||
from jedi.evaluate.base_context import ContextSet, NO_CONTEXTS, \
|
from jedi.evaluate.base_context import ContextSet, NO_CONTEXTS, \
|
||||||
TreeContext, ContextualizedNode, iterate_contexts, HelperContextMixin
|
TreeContext, ContextualizedNode, iterate_contexts, HelperContextMixin
|
||||||
from jedi.parser_utils import get_comp_fors
|
from jedi.parser_utils import get_sync_comp_fors
|
||||||
|
|
||||||
|
|
||||||
class IterableMixin(object):
|
class IterableMixin(object):
|
||||||
@@ -107,12 +107,17 @@ class CompForContext(TreeContext):
|
|||||||
def comprehension_from_atom(evaluator, context, atom):
|
def comprehension_from_atom(evaluator, context, atom):
|
||||||
bracket = atom.children[0]
|
bracket = atom.children[0]
|
||||||
test_list_comp = atom.children[1]
|
test_list_comp = atom.children[1]
|
||||||
|
|
||||||
if bracket == '{':
|
if bracket == '{':
|
||||||
if atom.children[1].children[1] == ':':
|
if atom.children[1].children[1] == ':':
|
||||||
|
sync_comp_for = test_list_comp.children[3]
|
||||||
|
if sync_comp_for.type == 'comp_for':
|
||||||
|
sync_comp_for = sync_comp_for.children[1]
|
||||||
|
|
||||||
return DictComprehension(
|
return DictComprehension(
|
||||||
evaluator,
|
evaluator,
|
||||||
context,
|
context,
|
||||||
comp_for_node=test_list_comp.children[3],
|
sync_comp_for_node=sync_comp_for,
|
||||||
key_node=test_list_comp.children[0],
|
key_node=test_list_comp.children[0],
|
||||||
value_node=test_list_comp.children[2],
|
value_node=test_list_comp.children[2],
|
||||||
)
|
)
|
||||||
@@ -122,10 +127,15 @@ def comprehension_from_atom(evaluator, context, atom):
|
|||||||
cls = GeneratorComprehension
|
cls = GeneratorComprehension
|
||||||
elif bracket == '[':
|
elif bracket == '[':
|
||||||
cls = ListComprehension
|
cls = ListComprehension
|
||||||
|
|
||||||
|
sync_comp_for = test_list_comp.children[1]
|
||||||
|
if sync_comp_for.type == 'comp_for':
|
||||||
|
sync_comp_for = sync_comp_for.children[1]
|
||||||
|
|
||||||
return cls(
|
return cls(
|
||||||
evaluator,
|
evaluator,
|
||||||
defining_context=context,
|
defining_context=context,
|
||||||
comp_for_node=test_list_comp.children[1],
|
sync_comp_for_node=sync_comp_for,
|
||||||
entry_node=test_list_comp.children[0],
|
entry_node=test_list_comp.children[0],
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -138,16 +148,16 @@ class ComprehensionMixin(object):
|
|||||||
def _nested(self, comp_fors, parent_context=None):
|
def _nested(self, comp_fors, parent_context=None):
|
||||||
comp_for = comp_fors[0]
|
comp_for = comp_fors[0]
|
||||||
|
|
||||||
is_async = 'async' == comp_for.children[comp_for.children.index('for') - 1]
|
is_async = comp_for.parent.type == 'comp_for'
|
||||||
|
|
||||||
input_node = comp_for.children[comp_for.children.index('in') + 1]
|
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)
|
||||||
# TODO: simulate await if self.is_async
|
# TODO: simulate await if self.is_async
|
||||||
|
|
||||||
cn = ContextualizedNode(parent_context, input_node)
|
cn = ContextualizedNode(parent_context, input_node)
|
||||||
iterated = input_types.iterate(cn, is_async=is_async)
|
iterated = input_types.iterate(cn, is_async=is_async)
|
||||||
exprlist = comp_for.children[comp_for.children.index('for') + 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()
|
||||||
dct = unpack_tuple_to_dict(parent_context, types, exprlist)
|
dct = unpack_tuple_to_dict(parent_context, types, exprlist)
|
||||||
@@ -169,7 +179,7 @@ class ComprehensionMixin(object):
|
|||||||
@evaluator_method_cache(default=[])
|
@evaluator_method_cache(default=[])
|
||||||
@to_list
|
@to_list
|
||||||
def _iterate(self):
|
def _iterate(self):
|
||||||
comp_fors = tuple(get_comp_fors(self._comp_for_node))
|
comp_fors = tuple(get_sync_comp_fors(self._sync_comp_for_node))
|
||||||
for result in self._nested(comp_fors):
|
for result in self._nested(comp_fors):
|
||||||
yield result
|
yield result
|
||||||
|
|
||||||
@@ -178,7 +188,7 @@ class ComprehensionMixin(object):
|
|||||||
yield LazyKnownContexts(set_)
|
yield LazyKnownContexts(set_)
|
||||||
|
|
||||||
def __repr__(self):
|
def __repr__(self):
|
||||||
return "<%s of %s>" % (type(self).__name__, self._comp_for_node)
|
return "<%s of %s>" % (type(self).__name__, self._sync_comp_for_node)
|
||||||
|
|
||||||
|
|
||||||
class _DictMixin(object):
|
class _DictMixin(object):
|
||||||
@@ -219,10 +229,11 @@ class Sequence(LazyAttributeOverwrite, IterableMixin):
|
|||||||
|
|
||||||
|
|
||||||
class _BaseComprehension(ComprehensionMixin):
|
class _BaseComprehension(ComprehensionMixin):
|
||||||
def __init__(self, evaluator, defining_context, comp_for_node, entry_node):
|
def __init__(self, evaluator, defining_context, sync_comp_for_node, entry_node):
|
||||||
|
assert sync_comp_for_node.type == 'sync_comp_for'
|
||||||
super(_BaseComprehension, self).__init__(evaluator)
|
super(_BaseComprehension, self).__init__(evaluator)
|
||||||
self._defining_context = defining_context
|
self._defining_context = defining_context
|
||||||
self._comp_for_node = comp_for_node
|
self._sync_comp_for_node = sync_comp_for_node
|
||||||
self._entry_node = entry_node
|
self._entry_node = entry_node
|
||||||
|
|
||||||
|
|
||||||
@@ -250,10 +261,11 @@ class GeneratorComprehension(_BaseComprehension, GeneratorBase):
|
|||||||
class DictComprehension(ComprehensionMixin, Sequence):
|
class DictComprehension(ComprehensionMixin, Sequence):
|
||||||
array_type = u'dict'
|
array_type = u'dict'
|
||||||
|
|
||||||
def __init__(self, evaluator, defining_context, comp_for_node, key_node, value_node):
|
def __init__(self, evaluator, defining_context, sync_comp_for_node, key_node, value_node):
|
||||||
|
assert sync_comp_for_node.type == 'sync_comp_for'
|
||||||
super(DictComprehension, self).__init__(evaluator)
|
super(DictComprehension, self).__init__(evaluator)
|
||||||
self._defining_context = defining_context
|
self._defining_context = defining_context
|
||||||
self._comp_for_node = comp_for_node
|
self._sync_comp_for_node = sync_comp_for_node
|
||||||
self._entry_node = key_node
|
self._entry_node = key_node
|
||||||
self._value_node = value_node
|
self._value_node = value_node
|
||||||
|
|
||||||
|
|||||||
@@ -134,11 +134,12 @@ class NameFinder(object):
|
|||||||
``filters``), until a name fits.
|
``filters``), until a name fits.
|
||||||
"""
|
"""
|
||||||
names = []
|
names = []
|
||||||
|
# TODO why is this paragraph needed?
|
||||||
if self._context.predefined_names and isinstance(self._name, tree.Name):
|
if self._context.predefined_names and isinstance(self._name, tree.Name):
|
||||||
node = self._name
|
node = self._name
|
||||||
while node is not None and not is_scope(node):
|
while node is not None and not is_scope(node):
|
||||||
node = node.parent
|
node = node.parent
|
||||||
if node.type in ("if_stmt", "for_stmt", "comp_for"):
|
if node.type in ("if_stmt", "for_stmt", "comp_for", 'sync_comp_for'):
|
||||||
try:
|
try:
|
||||||
name_dict = self._context.predefined_names[node]
|
name_dict = self._context.predefined_names[node]
|
||||||
types = name_dict[self._string_name]
|
types = name_dict[self._string_name]
|
||||||
@@ -199,7 +200,7 @@ class NameFinder(object):
|
|||||||
flow_scope = self._name
|
flow_scope = self._name
|
||||||
base_nodes = [self._name_context.tree_node]
|
base_nodes = [self._name_context.tree_node]
|
||||||
|
|
||||||
if any(b.type == 'comp_for' for b in base_nodes):
|
if any(b.type in ('comp_for', 'sync_comp_for') for b in base_nodes):
|
||||||
return contexts
|
return contexts
|
||||||
while True:
|
while True:
|
||||||
flow_scope = get_parent_scope(flow_scope, include_flows=True)
|
flow_scope = get_parent_scope(flow_scope, include_flows=True)
|
||||||
|
|||||||
@@ -247,7 +247,7 @@ def eval_atom(context, atom):
|
|||||||
except IndexError:
|
except IndexError:
|
||||||
pass
|
pass
|
||||||
|
|
||||||
if comp_for.type == 'comp_for':
|
if comp_for.type in ('comp_for', 'sync_comp_for'):
|
||||||
return ContextSet([iterable.comprehension_from_atom(
|
return ContextSet([iterable.comprehension_from_atom(
|
||||||
context.evaluator, context, atom
|
context.evaluator, context, atom
|
||||||
)])
|
)])
|
||||||
@@ -588,7 +588,7 @@ def tree_name_to_contexts(evaluator, context, tree_name):
|
|||||||
if types:
|
if types:
|
||||||
return types
|
return types
|
||||||
|
|
||||||
if typ in ('for_stmt', 'comp_for'):
|
if typ in ('for_stmt', 'comp_for', 'sync_comp_for'):
|
||||||
try:
|
try:
|
||||||
types = context.predefined_names[node][tree_name.value]
|
types = context.predefined_names[node][tree_name.value]
|
||||||
except KeyError:
|
except KeyError:
|
||||||
|
|||||||
@@ -54,11 +54,13 @@ def get_executable_nodes(node, last_added=False):
|
|||||||
return result
|
return result
|
||||||
|
|
||||||
|
|
||||||
def get_comp_fors(comp_for):
|
def get_sync_comp_fors(comp_for):
|
||||||
yield comp_for
|
yield comp_for
|
||||||
last = comp_for.children[-1]
|
last = comp_for.children[-1]
|
||||||
while True:
|
while True:
|
||||||
if last.type == 'comp_for':
|
if last.type == 'comp_for':
|
||||||
|
yield last.children[1] # Ignore the async.
|
||||||
|
elif last.type == 'sync_comp_for':
|
||||||
yield last
|
yield last
|
||||||
elif not last.type == 'comp_if':
|
elif not last.type == 'comp_if':
|
||||||
break
|
break
|
||||||
@@ -216,7 +218,12 @@ def get_following_comment_same_line(node):
|
|||||||
|
|
||||||
|
|
||||||
def is_scope(node):
|
def is_scope(node):
|
||||||
return node.type in ('file_input', 'classdef', 'funcdef', 'lambdef', 'comp_for')
|
t = node.type
|
||||||
|
if t == 'comp_for':
|
||||||
|
# Starting with Python 3.8, async is outside of the statement.
|
||||||
|
return node.children[1].type != 'sync_comp_for'
|
||||||
|
|
||||||
|
return t in ('file_input', 'classdef', 'funcdef', 'lambdef', 'sync_comp_for')
|
||||||
|
|
||||||
|
|
||||||
def get_parent_scope(node, include_flows=False):
|
def get_parent_scope(node, include_flows=False):
|
||||||
|
|||||||
Reference in New Issue
Block a user