首页 > 解决方案 > 创建与 `int` 兼容的新 `int` 子类型 mypy

问题描述

我想int以一种mypy仍将其识别为 int 的方式扩展类型。例如:

class u8(int):
    _size_bits = 8
    _struct_format: str = 'B'

    def validate(self):
        "Internal function. Mypy shouldn't care about it"
        return 0 <= int(self) <= 255

所以我可以使用

i: u8 = 10

mypy给出了错误

Incompatible types in assignment (expression has type "int", variable has type "u8")

假设它使用 PEP 563,即。from __future__ import annotations.

像这样铸造它会起作用,但它会污染,产生不必要的开销,并且它需要在现有代码中工作,只更改类型提示,而不是代码

i: u8 = u8(10)

因此,唯一需要的更改是添加类型提示,而不是更改其余代码。它应该可以在不打字的情况下正常工作。如果我删除库(假设 PEP 563),代码应该运行良好,即使在这种情况下它会在 Mypy 上给出错误:

from __future__ import annotations

i: u8 = 10  # Works OK without the u8 definition

i: u8 = u8(10)  # ERROR: u8 is not defined here.

我也尝试使用abc.ABCwith register 但它不起作用

class u8(int, ABC):
    ...

u8.register(int)

这似乎是一项简单的任务,我必须在这里遗漏一些非常明显的东西,但是到目前为止所有的谷歌搜索都没有帮助。

标签: pythonmypypython-typing

解决方案


您正在尝试将非类型信息填充到您的注释中,以使您正在构建的工具受益。您已尝试通过创建子类型来做到这一点,但这并不意味着您想要它的意思,并且 mypy 正确地引发了错误。

Python 3.9 中提供了您想要的功能,并且为typing_extensions. 这是PEP 593Annotated中提出的注释。,您可以定义Annotated

u8 = Annotated[int, whatever_arbitrary_data]

并注释之类的东西

i: u8 = 10

并且 mypy 会识别出这int是类型并且whatever_arbitrary_data是其他人的问题。


推荐阅读