简体   繁体   中英

Python version dependent type annotations

Problem:

I want to use type annotation for collections.deque , but since we have to support older python version (3.4 and 3.5, which to be exact - and doesn't matter that they are not officially supported), I want my code to be valid in all python version we have to support.

My original code:

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

it works just fine in 3.7, but in 3.5, I get ImportError: cannot import name 'Deque' .

What I tried:

so I was thinking of modifying it like this:

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

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

But then I get errors:

$ 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)

Question:

Is there a way of having the same code which would be valid even in python3.4 and python3.5 while having type annotation for deque?

Note:

Yes, I know 3.4 and 3.5 are not officially suported. But that fact does not help me at all. Please don't tell me to upgrade.

Type checkers use their own version of typing features, regardless whether the runtime typing library supports them. A type such as Deque[int] can be used freely for checking in any version as long as it is not used at runtime.

  • If the typing module is available on all desired version, 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]

    The typing module can be added to pre-3.5 version as a backport .

  • The general solution for versions not supporting all required type features are pyi stub files .

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

Perhaps this (or a variation of it) would work

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]
    

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM