Note that this is just type overloading, and doesn't allow for actual function logic overloading. For a single argument of changing type, see functools.singledispatch.
Overload & Cast
defload_json(path: str) -> Union[dict, list]:withopen(path) as f:
return json.load(f)
data = load_json("model_options.json")
data.items()
What's the problem with this?
Overload & Cast
cast ~ the inverse of union
data = cast(dict, load_json("model_options.json"))
data.items()
events = cast(list, load_json("events.json"))
events.reverse()
Note: cast is essentially just a type hint, it doesn't actually do anything, but just returns the second argument, as far as python is concerned
TYPE_CHECKING
If there are things that you want to import for type hinting purposes, but don't really need them otherwise, use TYPE_CHECKING
if TYPE_CHECKING:
from external_module_just_for_type_hints import Thing
else:
Thing = Anydefget_thing() -> Thing:
...
TYPE_CHECKING
Alternatively, use ""s, and mypy will figure out what you mean
if TYPE_CHECKING:
from external_module_just_for_type_hints import Thing
defget_thing() -> "Thing":
...
TYPE_CHECKING
This "" notation is also commonly used when you need to reference a class you haven't yet defined, by the way
classA:defget_thing(self) -> B:# raises a NameError
...
classA2:defget_thing(self) -> "B":# No error
...
classB:
...
Mypy Debugging
Mypy comes with two magic functions that can be handy for setting exactly what mypy things the types of certain objects are:
reveal_type(obj)
reveal_locals()
Note that these are not valid python, and are only understood by mypy, and if you leave them in your final code they will cause NameError's -- they are just for debugging purposes
Mypy Debugging
x = json.loads("[1,2,3]")
reveal_type(x) # Revealed type is "Any"
y = cast(dict, x)
reveal_type(y) # Revealed type is "builtins.dict[Any, Any]"
reveal_locals()
# Revealed local types are:# x: Anymypy(note)# y: builtins.dict[Any, Any]
Can see the output with mypy filename.py or inside of IDE
Note: you can get the same info from Pylance just by hovering over a variable in vscode
Mypy Debugging
Mypy Settings
There are many customizable settings, which can be passed on the command line, or set in a config file (mypy.ini or pyproject.toml).
Some useful ones:
--strict
--follow-imports=silent (not recommended, but perhaps useful for adding types to large existing codebases)
> python -m main --help
Usage: python -m main [OPTIONS] NAME
Arguments:
NAME [required]
Options:
--english / --no-english [default: english]
--install-completion [bash|zsh|fish|powershell|pwsh]
Install completion for the specified shell.
--show-completion [bash|zsh|fish|powershell|pwsh]
Show completion for the specified shell, to
copy it or customize the installation.
--help Show this message and exit.