*Memo:
- My post explains type hint (2).
- My post explains type hint (3).
- My post explains type hint (4).
- My post explains type hint (5).
- My post explains type hint (6).
- My post explains type hint (7).
- My post explains the memo for type hint-related posts.
A type hint:
- is the optional static type created by a non-union type or union type for a variable, or function parameter or return value.
- is for the (static) type checkers such as mypy, pyright, pyrefly, ty, etc so error doesn't occur with Python interpreter even if a type hint is wrong:
- should be used as specific as possible.
- can be done with
':', with one or more types and with or without'|'and'[]'.
Basically, I used mypy --strict for the experiments.
mypy --strict for the experiments. *mypy can be installed with pip install mypy.
A type hint can be done with ':', with one or more types and with or without '|' and '[]' as shown below:
*Memo for '|':
-
'|'can be used from Python 3.10. - The type of
'|'is Union at runtime:-
Unionis an old way and can still be used.
-
-
UnionType is the alias of
Unionfrom Python 3.14 but currently, using it with mypy gives error as the issue:-
UnionTypeis used as a static type which reveal_type() can print but type() cannot get:-
reveal_type()can ask a type checker to print the static type of a value at pre-runtime:- The 1st parameter is
obj(Required-PO-Type:Any):- It's a value.
- At runtime, it prints a dynamic type and gets the 1st argument.
- The 1st parameter is
-
type()can only get a dynamic type at runtime.
-
-
- To set one or more types and
None, Optional can also be used from Python 3.10: - For
UnionandUnionType:- The 1st parameter is
*types(Required-VP-Type:Type):- It's one or more types.
-
Union[str, int, None],UnionType[str, int, None]andstr | int | Noneare equivalent.
- The 1st parameter is
- For
Optional:- The 1st parameter is
type(Required-PO-Type:Type):- It's a type.
-
Optional[str],str | None,Union[str, None]andUnionType[str, None]are equivalent.
- The 1st parameter is
- At runtime:
- a single type is a non-union type even if using
Union,UnionTypeandOptional. - a set of multiple types is a union type even if using
UnionTypeandOptional.
- a single type is a non-union type even if using
- At pre-runtime, many representations of types are used whether a single type or a set of multiple types.
*Memo for '[]':
-
'[]'can be used for special typing forms and generic types.
# from typing import Union
# from types import UnionType
v: str = 'Hello'
# v: Union[str] = 'Hello'
# v: UnionType[str] = 'Hello' # Error
# Equivalent
v = 23
v = None
# Error
# from typing import Union, Optional
v: str | int | None = 'Hello'
# v: Union[str, int, None] = 'Hello'
# v: Optional[str | int] = 'Hello'
# Equivalent
v = 23
v = None
# No error
v = 2.3
# Error
# from typing import Union
v: list[int | str] = [0, 'A', 1, 'B', 2]
# v: list[int] | list[str] = [0, 'A', 1, 'B', 2] # Error
# 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
# from typing import Union, Optional
def func(name: str, age: int | None = None) -> str | None:
# def func(name: Union[str], age: Union[int, None] = None) -> Union[str]:
# def func(name: str, age: Optional[int] = None) -> str:
return f'Name:{name}, Age:{age}' # Equivalent
print(func('John'))
print(func(name='John'))
print(func('John', 28))
print(func(name='John', age=28))
# No error
# At runtime
from typing import Any, Union, Optional, reveal_type
# A non-union type with `reveal_type()`
reveal_type(int) # type
reveal_type(None) # NoneType
reveal_type(Any) # _AnyMeta
reveal_type(Union[int]) # type
reveal_type(Optional[None]) # type
# A union type with `reveal_type()`
reveal_type(int | float) # Union
reveal_type(None | Any) # Union
reveal_type(Union[int, float]) # Union
reveal_type(Optional[int]) # Union
# A non-union type with `type()`
print(type(int)) # <class 'type'>
print(type(None)) # <class 'NoneType'>
print(type(Any)) # <class 'typing._AnyMeta'>
print(type(Union[int])) # <class 'type'>
print(type(Optional[None])) # <class 'type'>
# A union type with `type()`
print(type(int | float)) # <class 'typing.Union'>
print(type(None | Any)) # <class 'typing.Union'>
print(type(Union[int, float])) # <class 'typing.Union'>
print(type(Optional[int])) # <class 'typing.Union'>
# At pre-runtime
from typing import Any, Union, Optional, reveal_type
# A non-union type with `reveal_type()`
reveal_type(int)
# Overload(def (builtins.str | _collections_abc.Buffer |
# typing.SupportsInt | typing.SupportsIndex =) -> builtins.int,
# def (builtins.str | builtins.bytes | builtins.bytearray,
# base: typing.SupportsIndex) -> builtins.int)"
reveal_type(None) # None
reveal_type(Any) # def () -> typing.Any
reveal_type(Union[int]) # typing._SpecialForm
reveal_type(Optional[None]) # typing._SpecialForm
# A union type with `reveal_type()`
reveal_type(int | float)
# types.UnionType | Overload(def (builtins.str |
# _collections_abc.Buffer | typing.SupportsInt |
# typing.SupportsIndex =) -> builtins.int,
# def (builtins.str | builtins.bytes |
# builtins.bytearray, base: typing.SupportsIndex) -> builtins.int)
reveal_type(None | Any) # types.UnionType | def () -> typing.Any
reveal_type(Union[int, float]) # typing._SpecialForm
reveal_type(Optional[int]) # typing._SpecialForm
# A non-union type with `type()`
print(type(int)) # Nothing
print(type(None)) # Nothing
print(type(Any)) # Nothing
print(type(Union[int])) # Nothing
print(type(Optional[None])) # Nothing
# A union type with `type()`
print(type(int | float)) # Nothing
print(type(None | Any)) # Nothing
print(type(Union[int, float])) # Nothing
print(type(Optional[int])) # Nothing
# At runtime with `reveal_type()` and `print()`
from typing import reveal_type
# Dynamic type # 1st argument
print(reveal_type(int)) # type # <class 'int'>
Top comments (0)