-
(Sorry for the multiple questions these past few days). Code sample in pyright playground The following does not seem to complain about the invariance of dict values, while mypy does. from typing import TypeAlias, Mapping
IncEx: TypeAlias = 'dict[int, str] | dict[str, IncEx | bool]'
def func(arg: IncEx): pass
func({"elements": {"__all__": True}})
func({"__all__": True}) We are going to switch to |
Beta Was this translation helpful? Give feedback.
Replies: 1 comment 1 reply
-
Pyright's behavior is correct here. The expression This appears to be a bug in mypy. It looks like it is failing to apply bidirectional type inference in this case and is falling back on regular type inference rules. Pyright does this as well if you separate the code into two lines. v1: IncEx = {"elements": {"__all__": True}} # OK
reveal_type(v1) # IncEx
v2 = {"elements": {"__all__": True}}
reveal_type(v2) # dict[str, dict[str, bool]]
v3: IncEx = v2 # Type error due to invariance Interestingly, you can avoid the mypy bug if you simplify the type alias slightly. from typing import TypeAlias
IncEx: TypeAlias = "dict[str, IncEx | bool]"
def func(arg: IncEx):
pass
func({"elements": {"__all__": True}})
func({"__all__": True}) |
Beta Was this translation helpful? Give feedback.
Pyright's behavior is correct here. The expression
{"elements": {"__all__": True}})
constructs an object that is compatible with the typedict[str, IncEx | bool]
. This type can be evaluated through bidirectional type inference (what mypy calls "context"), so no error should be generated here.This appears to be a bug in mypy. It looks like it is failing to apply bidirectional type inference in this case and is falling back on regular type inference rules. Pyright does this as well if you separate the code into two lines.