This question might already have an answer, so please guide me to one if you know any. I couldn't find one myself, though this question feels like a common one.
So, consider the following pattern:
arr = [None] * n
for i in range(n):
# do some computations
# ...
# even more computations
arr[i] = MyClass(some_computed_value)
So far so good, I tend to use this pattern from time to time. Now, let us be thorough in our attempt to provide all the code with type annotations. The problem is that we preallocate our array with None
s, so it has the type list[None]
. But we want it to be list[MyClass]
. How do we proceed?
The most straightforward solution is making it optional:
arr: list[Optional[MyClass]] = [None] * n
This solves the type checker issue, but now it's our issue since that Optional
prohibits us from performing even basic operations on the result
arr[0].my_method()
# error: NoneType has no attribute "my_method"
Long story short, I end up with the following pattern:
arr_: Any = [None] * n
for i in range(n):
# ...
arr_[i] = MyClass(some_computed_value)
arr = typing.cast(list[MyClass], arr_)
This is ugly, inconvenient, barely readable and boilerplate. What do you do?
You can lie to your type checker when you first initialize arr
to "trick" it that arr
never contains None
entries. For the purposes of static type checking, arr
will be a list[MyClass]
, even though it briefly contains None
entries at runtime. You of course assume responsibility for making sure that this assumption plays out.
For example,
from typing import cast, reveal_type
n = 1000
arr: list[int] = [cast(int, None)] * n
# or alternatively
arr: list[int] = [None] * n # type: ignore
for i in range(n):
arr[i] = i
reveal_type(arr)
reveal_type(arr[0])
passes type checking with both mypy
and pyright
, and outputs
# mypy
tmp.py:9: note: Revealed type is "builtins.list[builtins.int]"
tmp.py:10: note: Revealed type is "builtins.int"
Success: no issues found in 1 source file
# pyright
file.py
file.py:9:13 - information: Type of "arr" is "list[int]"
file.py:10:13 - information: Type of "arr[0]" is "int"
0 errors, 0 warnings, 2 informations