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
The type of __default= in dict.pop and dict.get doesn't look right #10293
Note the union with two type parameters as a type of __default=. This type is ambiguous if dict.pop is called with a value of type _VT. For example, given
d: dict[str, str]
d.pop("foo")
a type checker can choose any value for _T, since str is a subtype of str | _T regardless of what _T is.
It seems the union was introduced in 2fdcd2e, which unfortunately does not seem to give any reasoning for that. I think we should drop it and use _T instead in both dict.pop and dict.get (and similarly for MutableMapping), i.e.
I'm a little confused. In your example, why would d.pop("foo") match the def pop(self, __key: _KT, __default: _VT | _T) -> _VT | _T: ... overload (since __default does not have a default value in that overload)?
But I'm fine with anything as long as the following three cases type check:
from typing import assert_type
def f(d: dict[str, int]):
assert_type(d.pop("key"), int)
assert_type(d.pop("key", 1), int)
assert_type(d.pop("key", None), int | None)
Activity
JelleZijlstra commentedon Jun 9, 2023
Yes, I think you're right. Feel free to send a PR!
superbobry commentedon Jun 9, 2023
Will do!
hauntsaninja commentedon Jun 9, 2023
I'm a little confused. In your example, why would
d.pop("foo")match thedef pop(self, __key: _KT, __default: _VT | _T) -> _VT | _T: ...overload (since__defaultdoes not have a default value in that overload)?But I'm fine with anything as long as the following three cases type check:
superbobry commentedon Jun 9, 2023
Ooops, sorry. I was meaning to write
d.pop("foo", "bar"). I've updated the type to bedict[str, str]to minimize the edits to the original post.I think all three cases should type check with the proposed definition.
superbobry commentedon Jun 9, 2023
Okay, another correction. The right signature for seems to be
because a
dictcan return a value from an existing entry.Remove unnecessary union in the default type in .get() and .pop() met…
Remove unnecessary union in the default type in .get() and .pop() met…
Remove unnecessary union in the default type in .get() and .pop() met…
Remove unnecessary union in the default type in .get() and .pop() met…
More precise overloads for get/pop methods
More precise overloads for get/pop methods
More precise overloads for get/pop methods (#10501)