添加类型信息而不依赖于键入模块

Ant*_*hon 2 python typing mypy typeshed

我一直在将类型信息添加到程序包的.py文件中,以支持mypy针对程序包运行。除其他事项外,它允许为此第三方包装生成分类信息。

由于我的软件包必须与Python 2.7兼容,因此我在类型信息中使用了注释:

def __init__(self, s):
    # type: (Text) -> None
Run Code Online (Sandbox Code Playgroud)

但是要运行mypy此命令,我需要输入以下内容:

from typing import Text, IO, BinaryIO, Union
Run Code Online (Sandbox Code Playgroud)

这会导致两个问题:

  1. 这在Python 3.5.0和3.5.1上不起作用,因为它有一个模块typing,但不包含Texttyping从PyPI 安装并不能解决该问题。(并且有些用户在该版本的Python上运行该软件包)。

  2. 这使我的软件包依赖于typing2.7 / 3.3 / 3.4安装,需要额外的下载和安装。

  3. Union定义了自己的类型:

    StreamType = Union[BinaryIO, IO[str], StringIO]
    StreamTextType = Union[Text, StreamType]
    
    Run Code Online (Sandbox Code Playgroud)

    该代码必须根据是否可用键入而有条件地执行。

对于第一个问题,由于我没有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
Run Code Online (Sandbox Code Playgroud)

但这不能解决第二个问题。

注释掉import,就像注释中的类型信息一样,

# from typing import Text, IO, BinaryIO, Union
Run Code Online (Sandbox Code Playgroud)

会引发mypy错误Name 'Text' is not defined

第三个问题可以通过使用try- except(丑陋的,可能也是效率低下的)来解决,或者例如通过针对环境变量进行测试(也可以用来解决第一个问题)来解决。

运行时是否设置了mypy可以测试的环境变量,以便仅在运行时执行import语句mypy?针对环境变量进行测试也将使我能够将自己的类型的定义放入“受保护的对象”中。

还是其他解决方案?

Ant*_*hon 5

与关联的唯一环境变量mypyMYPYPATH和,它由程序包的代码读取,而不是由它设置的。尽管MYPYPATH可以设置(特别是在生成typeshed信息时,以提供“其他”类型的信息),但不能保证一定要设置。

您不能注释掉该import语句,但是可以将其放在永远不会执行的块中:

if False:  # MYPY
    from typing import Text, IO, BinaryIO, Union
Run Code Online (Sandbox Code Playgroud)

这样做的好处是,如果您在特定的Python文件中不需要其他os变量,则无需导入即可获取环境变量(和/或sys获取version_info)。

您的类型定义也应该这样指定,并且可以在导入或定义所有使用的类型之后的任何地方出现:

# import or define StringIO

if False:  # MYPY
    StreamType = Union[BinaryIO, IO[str], StringIO]
    StreamTextType = Union[Text, StreamType]
Run Code Online (Sandbox Code Playgroud)

如果上述内容在中mytypes.py,则在包中使用StreamTypeText任何类型定义的任何其他源文件都应执行以下操作:

if False:  # MYPY
    from typing import Text, IO, BinaryIO, Union
    from .mytypes StreamType
Run Code Online (Sandbox Code Playgroud)

以上内容将满足mypy,因此Text不会在未定义时引发错误。它还可以在3.5.0 / 1上运行,并且消除了使软件包依赖于typing

typing如果要mypy在Python 2.7环境中运行,您可能仍需要安装,但是普通软件包的用户不受此影响。

请注意,我# MYPYif每个块的后面添加了一条注释。搜索文件from typing很容易,但StreamType如果mypy更改其行为并且您的代码需要调整,则很难找到带有的块。