我们从Python开源项目中,提取了以下9个代码示例,用于说明如何使用ast.DictComp()。
def _collect_comprehension_children(self, node): # type: (ComprehensionNode) -> List[ast.expr] if isinstance(node, ast.DictComp): # dict comprehensions have two values to be checked child_nodes = [node.key, node.value] else: child_nodes = [node.elt] if node.generators: first_generator = node.generators[0] child_nodes.append(first_generator.target) for if_expr in first_generator.ifs: child_nodes.append(if_expr) for generator in node.generators[1:]: # rest need to be visited in the child scope child_nodes.append(generator.iter) child_nodes.append(generator.target) for if_expr in generator.ifs: child_nodes.append(if_expr) return child_nodes
def visit_DictComp(self, node): # type: (ast.DictComp) -> None self._handle_comprehension(node, 'dictcomp')
def test_dictcomp(self): g = ast.comprehension(ast.Name("y", ast.Store()), ast.Name("p", ast.Load()), []) c = ast.DictComp(ast.Name("x", ast.Store()), ast.Name("y", ast.Load()), [g]) self.expr(c, "must have Load context") c = ast.DictComp(ast.Name("x", ast.Load()), ast.Name("y", ast.Store()), [g]) self.expr(c, "must have Load context") def factory(comps): k = ast.Name("x", ast.Load()) v = ast.Name("y", ast.Load()) return ast.DictComp(k, v, comps) self._check_comprehension(factory)
def resolve_attr_id(node): if isinstance(node, (ast.Attribute, ast.Subscript)): value_id = None if isinstance(node.value, (ast.Name, ast.Attribute, ast.Subscript)): value_id = resolve_attr_id(node.value) elif isinstance(node.value, ast.Call): value_id = resolve_attr_id(node.value) elif isinstance(node.value, ast.Str): value_id = 'str' elif isinstance(node.value, ast.Bytes): value_id = 'bytes' elif isinstance(node.value, (ast.List, ast.ListComp)): value_id = 'list' elif isinstance(node.value, ast.Tuple): value_id = 'tuple' elif isinstance(node.value, (ast.Set, ast.SetComp)): value_id = 'set' elif isinstance(node.value, (ast.Dict, ast.DictComp)): value_id = 'dict' else: raise SyntaxError( 'unsupport type: {}'.format(ast.dump(node.value)) ) if isinstance(node, ast.Attribute): return '{}.{}'.format(value_id, node.attr) elif isinstance(node, ast.Subscript): slice = None if isinstance(node.slice.value, ast.Str): slice = node.slice.value.s elif isinstance(node.slice.value, ast.Num): slice = node.slice.value.n elif isinstance(node.slice.value, ast.Name): slice = resolve_attr_id(node.slice.value) return '{}[{}]'.format(value_id, slice) elif isinstance(node, ast.Call): return '{}()'.format(resolve_attr_id(node.func)) return node.id
def node_defines_name(node, name): """ Check if the specified statement node defines symbol *name*. :param node: The node to check. :param name: The symbol name to check. :return: Whether or not the node defines the symbole specified. :rtype: bool """ if isinstance(name, ast.Name): name = name.id if isinstance(node, ast.Assign): if node_targets_name(node, name): return True if isinstance(node.value, (ast.DictComp, ast.ListComp, ast.SetComp)): return node_defines_name(node.value, name) elif isinstance(node, ast.ClassDef): return node.name == name # these ones all assume the iterable will be executed at least once elif isinstance(node, (ast.DictComp, ast.GeneratorExp, ast.ListComp, ast.SetComp)): for generator in node.generators: target = generator.target if isinstance(target, ast.Name): if target.id == name: return True continue for child_node in iter_child_expr_nodes(target): if isinstance(child_node, ast.Name) and child_node.id == name: return True return False elif isinstance(node, ast.ExceptHandler): if isinstance(node.name, ast.Name): return node.name.id == name elif isinstance(node.name, str): return node.name == name elif isinstance(node, ast.Expr): if isinstance(node.value, (ast.DictComp, ast.GeneratorExp, ast.ListComp, ast.SetComp)): return node_defines_name(node.value, name) elif isinstance(node, ast.For): return isinstance(node.target, ast.Name) and node.target.id == name elif isinstance(node, ast.FunctionDef): return node.name == name elif isinstance(node, (ast.Import, ast.ImportFrom)): return next((alias for alias in node.names if (alias.asname or alias.name) == name), None) is not None return False
def infer(node, context, solver, from_call=False): """Infer the type of a given AST node""" if isinstance(node, ast.Num): return infer_numeric(node, solver) elif isinstance(node, ast.Str): return solver.z3_types.string elif (sys.version_info[0] >= 3 and sys.version_info[1] >= 6 and (isinstance(node, ast.FormattedValue) or isinstance(node, ast.JoinedStr))): # Formatted strings were introduced in Python 3.6 return solver.z3_types.string elif isinstance(node, ast.Bytes): return solver.z3_types.bytes elif isinstance(node, ast.List): return infer_list(node, context, solver) elif isinstance(node, ast.Dict): return infer_dict(node, context, solver) elif isinstance(node, ast.Tuple): return infer_tuple(node, context, solver) elif isinstance(node, ast.NameConstant): return infer_name_constant(node, solver) elif isinstance(node, ast.Set): return infer_set(node, context, solver) elif isinstance(node, ast.BinOp): return infer_binary_operation(node, context, solver) elif isinstance(node, ast.BoolOp): return infer_boolean_operation(node, context, solver) elif isinstance(node, ast.UnaryOp): return infer_unary_operation(node, context, solver) elif isinstance(node, ast.IfExp): return infer_if_expression(node, context, solver) elif isinstance(node, ast.Subscript): return infer_subscript(node, context, solver) elif sys.version_info[0] >= 3 and sys.version_info[1] >= 5 and isinstance(node, ast.Await): # Await and Async were introduced in Python 3.5 return infer(node.value, context, solver) elif isinstance(node, ast.Yield): return infer(node.value, context, solver) elif isinstance(node, ast.Compare): return infer_compare(node, context, solver) elif isinstance(node, ast.Name): return infer_name(node, context) elif isinstance(node, ast.ListComp): return infer_sequence_comprehension(node, solver.z3_types.list, context, solver) elif isinstance(node, ast.SetComp): return infer_sequence_comprehension(node, solver.z3_types.set, context, solver) elif isinstance(node, ast.DictComp): return infer_dict_comprehension(node, context, solver) elif isinstance(node, ast.Call): return infer_func_call(node, context, solver) elif isinstance(node, ast.Attribute): return infer_attribute(node, context, from_call, solver) elif isinstance(node, ast.Lambda): return _infer_lambda(node, context, solver) raise NotImplementedError("Inference for expression {} is not implemented yet.".format(type(node).__name__))
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)