AST:如何使用我的转换器访问导入:typeError:stmt

时间:2019-06-14 11:32:58

标签: python-3.x abstract-syntax-tree

我希望我的nodeTransformer访问所有遵循某种语法的(仅)导入模块。

现在我正在捕获任何ImportFrom,由于使用了node.module属性来获取源代码,所以我打开了文件,并从源代码创建AST节点。每次阅读源代码时,我还会为每个节点添加该节点的父级:

    def getASTFromSources(f):

        print('currentdir ',os.getcwd())
        with open(f, "r") as source:
            #parentify the tree
            astTree=ast.parse(source.read())
            for node in ast.walk(astTree):
                for child in ast.iter_child_nodes(node):
                    child.parent = node
            return astTree

然后我调用以下函数,以替换导入语句:

def insertAfterNode( node, nodeToInsert):
        parent = node.parent
        index= parent.body.index(node)
        parent.body.insert(index+1, nodeToInsert)
        nodeToInsert.parent=parent
        ast.fix_missing_locations(parent)

VisitImport的完整代码:

    def visit_ImportFrom(self,node):
        if not node.module.startswith('transforms_'):
            return node

        path= getFilePathFromModuleName(node.module)
        astImport=SourceTransformer.getASTFromSources(path)

        SourceTransformer.insertAfterNode(node, astImport)

但是最后,无论是否在整个树上应用fix_missing_locations(),编译器都会抱怨:

code=compile(astTree, 'modifiedModule','exec')
TypeError: required field "lineno" missing from stmt

还请注意,我还尝试将importNode替换为源节点:

def visit_ImportFrom(self,node):
        if not node.module.startswith('transforms_'):
            print (node.module)
            return node



        path= getFilePathFromModuleName(node.module)
        astImport=SourceTransformer.getASTFromSources(path)

        return astImport
"""I also tried that
        return ast.copy_location(astImport, node)"""

奇怪的是,如果用astunparse转储我的最终ast结果:

        print (astunparse.unparse(astTree))

在文件中,我可以执行文件而没有任何问题。这意味着这确实是位置问题。现在,我将仅使用此变通方法(使用astunparse获取源字符串,而是对其进行编译),但这将添加另一层解析,如果有ast的熟练技术人员向我解释了为什么fix_missing_location无法修复丢失的位置,我显然更愿意这样做。 >

0 个答案:

没有答案