You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

移除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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.03 09:19:50