如何在Python中为通用类型的数据类添加类型注释?

问题描述 投票:0回答:1

我正在用 Python 编写

dataclass
来收集
ArgumentParser.add_argument
所需的参数,但我在类型注释方面遇到了麻烦。

简化版:


from dataclasses import dataclass, KW_ONLY
from typing import Optional, TypeVar, Generic

T = TypeVar("T")

@dataclass
class CommandLineArgument(Generic[T]):
    name_or_flags: str | tuple[str]
    _: KW_ONLY
    metavar: Optional[str] = None
    type: Optional[type[T]] = None
    default: Optional[T] = None

虽然

mypy
认为这是正确的(没有发现问题),但
pytest
认为这是不对的。 请注意,当我在测试文件中导入
CommandLineArgument
时会发生这种情况。

如果这个类注释正确,为什么

pytest
会抱怨?

如果我将课程更改为:

@dataclass
class CommandLineArgument(Generic[T]):
    name_or_flags: str | tuple[str]
    _: KW_ONLY
    metavar: Optional[str] = None
    type: Optional[type[T]] = type
    default: Optional[T] = None

那么

pytest
很高兴,但显然
mypy
不高兴。

其他变体无法解决类似问题。

有没有办法让

pytest
mypy
都对此感到高兴?

python types pytest mypy type-hinting
1个回答
0
投票

最简单的解决方案是在模块顶部添加

from __future__ import annotations
以停止在运行时评估类型注释。


这是您的最小可重现示例:

import typing as t

T = t.TypeVar("T")

class A(t.Generic[T]):
    type: type[T] | None = None

这将在运行时失败,因为Python将在

type = None
的主体内分配
A
,然后尝试在运行时评估
type[T]
(变成
None[T]
),并出现以下失败:

TypeError: 'NoneType' object is not subscriptable
© www.soinside.com 2019 - 2024. All rights reserved.