You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
Add a strictness flag that disables the bivariant behavior of TypeGuard #11230
I can't stand bivariance, and I believe it should always be an opt-in behavior. I don't know any other place in python typing where bivariance exists (except for an Any generic parameter).
Please add a strictness flag that enforces standard python typing variance rules on TypeGuard.
i believe this flag would be useful, however the broader issue is that TypeGuard doesn't enforce that the narrowed type is a subtype in the first place.
The return type of a user-defined type guard function will normally refer to a type that is strictly “narrower” than the type of the first argument (that is, it’s a more specific type that can be assigned to the more general type). However, it is not required that the return type be strictly narrower. This allows for cases like the example above where List[str] is not assignable to List[object].
wouldn't the problem be much better solved by simply making TypeGuard take variance into account? that way, you can enforce that the narrowed type is actually narrower
What value would that error message provide? Who would use it other than you? And if you saw that error message, what would you do to fix it?
but couldn't you say the same thing about other scenarios where variance is taken into account?
deffoo(value: list[object]) ->None: ...
bar: list[int]
foo(bar) # error: Argument 1 to "foo" has incompatible type "List[int]"; expected "List[object]"
in this case, you get some helpful information as well:
main.py:5: note: "List" is invariant -- see https://mypy.readthedocs.io/en/stable/common_issues.html#variance
main.py:5: note: Consider using "Sequence" instead, which is covariant
What value would that error message provide? ... You can choose not to use this type of TypeGuard in your code if you don't like it.
I understand the desire for unsafe narrowing, the issue I have is that it's extremely inconsistent with the rest of the typing landscape. The example from the pep: list[object] to list[int] is very obviously unsafe, but once type aliases, contra-variance and refactoring (and I'm sure other things) are taken into account, it would would be quite easy to accidentally write/introduce unsafe code.
Ideally I would want a TypeGuard and an UnsafeTypeGuard. But until such option is available I much prefer the assurance that the code I write is safe.
There has been discussion in the typing-sig about a StrictTypeGuard. I've even implemented it in pyright as a proof of concept, but there hasn't been enough interest to proceed with a PEP at this time.
But until such option is available I much prefer the assurance that the code I write is safe.
Then don't use the current TypeGuard feature in your code — or at least avoid using it in a manner that you don't like. I see no value in adding an optional error in mypy to tell you not to use it.
Then don't use the current TypeGuard feature in your code — or at least avoid using it in a manner that you don't like.
The issue is that there is no way to know if the usage is safe or not, withought performing manual type checking.
This has been addressed in basedmypy:
defis_str_list(val: list[object]) ->valislist[str]: # error: A type-guard's type must be assignable to its parameter's type. (guard has type "list[str]", parameter has type "list[object]") [typeguard-subtype]returnall(isinstance(x, str) forxinval)
Activity
JelleZijlstra commentedon Mar 19, 2022
Can you clarify what error you'd want to see exactly?
KotlinIsland commentedon Mar 19, 2022
erictraut commentedon Mar 19, 2022
What value would that error message provide? Who would use it other than you? And if you saw that error message, what would you do to fix it?
You can choose not to use this type of TypeGuard in your code if you don't like it.
DetachHead commentedon Mar 20, 2022
i believe this flag would be useful, however the broader issue is that
TypeGuarddoesn't enforce that the narrowed type is a subtype in the first place.from the PEP:
wouldn't the problem be much better solved by simply making
TypeGuardtake variance into account? that way, you can enforce that the narrowed type is actually narrowerbut couldn't you say the same thing about other scenarios where variance is taken into account?
in this case, you get some helpful information as well:
how is this any different?
KotlinIsland commentedon Mar 20, 2022
I understand the desire for unsafe narrowing, the issue I have is that it's extremely inconsistent with the rest of the typing landscape. The example from the pep:
list[object]tolist[int]is very obviously unsafe, but once type aliases, contra-variance and refactoring (and I'm sure other things) are taken into account, it would would be quite easy to accidentally write/introduce unsafe code.Ideally I would want a
TypeGuardand anUnsafeTypeGuard. But until such option is available I much prefer the assurance that the code I write is safe.erictraut commentedon Mar 20, 2022
There has been discussion in the typing-sig about a
StrictTypeGuard. I've even implemented it in pyright as a proof of concept, but there hasn't been enough interest to proceed with a PEP at this time.Then don't use the current TypeGuard feature in your code — or at least avoid using it in a manner that you don't like. I see no value in adding an optional error in mypy to tell you not to use it.
KotlinIsland commentedon Apr 6, 2024
The issue is that there is no way to know if the usage is safe or not, withought performing manual type checking.
This has been addressed in basedmypy:
playground
So I'm going to close it.
JelleZijlstra commentedon Apr 6, 2024
FYI,
TypeIs(added by PEP 742 and implemented in the next release of mypy) also requires that the output type is a subtype of the input type.