我们从Python开源项目中,提取了以下10个代码示例,用于说明如何使用ast.GeneratorExp()。
def _get_offsets(func_ast): for arg in func_ast.args: start_line, start_col = arg.lineno - 2, arg.col_offset - 1 # horrible hack for http://bugs.python.org/issue31241 if isinstance(arg, (ast.ListComp, ast.GeneratorExp)): start_col -= 1 yield start_line, start_col for kw in func_ast.keywords: yield kw.value.lineno - 2, kw.value.col_offset - len(kw.arg) - 2
def visit_Call(self, node): if ( isinstance(node.func, ast.Name) and node.func.id == 'dict' and len(node.args) == 1 and not _has_kwargs(node) and isinstance(node.args[0], (ast.ListComp, ast.GeneratorExp)) and isinstance(node.args[0].elt, (ast.Tuple, ast.List)) and len(node.args[0].elt.elts) == 2 ): arg, = node.args key = Offset(node.func.lineno, node.func.col_offset) self.dicts[key] = arg self.generic_visit(node)
def visit_GeneratorExp(self, node): # type: (ast.GeneratorExp) -> None # Generator expressions are an interesting case. # They create a new sub scope, but they're not # explicitly named. Python just creates a table # with the name "genexpr". self._handle_comprehension(node, 'genexpr')
def visit_Call(self, node): argnodes = node.args + node.keywords py2_starargs = getattr(node, 'starargs', None) if py2_starargs: # pragma: no cover (<PY35) argnodes.append(py2_starargs) py2_kwargs = getattr(node, 'kwargs', None) if py2_kwargs: # pragma: no cover (<PY35) argnodes.append(py2_kwargs) arg_offsets = set() has_starargs = bool(py2_starargs or py2_kwargs) for argnode in argnodes: if ( _is_star_arg(argnode) or _is_star_star_kwarg(argnode) ): # pragma: no cover (PY35+) has_starargs = True offset = _to_offset(argnode) # multiline strings have invalid position, ignore them if offset.utf8_byte_offset != -1: # pragma: no branch (cpy bug) arg_offsets.add(offset) # If the sole argument is a generator, don't add a trailing comma as # this breaks lib2to3 based tools only_a_generator = ( len(argnodes) == 1 and isinstance(argnodes[0], ast.GeneratorExp) ) if arg_offsets and not only_a_generator: key = Offset(node.lineno, node.col_offset) self.calls[key].append(Call(node, has_starargs, arg_offsets)) self.generic_visit(node)
def test_generatorexp(self): self._simple_comp(ast.GeneratorExp)
def checkCompare(self, compare, modelName = None, script = None): """Check an AST Compare node - iterate for Attribute nodes and match against modelName argument. Recurse for script's model defs.""" if modelName is None and script is None: return if modelName is not None: valueCallArgs = [] generatorExps = [] for node in ast.walk(compare): if isinstance(node, ast.Attribute): if isinstance(node.value, ast.Name): if node.value.id == modelName: wrapped = self.checkWrapped(node, valueCallArgs, generatorExps) if not wrapped: self.problem("Comparison on attribute {0}.{1} not wrapped in value()".format(modelName, node.attr), lineno=compare.lineno) elif isinstance(node, ast.Call): if isinstance(node.func, ast.Name): if node.func.id == 'value': valueCallArgs.append(node.args) elif isinstance(node, ast.GeneratorExp): generatorExps.append(node) if script is not None: for name in script.modelVars: self.checkCompare(compare, modelName = name)
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 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)