移除Python 3.10+类型提示以适配Python 3.8运行环境
问题描述
我们公司有一个基于Python 3.10开发的代码库,原本计划在该版本环境运行,但目前已迁移至仅支持Python 3.8.12的Google Cloud Composer平台。
当前核心问题是代码库大量使用了Python 3.10+专属的新型类型语法(如新联合类型语法),需要移除所有类型提示。手动处理数千行代码不现实,我尝试用Python的AST包编写脚本移除类型提示,但仅能移除函数参数和返回值的类型提示,无法处理变量声明的类型提示。
示例问题函数:
def sampleFunction( self, argument1: bool, argument2: str, argument3: float, ) -> dict[str, list[float]]: var1: bool = True var2: str = "Hello"
我编写的AST脚本如下:
class TypeHintRemover(ast.NodeTransformer): def recursive(func): """decorator to make visitor work recursive""" def wrapper(self, node): self.generic_visit(node) return func(self, node) return wrapper 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 return node def visit_Assign(self, node): for target in node.targets: if hasattr(target, "type_comment") and target.type_comment: target.type_comment = None return node def visit_Attribute(self, node: Attribute) -> Any: if hasattr(node, "type_comment") and node.type_comment: node.type_comment = None return node @recursive def visit(self, node): return super().visit(node)
请问如何实现完整移除所有类型提示?
解决方案
你当前的脚本未处理**变量类型注解(var: Type = value)**对应的AST节点——这类语法对应的是ast.AnnAssign节点,而非普通的ast.Assign,同时还需覆盖异步函数、Lambda表达式等场景的类型提示。以下是修改后的完整脚本:
import ast from typing import Any class TypeHintRemover(ast.NodeTransformer): def visit_FunctionDef(self, node: ast.FunctionDef) -> ast.FunctionDef: # 移除函数返回值类型 node.returns = None # 移除各类参数的类型注解 for arg in node.args.args: arg.annotation = None for kwarg in node.args.kwonlyargs: kwarg.annotation = None if node.args.vararg: node.args.vararg.annotation = None if node.args.kwarg: node.args.kwarg.annotation = None # 递归处理函数内部节点 self.generic_visit(node) return node def visit_AsyncFunctionDef(self, node: ast.AsyncFunctionDef) -> ast.AsyncFunctionDef: # 异步函数处理逻辑与普通函数一致 node.returns = None for arg in node.args.args: arg.annotation = None for kwarg in node.args.kwonlyargs: kwarg.annotation = None if node.args.vararg: node.args.vararg.annotation = None if node.args.kwarg: node.args.kwarg.annotation = None self.generic_visit(node) return node def visit_AnnAssign(self, node: ast.AnnAssign) -> ast.Assign: # 将带类型注解的变量声明转换为普通赋值语句 assign_node = ast.Assign( targets=[node.target], value=node.value, type_comment=None ) # 保留原节点位置信息,确保报错行号准确 ast.copy_location(assign_node, node) self.generic_visit(assign_node) return assign_node def visit_Lambda(self, node: ast.Lambda) -> ast.Lambda: # 移除Lambda表达式的参数类型注解 for arg in node.args.args: arg.annotation = None for kwarg in node.args.kwonlyargs: kwarg.annotation = None if node.args.vararg: node.args.vararg.annotation = None if node.args.kwarg: node.args.kwarg.annotation = None self.generic_visit(node) return node def visit_Assign(self, node: ast.Assign) -> ast.Assign: # 移除普通赋值语句的类型注释(如`var = value # type: Type`) for target in node.targets: if hasattr(target, 'type_comment'): target.type_comment = None self.generic_visit(node) return node # 使用示例 def remove_type_hints(source_code: str) -> str: tree = ast.parse(source_code) transformer = TypeHintRemover() modified_tree = transformer.visit(tree) # 保留原代码格式:Python3.9+可用ast.unparse,低版本需安装astunparse库 try: import astunparse return astunparse.unparse(modified_tree).strip() except ImportError: return ast.unparse(modified_tree).strip()
关键改进说明
- 新增
visit_AnnAssign:将带类型注解的变量声明转换为普通赋值语句,彻底移除变量类型提示。 - 完善参数处理:覆盖位置参数、关键字参数、可变参数(
*args/**kwargs)的类型注解移除。 - 扩展场景支持:新增异步函数、Lambda表达式的类型提示处理逻辑。
- 保留位置信息:避免修改后的代码报错时行号混乱。
测试结果
将示例代码传入remove_type_hints函数后,输出结果为:
def sampleFunction( self, argument1, argument2, argument3, ): var1 = True var2 = "Hello"
内容的提问来源于stack exchange,提问作者Daniel Liao
相关产品推荐
相关产品推荐

