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

如何为整合typeguard.check_type的ensure_type编写兼容mypy的类型提示

解决ensure_type函数的mypy类型提示问题

typing.cast(type, obj)虽实用,但缺少运行时类型检查,因此我实现了ensure_type函数——先用typeguard.check_type做运行时类型校验,通过后再用typing.cast返回值:

from types import GenericAlias, UnionType
from typing import Any, cast

from annotated_types import T
from typeguard import check_type

def ensure_type(value, expected_type):  # noqa: ANN401 This function should hold Any value
    """Check the type and return value only if the types are matched.

    Otherwise, raise TypeError.
    """
    if check_type(value, expected_type):
        return cast("T", value)
    msg = f"Type check failed: type({value}) is {type(value)}, expected {expected_type}"
    raise TypeError(msg)

使用对比

obj = ensure_type(..., type)的写法比嵌套if check_type(obj, type)更简洁:

基于ensure_type的写法

# 使用 ensure_type
data = ensure_type(request_some_data(), dict[str])
key = ensure_type(data.get("key"), PromisedKey)
print(key)

直接使用check_type的写法

# 直接用 check_type
data = request_some_data()
if check_type(data, dict[str]):
    key = data.get("key")
    if check_type(key, PromisedKey):
        print(key)

类型提示的困扰

我尝试给ensure_type添加类型提示,但无法让mypy正确识别:

def ensure_type(value: Any, expected_type: type[T] | GenericAlias | UnionType) -> <the_same_type_of_expected_type>:

需要正确的类型提示写法,让mypy能正确推导返回值类型与expected_type的对应关系。

正确的类型提示写法

要让mypy正确识别,需利用标准TypeVar绑定泛型,并调整参数与返回值的类型标注,修改后的代码如下:

from types import GenericAlias, UnionType
from typing import Any, TypeVar, cast, Type

from typeguard import check_type

T = TypeVar("T")

def ensure_type(value: Any, expected_type: Type[T] | GenericAlias | UnionType) -> T:
    """Check the type and return value only if the types are matched.

    Otherwise, raise TypeError.
    """
    check_type(value, expected_type)
    return cast(T, value)

关键说明

  1. 替换annotated_types.T为标准TypeVar("T"),这是泛型类型推导的核心
  2. 参数expected_type标注为Type[T] | GenericAlias | UnionType,覆盖了类类型、泛型别名(如dict[str])、联合类型(如int | str)三类场景
  3. 返回值直接标注为T,mypy会根据传入的expected_type自动推导返回值的具体类型
  4. 简化逻辑:check_type本身会在类型不匹配时抛出TypeError,无需额外if判断

修改后,mypy就能正确识别:比如ensure_type(request_some_data(), dict[str])会被推导为dict[str]类型,ensure_type(data.get("key"), PromisedKey)会被推导为PromisedKey类型。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.13 03:05:12