"无效类型"自引用mypy类型中的错误

时间:2017-06-14 16:12:32

标签: python static-typing mypy

我定义了以下类型:

KRPCTypes = typing.Union[int, bytes, list, "KRPCDict"]
KRPCDict = typing.Dict[bytes, KRPCTypes]

当我运行mypy时,我收到以下错误:

error: Invalid type "test.KRPCDict"

以下是重现错误的完整最小代码:

import typing

KRPCTypes = typing.Union[int, bytes, list, "KRPCDict"]
KRPCDict = typing.Dict[bytes, KRPCTypes]

谢谢!

1 个答案:

答案 0 :(得分:2)

不幸的是,mypy和Python打字生态系统目前还不支持递归类型。

你可以在这里找到它的问题:https://github.com/python/mypy/issues/731(虽然你应该忽略中间的一些帖子,因为它们是由最终发生无关问题的人发布的。)

线程中的主要阻止者(例如"我们应该首先实现结构子类型")是under active development并且希望在接下来的几个月内至少成为mypy的一部分,所以也许它可能值得重新讨论。

许多人倾向于使用的当前解决方法(特别是在尝试键入类型相似的JSON时)是手动将递归类型扩展到所需级别,并最终使用Any。例如:

from typing import Union, Dict, List, Any

KRPCTypes = Union[int, bytes, list, Dict[bytes, Union[int, bytes, list, Any]]]
KRPCDict = Dict[bytes, KRPCTypes]

顺便提一下,您可能希望使用typing.List[T]并指定列表应包含的类型 - 如果仅执行list,则默认为typing.List[Any],这不太精确那可能是。

另一种方法可能是使用实验TypedDict类型,它允许您定义给定字典的确切类型和结构。这不太有用,因为TypedDict不能表示每种KRPCDict,但如果您希望只处理有限数量的不同类型的KRPCDict类型,它会派上用场。

还没有关于TypedDict的文档(开发人员希望在宣传之前先解决所有主要错误),但是如果你想尝试修补它,我写了一个例子说明如何你可以在bottom of this (largely unrelated) answer使用它。