创建与 int 兼容的新 int 子类型 mypy
Create new `int` subtype mypy compatible with `int`
我想扩展 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.ABC
与寄存器一起使用,但它 doesn't works:
class u8(int, ABC):
...
u8.register(int)
这似乎是一项简单的任务,我一定在这里遗漏了一些非常明显的东西,但到目前为止所有的谷歌搜索都没有帮助。
目前我发现的解决方法是在 TYPE_CHECKING
为真时将 class 定义为 int
。上面的例子似乎让 mypy 高兴并给出了我在运行时需要的东西:
from typing import TYPE_CHECKING
class _u8(int):
_size_bits = 8
_struct_format: str = 'B'
def validate(self):
return 0 <= int(self) <= 255
if TYPE_CHECKING:
u8 = int
else:
u8 = _u8
i: u8 = 10
您正试图将非类型信息填充到您的注释中,以便于您正在构建的工具。您已尝试通过创建子类型来做到这一点,但这并不意味着您想要它的意思,并且 mypy 正确地引发了错误。
Python 3.9 中将提供您想要的功能,typing_extensions
. It's the Annotated
annotation, proposed in PEP 593 中的大多数先前版本(3.5.3+ 和可能是 2.7)都可以使用向后移植。使用 Annotated
,您可以定义
u8 = Annotated[int, whatever_arbitrary_data]
并注释
i: u8 = 10
而mypy会识别int
是类型,whatever_arbitrary_data
是别人的问题。
我想扩展 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.ABC
与寄存器一起使用,但它 doesn't works:
class u8(int, ABC):
...
u8.register(int)
这似乎是一项简单的任务,我一定在这里遗漏了一些非常明显的东西,但到目前为止所有的谷歌搜索都没有帮助。
目前我发现的解决方法是在 TYPE_CHECKING
为真时将 class 定义为 int
。上面的例子似乎让 mypy 高兴并给出了我在运行时需要的东西:
from typing import TYPE_CHECKING
class _u8(int):
_size_bits = 8
_struct_format: str = 'B'
def validate(self):
return 0 <= int(self) <= 255
if TYPE_CHECKING:
u8 = int
else:
u8 = _u8
i: u8 = 10
您正试图将非类型信息填充到您的注释中,以便于您正在构建的工具。您已尝试通过创建子类型来做到这一点,但这并不意味着您想要它的意思,并且 mypy 正确地引发了错误。
Python 3.9 中将提供您想要的功能,typing_extensions
. It's the Annotated
annotation, proposed in PEP 593 中的大多数先前版本(3.5.3+ 和可能是 2.7)都可以使用向后移植。使用 Annotated
,您可以定义
u8 = Annotated[int, whatever_arbitrary_data]
并注释
i: u8 = 10
而mypy会识别int
是类型,whatever_arbitrary_data
是别人的问题。