Using classes that are generic in stubs but not at runtime
Some classes are declared as generic in stubs, but not at runtime. Examplesin the standard library include os.PathLike
and queue.Queue
.Subscripting such a class will result in a runtime error:
- from queue import Queue
- class Tasks(Queue[str]): # TypeError: 'type' object is not subscriptable
- ...
- results: Queue[int] = Queue() # TypeError: 'type' object is not subscriptable
To avoid these errors while still having precise types you can either usestring literal types or TYPE_CHECKING
:
- from queue import Queue
- from typing import TYPE_CHECKING
- if TYPE_CHECKING:
- BaseQueue = Queue[str] # this is only processed by mypy
- else:
- BaseQueue = Queue # this is not seen by mypy but will be executed at runtime.
- class Tasks(BaseQueue): # OK
- ...
- results: 'Queue[int]' = Queue() # OK
If you are running Python 3.7+ you can use from future import annotations
as a (nicer) alternative to string quotes, read more in PEP 563. For example:
- from __future__ import annotations
- from queue import Queue
- results: Queue[int] = Queue() # This works at runtime