pythonpython-typing

What's the best practice of typing hint after python 3.9?


After python3.9, there are at least three ways to use typing hint. Take the build-in collection set for instance:

# way 1
def f(s: set[str]) -> str:
    pass

# way 2
def f(s: typing.Set[str]) -> str:
    pass

# way 3
def f(s: collections.abc.Set[str]) -> str:
    pass

# way 3': or arguable collections.abc.MutableSet vs collections.abc.Set
def f(s: collections.abc.MutableSet[str]) -> str:
    pass

Furthermore, for some abstract type there are two version in typing and collections.abc, take Mapping for instance:

def f(m: typing.Mapping[str, int]) -> int:
    pass

def f(m: collections.abc.Mapping[str, int]) -> int:
    pass

According to The Zen of Python:

There should be one-- and preferably only one --obvious way to do it.

I am confused which one is best?


Solution

  • You should be using the set[str] style of typing. Looking at PEP 585:

    Importing those from typing is deprecated. Due to PEP 563 and the intention to minimize the runtime impact of typing, this deprecation will not generate DeprecationWarnings. Instead, type checkers may warn about such deprecated usage when the target version of the checked program is signaled to be Python 3.9 or newer.

    So importing those from python's typing package is now deprecated and you ideally should not be using those anymore; however, if you need to be backwards compatible with older versions of python, you can get by using them for now. Just be aware that in 5 years you may need to go in and update your code base since you will nedd python 3.9:

    Tooling, including type checkers and linters, will have to be adapted to recognize standard collections as generics.

    On the source level, the newly described functionality requires Python 3.9