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

问题描述 投票:0回答:1

我一直在包的

.py
文件中添加类型信息,以支持针对包运行
mypy
。除此之外,还允许为此第三方包生成 [typeshed][1] 信息。

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

def __init__(self, s):
    # type: (Text) -> None

但是为了运行

mypy
,这需要我导入输入:

from typing import Text, IO, BinaryIO, Union

这会导致两个问题:

  1. 这不适用于 Python 3.5.0 和 3.5.1,因为它有一个模块

    typing
    但不包括
    Text
    。从 PyPI 安装 [
    typing
    ][2] 并不能解决这个问题。 (并且有些用户在该版本的 Python 上运行该包)。

  2. 这使得我的软件包依赖于[

    typing
    ][2]进行2.7/3.3/3.4安装,需要额外的下载和安装。

  3. 我定义了自己的

    Union
    类型:

     StreamType = Union[BinaryIO, IO[str], StringIO]
     StreamTextType = Union[Text, StreamType]
    

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

对于第一个问题,由于我不在Python 3.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
,就像注释中的类型信息一样,

# from typing import Text, IO, BinaryIO, Union

将导致

mypy
抛出错误
Name 'Text' is not defined

第三个问题可以通过使用

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

运行

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

或者其他解决方案? [1]:https://github.com/python/typeshed [2]:https://pypi.python.org/pypi/typing

python python-typing mypy typeshed
1个回答
5
投票

mypy
关联的唯一环境变量是
MYPYPATH
,它由包的代码读取,而不是由包的代码设置。虽然
MYPYPATH
可能会被设置(特别是在生成
typeshed
信息时,以提供“其他”类型信息),但不能保证它是这样的。

您无法注释掉

import
语句,但您 可以 将其放入从不执行的块中:

if False:  # MYPY
    from typing import Text, IO, BinaryIO, Union

这样做的好处是,如果您在特定的 Python 文件中没有其他需要,则不必导入

os
来获取环境变量(和/或
sys
来获取
version_info
) .

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

# import or define StringIO

if False:  # MYPY
    StreamType = Union[BinaryIO, IO[str], StringIO]
    StreamTextType = Union[Text, StreamType]

如果上述内容位于

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

if False:  # MYPY
    from typing import Text, IO, BinaryIO, Union
    from .mytypes StreamType

上面将满足

mypy
,因此不会因未定义
Text
而抛出错误。它也适用于 3.5.0/1,并且无需使您的包依赖于
typing

如果要在 Python 2.7 环境中运行

typing
,您可能仍然需要安装
mypy
,但普通包的用户不会受此影响。

请注意,我在每个块的

# MYPY
之后添加了注释
if
。在文件中搜索
from typing
很容易,但是带有
StreamType
的块将不容易找到,以防
mypy
改变其行为并且您的代码需要调整。

© www.soinside.com 2019 - 2024. All rights reserved.