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

使用mypy时函数类型注解报错:Invalid type comment or annotation [valid-type]

问题描述

mypy抛出类型错误:

error: Invalid type comment or annotation [valid-type]

相关代码如下:

动态分页模型生成类

class PaginatedResults:
    def __new__(cls, model_to_paginate):
        fields = {
            "data": (typing.List[model_to_paginate], []),
            "limit": (int, DEFAULT_PAGE_SIZE),
            "offset": (int, 0),
            "total": (int, 0),
        }
        return create_model(f"Paginated{model_to_paginate.__name__}", **fields)

Pydantic模型定义

class Car(BaseModel):     
    id: int

函数使用代码

def my_function(limit: int, offset:int) -> PaginatedResults(Car)
    total=0
    return PaginatedResults(Car)(
            data=[],
            limit=limit,
            offset=offset,
            total=0,
    )

代码能正常运行,但mypy持续报错,求正确处理方式。

解决方案

mypy报错的核心原因是:PaginatedResults(Car)是运行时调用表达式,无法直接作为静态类型注解使用——mypy在静态检查阶段无法解析动态生成的类型,需要通过以下方式处理:

1. 改用泛型类(推荐方案)

将PaginatedResults重构为泛型类,让mypy能识别类型参数,同时保留分页模型的复用性:

from typing import Generic, TypeVar, List
from pydantic import BaseModel

T = TypeVar('T')
DEFAULT_PAGE_SIZE = 10

class PaginatedResults(BaseModel, Generic[T]):
    data: List[T] = []
    limit: int = DEFAULT_PAGE_SIZE
    offset: int = 0
    total: int = 0

# 函数注解直接使用泛型类型
def my_function(limit: int, offset: int) -> PaginatedResults[Car]:
    return PaginatedResults[Car](
        data=[],
        limit=limit,
        offset=offset,
        total=0,
    )

这种方案既保证了类型安全,又让mypy能正确校验返回值类型,同时避免了动态生成类的复杂性。

2. 用cast兼容动态生成场景(适合必须保留原逻辑的情况)

如果因业务需求必须保留动态生成类的逻辑,可以通过cast显式告知mypy实际返回类型:

from typing import cast, TypeVar
from pydantic import BaseModel, create_model

T = TypeVar('T')
DEFAULT_PAGE_SIZE = 10

class PaginatedResults:
    def __new__(cls, model_to_paginate: type[T]) -> type[BaseModel]:
        fields = {
            "data": (list[model_to_paginate], []),
            "limit": (int, DEFAULT_PAGE_SIZE),
            "offset": (int, 0),
            "total": (int, 0),
        }
        return create_model(f"Paginated{model_to_paginate.__name__}", **fields)

class Car(BaseModel):
    id: int

def my_function(limit: int, offset: int):
    return cast(PaginatedResults(Car), PaginatedResults(Car)(
        data=[],
        limit=limit,
        offset=offset,
        total=0,
    ))

3. 临时忽略mypy错误(不推荐)

如果只是临时绕过检查,可以在报错行添加注释忽略特定错误:

def my_function(limit: int, offset:int) -> PaginatedResults(Car):  # type: ignore[valid-type]
    total=0
    return PaginatedResults(Car)(
            data=[],
            limit=limit,
            offset=offset,
            total=0,
    )

这种方式会跳过该行的类型检查,丢失mypy的静态类型保障,不建议长期使用。

内容的提问来源于stack exchange,提问作者Johnne

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.30 20:36:01