Reputation: 273
I am using mypy and protocols and have run into a spot where I would like type hinting if possible, but I am unable to figure out how I should set it up so mypy doesn't error.
Consider the following example:
class TProtocol(Protocol):
t: str
@attrs(auto_attribs=True)
class T:
t: str
t2: str
@attrs(auto_attribs=True)
class T2:
t: str
def func(var: TProtocol) -> None:
if some_condition:
var: T
reveal_type(var)
else:
reveal_type(var)
While very contrived, it illustrates my goal of I have some runtime condition that if met I know that the type of that variable based on knowledge of the code base. I then want to pass this knowledge onto mypy so that further type checking uses that type.
The same example can be replace with a Union. Some runtime check occurs which tells me explicitly which one of the types I have based on knowledge of the code base. I then want to tell mypy explicitly which type that is for further type checking based on that outside knowledge.
The above example raises an error stating that var is already defined. I tried the allow_redefinition
option and it didn't change the output.
Upvotes: 4
Views: 1147
Reputation: 50076
Use typing.cast
to forcefully declare a variable as a specific type. This disregards any other typing information, and works on runtime-branches as well.
def func(var: TProtocol) -> None:
reveal_type(var) # line 21
if some_condition:
var = cast(T, var) # line 23
reveal_type(var)
else:
var = cast(T2, var) # line 26
reveal_type(var)
This makes mypy
treat each casted occurrence of var
differently, i.e. before and inside each branch:
type_tests.py:21: note: Revealed type is 'type_tests.TProtocol'
type_tests.py:24: note: Revealed type is 'type_tests.T'
type_tests.py:27: note: Revealed type is 'type_tests.T2'
Upvotes: 2