Consider this example that emulates dict.get: (https://mypy-play.net/?mypy=latest&python=3.12)
fromtypingimportAny, reveal_typeclassMap[K, V]:
defset(self, key: K, value: V) ->None: ...
defget[T](self, key: Any, default: T, /) ->V|T: ...
d_any: Map[str, Any] =Map()
reveal_type(d_any.get("key", None)) # Any | None ✅️result: str=reveal_type(d_any.get("key", None)) # Any | str ❌️# error: Argument 2 to "get" of "Map" has incompatible type "None"; expected "str" mypys error message is misleading. None is a perfectly reasonable argument for the default value of d_any.get. The problem is that the return type Any | None is not assignable to str. It would make more sense if either:
mypy reports that Any | None cannot be assigned to str.
(e.g. by a two step approach: first try to solve with context and if that fails, use the return type that is inferred from the arguments alone)1mypy reports that it cannot find a solution for the type variable T.
(e.g. single step that considers both constraints from arguments and context)
Consider this example that emulates
dict.get: (https://mypy-play.net/?mypy=latest&python=3.12)mypys error message is misleading.Noneis a perfectly reasonable argument for the default value ofd_any.get. The problem is that the return typeAny | Noneis not assignable tostr. It would make more sense if either:mypyreports thatAny | Nonecannot be assigned tostr.(e.g. by a two step approach: first try to solve with context and if that fails, use the return type that is inferred from the arguments alone)1
mypyreports that it cannot find a solution for the type variableT.(e.g. single step that considers both constraints from arguments and context)
Footnotes
In certain special cases like tuple/list/set/dict-comprehensions, the current behavior that inverts the priority seems fine ↩