DEV Community

Super Kai (Kazuya Ito)
Super Kai (Kazuya Ito)

Posted on

Type hints in Python (1)

A type hint:

  • is the label(annotation) which specifies the types for a variable, or function parameter or return value.
  • can be done with one or more types with ':'and with or without '|' and [].
  • is used with the type checkers such as mypy, pyright, pyre-check, pytype, etc.
  • is optional so it doesn't force the type with error unless type checkers are used.

I used mypy --strict for the experiments.

    *mypy can be installed with pip install mypy.


A type hint can be done with one or more types with ':' and with or without '|' and [] as shown below:

*Memo:

  • | can be used from Python 3.10 and typing.Union is still usable:
    • typing.Union can have one or more types.
  • [] can be used for collection and callable types such as a list, tuple, set, function, etc.
# from typing import Union

v: str = 'Hello'
# v: Union[str] = 'Hello' # Equivalent

v = 23
v = None
# Error
Enter fullscreen mode Exit fullscreen mode
# from typing import Union

v: str | int | None = 'Hello'
# v: Union[str, int, None] = 'Hello' # Equivalent

v = 23
v = None
# No error

v = 2.3
# Error
Enter fullscreen mode Exit fullscreen mode
# from typing import Union

v: list[int | str] = [0, 'A', 1, 'B', 2]
# v: list[Union[int, str]] = [0, 'A', 1, 'B', 2]        
# v: Union[list[int | str]] = [0, 'A', 1, 'B', 2]
# v: Union[list[Union[int, str]]] = [0, 'A', 1, 'B', 2]
# Equivalent

v.append('C')
# No error

v.append(3.4)
v = {0, 1, 2}
# Error
Enter fullscreen mode Exit fullscreen mode
# from typing import Union

def func(x: int, y: int | float = 5) -> str:
# def func(x: Union[int], y: Union[int, float] = 5) -> Union[str]:
    return f'x+y={x+y}'               # Equivalent

print(func(3))    # x+y=8
print(func(2, 4)) # x+y=6
Enter fullscreen mode Exit fullscreen mode
# from typing import Union
from collections.abc import Callable

def func(x: list[int], y: list[str]) -> list[int | str]:
# def func(x: list[Union[int]], y: list[Union[str]]) -> list[Union[int, str]]:
# def func(x: Union[list[int]], y: Union[list[str]]) -> Union[list[int | str]]:
# def func(x: Union[list[Union[int]]], y: Union[list[Union[str]]]) \
#     -> Union[list[Union[int, str]]]:
# Equivalent
    return x+y

v: Callable[[list[int], list[str]], list[int | str]] = func

print(v([0, 1, 2], ['A', 'B']))
# [0, 1, 2, 3, 'A', 'B']
Enter fullscreen mode Exit fullscreen mode
# from typing import Union

def func(x: str | None = None) -> int | float | bool | None:
# def func(x: Union[str, None] = None) -> Union[float, bool, None]:
    if not x:                    # Equivalent
        pass 
    elif x == 'i':
        return 23
    elif x == 'f':
        return 2.3
    elif x == 'b':
        return True

    return None

print(func())    # None
print(func('i')) # 23
print(func('f')) # 2.3
print(func('b')) # True
Enter fullscreen mode Exit fullscreen mode

Running mypy --strict, the function without type hints gets the errors while the variable without a type hint doesn't get error as shown below:

*Memo:

  • I reported this strange behaviour as the issue.
def func(x):
    return x
# error: Function is missing a type annotation
Enter fullscreen mode Exit fullscreen mode
def func(x) -> str:
    return x
# error: Function is missing a type annotation for one or more arguments
Enter fullscreen mode Exit fullscreen mode
def func(x: str):
    return x
# error: Function is missing a return type annotation
Enter fullscreen mode Exit fullscreen mode
v = 'Hello'
# No error
Enter fullscreen mode Exit fullscreen mode
v: str = 'Hello'
def func(x: int, y: int | float = 5) -> str:
    return f'x+y={x+y}'
# No error
Enter fullscreen mode Exit fullscreen mode

The variable with a type-hint and no value is possible while the variable with no type-hint and value is impossible as shown below:

v: str

v = 'Hello'
Enter fullscreen mode Exit fullscreen mode
v: str

print(v)
# NameError: name 'v' is not defined
Enter fullscreen mode Exit fullscreen mode
v
# NameError: name 'v' is not defined
Enter fullscreen mode Exit fullscreen mode

The value None should be used as a type within a type hint because the type NoneType gets error as shown below:

v: None
# No error
Enter fullscreen mode Exit fullscreen mode
from types import NoneType

v: NoneType
# error: NoneType should not be used as a type, please use None instead
Enter fullscreen mode Exit fullscreen mode

The function which only returns None gets the error if defining and calling the function, and printing the return value as shown below:

*Memo:

  • The error can be disabled using --disable-error-code with func-returns-value:
    • mypy --strict --disable-error-code func-returns-value test.py.
    • mypy --disable-error-code func-returns-value test.py.
  • Only defining and calling the function doesn't get the error.
  • Only defining the function doesn't get the error.
  • I reported this strange behaviour as the issue.
def func() -> None:
    return None

print(func())
# error: "func" does not return a value (it only ever returns None)
Enter fullscreen mode Exit fullscreen mode
from types import def func() -> None:
    return None

func()
# No error
Enter fullscreen mode Exit fullscreen mode
def func() -> None:
    return None
# No error
Enter fullscreen mode Exit fullscreen mode

Top comments (0)