Remove type hints in Python source programmatically

后端 未结 3 817
孤城傲影
孤城傲影 2020-12-29 07:21

I have some source code written for Python 3.5 that I want to make executable under Python 3.4. The only feature from 3.5 that I use which is not available in 3.4 are type h

3条回答
  •  夕颜
    夕颜 (楼主)
    2020-12-29 08:15

    There are also type hints for local variables (which came from Python 3.6). I've modified @klamann 's code to remove them too. Also, I use astor (https://pypi.org/project/astor/) to generate code.

    import ast
    import astor
    import sys
    
    
    class TypeHintRemover(ast.NodeTransformer):
    
        def visit_FunctionDef(self, node):
            # remove the return type definition
            node.returns = None
            # remove all argument annotations
            if node.args.args:
                for arg in node.args.args:
                    arg.annotation = None
            self.generic_visit(node)
            return node
    
        def visit_AnnAssign(self, node):
            if node.value is None:
                return None
            return ast.Assign([node.target], node.value)
    
        def visit_Import(self, node):
            node.names = [n for n in node.names if n.name != 'typing']
            return node if node.names else None
    
        def visit_ImportFrom(self, node):
            return node if node.module != 'typing' else None
    
    def remove_type_hints(source: str):
        # parse the source code into an AST
        parsed_source = ast.parse(source)
        # remove all type annotations, function return type definitions
        # and import statements from 'typing'
        transformed = TypeHintRemover().visit(parsed_source)
        # convert the AST back to source code
        return astor.to_source(transformed)
    
    
    def main():
        _, source_name, dest_name = sys.argv
        with open(source_name, "r") as sourceFile:
            source = "\n".join(sourceFile.readlines())
            dest = remove_type_hints(source)
            with open(dest_name, "w") as destFile:
                destFile.write(dest)
    
    if __name__ == "__main__":
        main()
    

提交回复
热议问题