我一直在向我的包.py
文件添加类型信息,以支持mypy
针对包运行。除其他外,还允许为此第三方包生成类型信息。
由于我的包必须与 Python 2.7 兼容,因此我对类型信息使用注释:
def __init__(self, s):
# type: (Text) -> None
但为了运行mypy
这需要我导入输入:
from typing import Text, IO, BinaryIO, Union
这会导致两个问题:
这不适用于 Python 3.5.0 和 3.5.1,因为它有一个模块
typing
,但不包括Text
. 从 PyPI安装typing
并不能解决这个问题。(并且有些用户在该版本的 Python 上运行该包)。这使我的包依赖于
typing
2.7/3.3/3.4 安装,需要额外的下载和安装。我
Union
定义了自己的类型:StreamType = Union[BinaryIO, IO[str], StringIO] StreamTextType = Union[Text, StreamType]
必须根据输入是否可用,有条件地执行此代码。
对于第一个问题,由于我不在mypy
Python 3.5.0/1 下运行,我可以执行以下操作:
import sys
if sys.version_info < (3, 5, 0) and sys.version_info >= (3, 5, 2):
from typing import Text, IO, BinaryIO, Union
但这并不能解决第二个问题。
注释掉import
,例如注释中的类型信息,
# from typing import Text, IO, BinaryIO, Union
会导致mypy
抛出错误Name 'Text' is not defined
。
第三个问题可以通过使用try
- except
(丑陋,而且可能效率低下)或例如通过测试环境变量(也可以用来解决第一个问题)来解决。
运行时是否设置了环境变量mypy
,我可以对其进行测试,以便仅在运行时执行导入语句mypy
?针对环境变量进行测试还可以让我将自己类型的定义放在“受保护的”范围内。
还是其他解决方案?