【问题标题】:adding type information without dependency on typing module添加类型信息而不依赖于类型模块
【发布时间】:2017-09-16 22:13:06
【问题描述】:

我一直在向我的包的 .py 文件添加类型信息,以支持针对包运行 mypy。除此之外,还允许为此、第三方、包生成typeshed 信息。

由于我的包必须与 Python 2.7 兼容,因此我使用 cmets 作为类型信息:

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 并不能解决这个问题。 (并且有用户在那个版本的 Python 上运行包)。

  2. 这使我的包在 2.7/3.3/3.4 安装时依赖于 typing,需要额外的下载和安装。

  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,就像在cmets中的类型信息,

# from typing import Text, IO, BinaryIO, Union

将导致mypy 抛出错误Name 'Text' is not defined

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

在运行mypy 时是否设置了一个我可以测试的环境变量,以便只在运行mypy 时执行导入语句? 针对环境变量进行测试还可以让我将自己的类型定义放在“受保护的”范围内。

或者其他解决方案?

【问题讨论】:

    标签: python type-hinting mypy typeshed


    【解决方案1】:

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

    您不能注释掉 import 语句,但您可以将它放在一个从不执行的块中:

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

    这样做的好处是,如果您在特定情况下没有其他需要,则不必导入 os 来获取环境变量(和/或 sys 来获取 version_info) Python 文件。

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

    # 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 环境中运行 mypy,您可能仍需要安装 typing,但您的普通包的用户不会受此影响。

    请注意,我在每个块的 if 之后添加了注释 # MYPY。在文件中搜索from typing 很容易,但是如果mypy 改变了它的行为并且你的代码需要调整,那么StreamType 的块就不会那么容易被找到。

    【讨论】:

      猜你喜欢
      • 2020-12-08
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2023-03-22
      • 2023-03-21
      • 1970-01-01
      • 1970-01-01
      • 2019-03-06
      相关资源
      最近更新 更多