-
Notifications
You must be signed in to change notification settings - Fork 278
Open
Labels
contextual-typingissues related to contextual typingissues related to contextual typingstaletypechecking
Description
Describe the Bug
In the example below, I create a dict-like class
from typing import Any, reveal_type
class Map[K, V]:
def set(self, key: K, value: V) -> None: ...
def get[T=None](self, key: Any, default: T = None, /) -> V | T: ...
d_any: Map[str, Any] = Map()
# as expected, these are both `Any | None`
reveal_type(d_any.get("key")) # Any | None ✅️
reveal_type(d_any.get("key", None)) # Any | None ✅️
# outer context should not overrule the argument type!
result: str = reveal_type(d_any.get("key", None)) # Any | str ❌️ERROR sandbox.py:13:44-48: Argument `None` is not assignable to parameter `default` with type `str` in function `Map.get`
This message is confusing, it should be "Any | None can't be assigned to str".
Explanation
d_any.get("key", None) produces Any | None, and we have str as outer context. This gives an unsolvable situation for the type variable T as we would need both T <: str and T :> None. It seems pyrefly gives priority to the outer constraint T <: str here, which seems misguided and leads to an illogical error message:
Instead, I believe priority should be given to the inner constraint T :> None and the error message should be that Any | None cannot be assigned to str as pyright does it (Code sample in pyright playground)
Sandbox Link
See Also:
Reactions are currently unavailable
Metadata
Metadata
Assignees
Labels
contextual-typingissues related to contextual typingissues related to contextual typingstaletypechecking