def peval_comprehension(state, node, ctx):
accum_cls = {
ast.ListComp: ListAccumulator,
ast.GeneratorExp: GeneratorExpAccumulator,
ast.SetComp: SetAccumulator,
ast.DictComp: DictAccumulator,
}
# variables from generators temporary mask bindings
target_names = set()
for generator in node.generators:
if type(generator.target) == ast.Name:
target_names.add(generator.target.id)
else:
target_names.update([elt.id for elt in generator.target.elts])
# pre-evaluate the expression
elt_bindings = dict(ctx.bindings)
for name in target_names:
if name in elt_bindings:
del elt_bindings[name]
elt_ctx = ctx.update(bindings=elt_bindings)
if type(node) == ast.DictComp:
elt = ast.Tuple(elts=[node.key, node.value])
else:
elt = node.elt
state, new_elt = _peval_expression(state, elt, elt_ctx)
try:
state, container = _peval_comprehension(
state, accum_cls[type(node)], new_elt, node.generators, ctx)
evaluated = True
except CannotEvaluateComprehension:
evaluated = False
if evaluated:
return state, KnownValue(value=container)
else:
state, new_elt = map_reify(state, new_elt)
state, new_generators = _peval_comprehension_generators(state, node.generators, ctx)
if type(node) == ast.DictComp:
key, value = new_elt.elts
return state, replace_fields(node, key=key, value=value, generators=new_generators)
else:
return state, replace_fields(node, elt=new_elt, generators=new_generators)
评论列表
文章目录