Python 版本相关的类型注解

Python version dependent type annotations

问题:

我想为 collections.deque 使用类型注释,但由于我们必须支持旧的 python 版本(确切地说是 3.4 和 3.5 - 而且它们不是官方 支持),我希望我的代码在我们必须支持的所有 python 版本中都有效。

我的原码:

from collections import deque
from typing import Deque
a = deque() # type: Deque[int]

它在 3.7 中工作得很好,但在 3.5 中,我得到 ImportError: cannot import name 'Deque'

我尝试了什么:

所以我想这样修改它:

from typing import Sequence
try:
    from typing import Deque
except ImportError:
    Deque = Sequence

from collections import deque
a = deque() # type: Deque[int]

但是我得到错误:

$ mypy . --pretty
a.py:5: error: Cannot assign multiple types to name "Deque" without an explicit "Type[...]" annotation
    Deque = Sequence
    ^
a.py:5: error: Incompatible types in assignment (expression has type "Type[Sequence[Any]]", variable has
type "Type[deque[Any]]")
    Deque = Sequence
        ^
Found 2 errors in 1 file (checked 1 source file)

问题:

有没有一种方法可以在 python3.4 和 python3.5 中使用相同的代码,同时为双端队列添加类型注释?

注:

是的,我知道 3.4 和 3.5 不受官方支持。但这个事实对我一点帮助都没有。请不要告诉我升级。

也许这个(或它的变体)会起作用

import sys
if sys.version_info[:2] >= (3,7):
    from typing import Deque
else:
    from typing import Sequence as Deque

from collections import deque    
a = deque() # type: Deque[int]
    

类型检查器使用它们自己版本的 typing 功能,无论运行时 typing 库是否支持它们。像Deque[int]这样的类型,只要不在运行时使用,就可以自由地用于签入任何版本。

  • 如果 typing 模块在所有需要的版本上可用,guard the imports:

    from collections import deque
    from typing import TYPE_CHECKING
    if TYPE_CHECKING:             # not entered at runtime
        from typing import Deque  # only happens during static type checking
    
    a = deque() # type: Deque[int]
    

    typing 模块可以作为 a backport 添加到 3.5 之前的版本。

  • 不支持所有必需类型功能的版本的一般解决方案是 pyi stub files

    # a.py
    from collections import deque
    
    a = deque()
    
    # a.pyi
    from typing import Deque
    
    a: Deque[int] = ...