我一直在向包的.py
文件中添加类型信息,以支持对包运行mypy
。除此之外,允许为这个第三方包生成typeshed信息。在
由于我的软件包必须与Python2.7兼容,所以我使用注释作为类型信息:
def __init__(self, s):
# type: (Text) -> None
但是为了运行mypy
,这需要我导入类型:
这会导致两个问题:
这在python3.5.0和3.5.1上不起作用,因为它有一个模块typing
,但不包括Text
。从PyPI安装^{
这使得我的软件包依赖于^{
我定义了自己的Union
类型:
StreamType = Union[BinaryIO, IO[str], StringIO]
StreamTextType = Union[Text, StreamType]
根据输入是否可用,必须有条件地执行此代码。
对于第一个问题,由于我不在Python3.5.0/1下运行mypy
,所以我可以做如下操作:
import sys
if sys.version_info < (3, 5, 0) and sys.version_info >= (3, 5, 2):
from typing import Text, IO, BinaryIO, Union
但这并不能解决第二个问题。在
注释掉import
,就像comments中的类型信息一样
# from typing import Text, IO, BinaryIO, Union
将导致mypy
抛出一个错误Name 'Text' is not defined
。在
第三个问题可以通过使用try
-except
(丑陋,也可能低效)或例如通过测试环境变量(也可以用来解决第一个问题)来解决。在
在运行mypy
时是否设置了一个可以测试的环境变量,这样import语句只在运行mypy
时执行?
对环境变量进行测试也可以让我将自己类型的定义放在“保护”的范围内。在
或者其他解决方案?在
与
mypy
关联的唯一环境变量是MYPYPATH
,它由包的代码读取,而不是由它设置。当{cd2>生成信息时,{cd2>可能被设置。在不能注释掉
import
语句,但可以将其放入从不执行的块中:这样做的好处是,如果您在特定的Python文件中没有其他需要,则不必导入}来获取
os
来获取环境变量(和/或{version_info
)。在您的类型定义也应该这样指定,并且可以在导入或定义所有使用的类型之后的任何位置发生:
^{pr2}$如果上面的内容在
mytypes.py
中,则包中的任何其他源文件(在任何类型定义中使用StreamTypeText
)都应该执行以下操作:以上内容将满足
mypy
,因此不会在未定义Text
时引发错误。它也可以在3.5.0/1上运行,并且不需要使您的包依赖于typing
如果要在Python2.7环境中运行
mypy
,您可能仍然需要安装typing
,但是您的普通软件包的用户不受此影响。在请注意,我在每个块的
if
后面添加了一个注释# MYPY
。{{{18}在cd1}中搜索{19}很难找到它的行为。在相关问题 更多 >
编程相关推荐