虽然此代码有效:
from typing import TypeAlias, TypeVar
T = TypeVar("T", complex, float, str)
z: TypeAlias = tuple[T, ...] | list[T]
有条件地定义
T
则不然。
from typing import Generic, TypeAlias, TypeVar
try:
import somepackage
use_complex = True
except:
use_complex = False
if use_complex:
T = TypeVar("T", complex, float, str)
else:
T = TypeVar("T", float, str)
z: TypeAlias = tuple[T, ...] | list[T]
我得到:
Variable not allowed in type expression
有没有一种方法可以告诉类型检查器 use_complex 是一个常量,因此它要么是一个分支,要么是另一个分支,
T
仅定义一次并且不会更改?
mypy 和 Pyright1 都支持定义编译时常量以实现这样的控制流分析;该行为类似于
sys.version_info
、sys.platform
或 typing.TYPE_CHECKING
守卫。
将以下内容放入 mypy 配置文件中:
[mypy]
# Only specify ONE of the following:
# * When developing against the package
always_true = use_complex
# * When not developing against the package
always_false = use_complex
然后执行以下操作之一:
在专用模块中定义常数
# constants.py
try:
import somepackage
use_complex = True
except:
use_complex = False
>>> import constants
>>>
>>> if constants.use_complex: ...
... ...
在同一模块中定义常量并使用它。这与您在问题中的示例相同(mypy游乐场演示:
always_true = use_complex
,always_false = use_complex
)
try:
import somepackage
use_complex = True
except:
use_complex = False
if use_complex:
T = TypeVar("T", complex, float, str)
else:
T = TypeVar("T", float, str)
z: TypeAlias = tuple[T, ...] | list[T]
num: z[complex] = [8j] # OK when `always_true = use_complex`, else errors when `always_false = use_complex`
请注意,
try...except
实际上并不为 mypy 做任何事情,这只适用于您的运行时行为。
defineConstant
配置https://github.com/microsoft/pyright/blob/main/docs/configuration.md