让 Mypy 对固定/最大长度序列感到满意

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

在与其他几种语言实现互操作层时,我遇到了如何表示固定和最大长度序列的问题。而对于 Python 来说,其他语言需要提供完整的类型信息并不重要。面向用户的 API 应如下所示:

@dataclass
class MyStruct:
    name: bounded_str[12]           # here 12 is a max length
    data: sequence[int8, 20]        # here 20 is the max length
    other_data: array[float32, 10]  # here 10 is a fixed length

现在我可以毫无问题地让它与普通的 python 一起工作。我让

sequence
array
生成
Annotated
类型,如下所示:

class ArrayMeta(type):
    def __getitem__(cls, tup):
        if type(tup) != tuple or len(tup) != 2 or type(tup[1]) != int:
            return TypeError("An array takes two arguments: a subtype and a constant length.")
        return Annotated[Sequence[tup[0]], array(*tup)]


class array(metaclass=ArrayMeta):
    def __init__(self, subtype, length):
        self.subtype = subtype
        self.length = length

这使得数据类具有完全可接受的

Annotated[Sequence[subtype], ...]
,我可以使用
get_type_hints
检查注释并确定互操作所需的“真实”类型,生成验证器/序列化器等。

现在,当我们将 Mypy 引入其中时,问题就出现了。 Mypy 不认为

array
类型有效,这很公平。然而,到目前为止,我制作有效版本的任何尝试都被难住了,因为
Generic
不会采用值类型:

T = TypeVar('T')
V = TypeVar('V')

class MyArray(Protocol, Generic[T, V]):
    def __getitem__(self, key: int) -> T: ...
    def __len__(self):
        return V

a: MyArray[int, 5] = [0, 1, 2, 3, 4]
>>> TypeError: Parameters to generic types must be types. Got 5.

有没有办法让 Mypy 对这些

sequence
array
类型感到满意?

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

mypy 中没有“最大长度”检查,这意味着集合在运行时已填充,因此在此之前无法进行检查。

唯一可以定义固定长度的结构是

Tuple
,并且您必须定义每个元素,例如其中包含 4 个整数的元组如下所示:

from typing import Tuple
data: Tuple[int, int, int, int]

-2
投票

您可以使用

Literal[5]
,请参阅打字。文字

一种类型,可用于向类型检查器指示相应的变量或函数参数具有等于所提供的文字(或多个文字之一)的值。

© www.soinside.com 2019 - 2024. All rights reserved.