我们从Python开源项目中,提取了以下50个代码示例,用于说明如何使用_ast.AST。
def generate2(): """ Call an external Python 2 program to retrieve the AST symbols of that language version :return: """ import subprocess as sp import tempfile, shutil, sys, traceback tempdir = tempfile.mkdtemp() tempfile = os.path.join(tempdir, "py2_ast_code.py") py2_proc_out = "" try: with open(tempfile, 'w') as py2code: py2code.write(generate_str + WRITESYMS_CODE) py2_proc_out = sp.check_output(["python2", tempfile]).decode() finally: try: shutil.rmtree(tempdir) except: print("Warning: error trying to delete the temporal directory:", file=sys.stderr) print(traceback.format_exc(), file=sys.stderr) return set(py2_proc_out.splitlines())
def get_statement_startend2(lineno, node): import ast # flatten all statements and except handlers into one lineno-list # AST's line numbers start indexing at 1 l = [] for x in ast.walk(node): if isinstance(x, _ast.stmt) or isinstance(x, _ast.ExceptHandler): l.append(x.lineno - 1) for name in "finalbody", "orelse": val = getattr(x, name, None) if val: # treat the finally/orelse part as its own statement l.append(val[0].lineno - 1 - 1) l.sort() insert_index = bisect_right(l, lineno) start = l[insert_index - 1] if insert_index >= len(l): end = None else: end = l[insert_index] return start, end
def test_pythontypes(self): # check all types defined in Python/ h = self.header vh = self.vheader size = self.calcsize check = self.check_sizeof # _ast.AST import _ast check(_ast.AST(), size(h + '')) # imp.NullImporter import imp check(imp.NullImporter(self.file.name), size(h + '')) try: raise TypeError except TypeError: tb = sys.exc_info()[2] # traceback if tb != None: check(tb, size(h + '2P2i')) # symtable entry # XXX # sys.flags check(sys.flags, size(vh) + self.P * len(sys.flags))
def test_pythontypes(self): # check all types defined in Python/ size = test.support.calcobjsize vsize = test.support.calcvobjsize check = self.check_sizeof # _ast.AST import _ast check(_ast.AST(), size('P')) try: raise TypeError except TypeError: tb = sys.exc_info()[2] # traceback if tb is not None: check(tb, size('2P2i')) # symtable entry # XXX # sys.flags check(sys.flags, vsize('') + self.P * len(sys.flags))
def test_pythontypes(self): # check all types defined in Python/ size = test.test_support.calcobjsize vsize = test.test_support.calcvobjsize check = self.check_sizeof # _ast.AST import _ast check(_ast.AST(), size('')) # imp.NullImporter import imp check(imp.NullImporter(self.file.name), size('')) try: raise TypeError except TypeError: tb = sys.exc_info()[2] # traceback if tb != None: check(tb, size('2P2i')) # symtable entry # XXX # sys.flags check(sys.flags, vsize('') + self.P * len(sys.flags))
def visitDefault(self, node): for field in node._fields: value = getattr(node, field) if value == self.old: setattr(node, field, self.new) if isinstance(value, (list, tuple)): for i, item in enumerate(value): if item == self.old: value[i] = self.new elif isinstance(item, _ast.AST): self.visit(item) else: pass elif isinstance(value, _ast.AST): self.visit(value) else: pass return
def visitDefault(self, node): for field in node._fields: value = getattr(node, field) if value in self.to_remove: setattr(node, field, self.new) if isinstance(value, (list, tuple)): for i, item in enumerate(value): if item == self.old: value[i] = self.new elif isinstance(item, _ast.AST): self.visit(item) else: pass elif isinstance(value, _ast.AST): self.visit(value) else: pass return
def mutateDefault(self, node): for field in node._fields: value = getattr(node, field) if isinstance(value, (list, tuple)): for i, item in enumerate(value): if isinstance(item, _ast.AST): new_item = self.mutate(item) if new_item is not None: value[i] = new_item else: pass elif isinstance(value, _ast.AST): new_value = self.mutate(value) if new_value is not None: setattr(node, field, new_value) return None
def get_ast_symbols(): return set() # This is defined as an str so we can also pass it to the Python2 interpreter # to get Python2's AST symbols
def generate23(outpath): allsyms = list( generate2().union(generate3()) ) # add the types that we add to improve the raw AST information allsyms.extend(["StringLiteral", "NoneLiteral", "NumLiteral", "ByteLiteral", "BoolLiteral", "PreviousNoops", "NoopLine", "SameLineNoops", "RemainderNoops", "noop_line"]) allsyms.sort() maxlen = max((len(i) for i in allsyms)) decl_list = ['\t{symbol:<{maxlen}} = "{symbol}"'.format(symbol=i, maxlen=maxlen) for i in allsyms] symlist_str = '\n'.join(decl_list) final_content = CONTENT.format(constants=symlist_str).lstrip() with open(outpath, 'w') as destfile: print(final_content, file=destfile)
def compile_(source, filename=None, mode='exec', flags= generators.compiler_flag, dont_inherit=0): """ compile the given source to a raw code object, and maintain an internal cache which allows later retrieval of the source code for the code object and any recursively created code objects. """ if _ast is not None and isinstance(source, _ast.AST): # XXX should Source support having AST? return cpy_compile(source, filename, mode, flags, dont_inherit) _genframe = sys._getframe(1) # the caller s = Source(source) co = s.compile(filename, mode, flags, _genframe=_genframe) return co
def getstatementrange_ast(lineno, source, assertion=False, astnode=None): if astnode is None: content = str(source) if sys.version_info < (2,7): content += "\n" try: astnode = compile(content, "source", "exec", 1024) # 1024 for AST except ValueError: start, end = getstatementrange_old(lineno, source, assertion) return None, start, end start, end = get_statement_startend2(lineno, astnode) # we need to correct the end: # - ast-parsing strips comments # - there might be empty lines # - we might have lesser indented code blocks at the end if end is None: end = len(source.lines) if end > start + 1: # make sure we don't span differently indented code blocks # by using the BlockFinder helper used which inspect.getsource() uses itself block_finder = inspect.BlockFinder() # if we start with an indented line, put blockfinder to "started" mode block_finder.started = source.lines[start][0].isspace() it = ((x + "\n") for x in source.lines[start:end]) try: for tok in tokenize.generate_tokens(lambda: next(it)): block_finder.tokeneater(*tok) except (inspect.EndOfBlock, IndentationError): end = block_finder.last + start except Exception: pass # the end might still point to a comment or empty line, correct it while end: line = source.lines[end - 1].lstrip() if line.startswith("#") or not line: end -= 1 else: break return astnode, start, end
def test_pythontypes(self): # check all types defined in Python/ size = test.test_support.calcobjsize vsize = test.test_support.calcvobjsize check = self.check_sizeof # _ast.AST import _ast check(_ast.AST(), size('')) # imp.NullImporter import imp f = open(test.test_support.TESTFN, 'wb') try: check(imp.NullImporter(f.name), size('')) finally: f.close() test.test_support.unlink(test.test_support.TESTFN) try: raise TypeError except TypeError: tb = sys.exc_info()[2] # traceback if tb != None: check(tb, size('2P2i')) # symtable entry # XXX # sys.flags check(sys.flags, vsize('') + self.P * len(sys.flags))
def iter_child_nodes(node, omit=None, _fields_order=_FieldsOrder()): """ Yield all direct child nodes of *node*, that is, all fields that are nodes and all items of fields that are lists of nodes. """ for name in _fields_order[node.__class__]: if name == omit: continue field = getattr(node, name, None) if isinstance(field, ast.AST): yield field elif isinstance(field, list): for item in field: yield item
def get_child_nodes(node): if isinstance(node, _ast.Module): return node.body result = [] if node._fields is not None: for name in node._fields: child = getattr(node, name) if isinstance(child, list): for entry in child: if isinstance(entry, _ast.AST): result.append(entry) if isinstance(child, _ast.AST): result.append(child) return result
def getstatementrange_ast(lineno, source, assertion=False, astnode=None): if astnode is None: content = str(source) try: astnode = compile(content, "source", "exec", 1024) # 1024 for AST except ValueError: start, end = getstatementrange_old(lineno, source, assertion) return None, start, end start, end = get_statement_startend2(lineno, astnode) # we need to correct the end: # - ast-parsing strips comments # - there might be empty lines # - we might have lesser indented code blocks at the end if end is None: end = len(source.lines) if end > start + 1: # make sure we don't span differently indented code blocks # by using the BlockFinder helper used which inspect.getsource() uses itself block_finder = inspect.BlockFinder() # if we start with an indented line, put blockfinder to "started" mode block_finder.started = source.lines[start][0].isspace() it = ((x + "\n") for x in source.lines[start:end]) try: for tok in tokenize.generate_tokens(lambda: next(it)): block_finder.tokeneater(*tok) except (inspect.EndOfBlock, IndentationError): end = block_finder.last + start except Exception: pass # the end might still point to a comment or empty line, correct it while end: line = source.lines[end - 1].lstrip() if line.startswith("#") or not line: end -= 1 else: break return astnode, start, end
def flatten(node): result = [] if isinstance(node, _ast.AST): for value in ast_values(node): result.extend(flatten(value)) elif isinstance(node, (list, tuple)): for child in node: result.extend(flatten(child)) else: result.append(node) return result