TypeVar 在 if/else 中定义

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

虽然此代码有效:

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
仅定义一次并且不会更改?

python python-typing mypy
1个回答
0
投票

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 做任何事情,这只适用于您的运行时行为。


  1. 查看
    defineConstant
    配置https://github.com/microsoft/pyright/blob/main/docs/configuration.md
© www.soinside.com 2019 - 2024. All rights reserved.