When you’re puzzled or when things are complicated
- from typing import Union, Any, List, Optional, cast
-
- # To find out what type mypy infers for an expression anywhere in
- # your program, wrap it in reveal_type(). Mypy will print an error
- # message with the type; remove it again before running the code.
- reveal_type(1) # -> Revealed type is 'builtins.int'
-
- # Use Union when something could be one of a few types
- x: List[Union[int, str]] = [3, 5, "test", "fun"]
-
- # Use Any if you don't know the type of something or it's too
- # dynamic to write a type for
- x: Any = mystery_function()
-
- # If you initialize a variable with an empty container or "None"
- # you may have to help mypy a bit by providing a type annotation
- x: List[str] = []
- x: Optional[str] = None
-
- # This makes each positional arg and each keyword arg a "str"
- def call(self, *args: str, **kwargs: str) -> str:
- request = make_request(*args, **kwargs)
- return self.do_api_query(request)
-
- # Use a "type: ignore" comment to suppress errors on a given line,
- # when your code confuses mypy or runs into an outright bug in mypy.
- # Good practice is to comment every "ignore" with a bug link
- # (in mypy, typeshed, or your own code) or an explanation of the issue.
- x = confusing_function() # type: ignore # https://github.com/python/mypy/issues/1167
-
- # "cast" is a helper function that lets you override the inferred
- # type of an expression. It's only for mypy -- there's no runtime check.
- a = [4]
- b = cast(List[int], a) # Passes fine
- c = cast(List[str], a) # Passes fine (no runtime check)
- reveal_type(c) # -> Revealed type is 'builtins.list[builtins.str]'
- print(c) # -> [4]; the object is not cast
-
- # If you want dynamic attributes on your class, have it override "__setattr__"
- # or "__getattr__" in a stub or in your source code.
- #
- # "__setattr__" allows for dynamic assignment to names
- # "__getattr__" allows for dynamic access to names
- class A:
- # This will allow assignment to any A.x, if x is the same type as "value"
- # (use "value: Any" to allow arbitrary types)
- def __setattr__(self, name: str, value: int) -> None: ...
-
- # This will allow access to any A.x, if x is compatible with the return type
- def __getattr__(self, name: str) -> int: ...
-
- a.foo = 42 # Works
- a.bar = 'Ex-parrot' # Fails type checking