mypy "invalid type" 错误

mypy "invalid type" error

我正在尝试在当前项目中实现类型注释,但从 mypy 收到我不理解的错误。

我正在使用 Python 2.7.11,并在我的基本 virtualenv 中新安装了 mypy。以下程序运行良好:

from __future__ import print_function
from types import StringTypes
from typing import List, Union, Callable

def f(value):     # type: (StringTypes) -> StringTypes
    return value

if __name__ == '__main__':
    print("{}".format(f('some text')))
    print("{}".format(f(u'some unicode text')))

但是运行mypy --py2 -s mypy_issue.pyreturns如下:

mypy_issue.py: note: In function "f":
mypy_issue.py:8: error: Invalid type "types.StringTypes"

以上类型似乎在 Typeshed... the mypy documentation 中表示 "Mypy incorporates the typeshed project, which contains library stubs for the Python builtins and the standard library. "... 不确定 "incorporates" 是什么意思 - 我需要对 "activate" 做些什么吗,或者提供一条路径,Typeshed?我需要在本地下载并安装(?)Typeshed 吗?

问题是 types.StringTypes 被定义为类型的 序列 -- 正式的类型签名 on Typeshed 是:

StringTypes = (StringType, UnicodeType)

这对应于 official documentation,表示 StringTypes 常量是 "a sequence containing StringType and UnicodeType"...

那么,这就解释了您遇到的错误——StringTypes 不是实际的 class(它可能是一个元组),因此 mypy 无法将其识别为有效的类型。

有几个可能的修复方法。

第一种方法可能是使用 typing.AnyStr,它被定义为 AnyStr = TypeVar('AnyStr', bytes, unicode)。尽管 AnyStr 包含在 typing 模块中,但不幸的是,到目前为止,它的文档还有些不足——您可以找到有关它的功能的更多详细信息 within the mypy docs.

一种不太简洁的表达方式是:

from types import StringType, UnicodeType
from typing import Union

MyStringTypes = Union[StringType, UnicodeType]

def f(value):     
    # type: (MyStringTypes) -> MyStringTypes
    return value

这也有效,但不太理想,因为 return 类型不再必须与输入类型相同,这在处理不同类型的字符串时通常不是您想要的。

至于 typeshed——它在您安装 mypy 时默认捆绑在一起。在理想情况下,您根本不需要担心 typeshed,但由于 mypy 处于测试阶段,因此 typeshed 经常更新以解决丢失的模块或不正确的类型注释,可能值得直接从 Github repo 并在本地安装 typeshed,如果你发现自己经常 运行 遇到 typeshed 的错误。