Skip to content

Commit e3aa188

Browse files
allow object type in dict.get and dict.pop
1 parent 843c1fd commit e3aa188

File tree

7 files changed

+29
-17
lines changed

7 files changed

+29
-17
lines changed

stdlib/@tests/test_cases/builtins/check_dict.py

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
from __future__ import annotations
22

33
import os
4-
from typing import Any, Dict, Generic, Iterable, Mapping, TypeVar, Union
4+
from typing import Any, Dict, Generic, Iterable, Literal, Mapping, TypeVar, Union
55
from typing_extensions import Self, assert_type
66

77
###################################################################
@@ -103,6 +103,16 @@ def test_iterable_tuple_overload(x: Iterable[tuple[int, str]]) -> dict[int, str]
103103
result = d_str.get("key", int_value) # type: ignore[arg-type]
104104

105105

106+
def test_dict_signature_overlapping_type(d: dict[Literal["foo", "bar"], int], key: str) -> None:
107+
# Note: annotations also allow using keys of a disjoint type (e.g., int),
108+
# linters / type checkers are free to issue warnings in such cases.
109+
# statically, a .get(arg) is superfluous if the intersection of the
110+
# dict key type and the argument type is empty.
111+
# So we only test a case with non-empty intersection here.
112+
d.get(key)
113+
d.pop(key)
114+
115+
106116
# Return values also make things weird
107117

108118
# Pyright doesn't have a version of no-any-return,

stdlib/builtins.pyi

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1220,17 +1220,19 @@ class dict(MutableMapping[_KT, _VT]):
12201220
def fromkeys(cls, iterable: Iterable[_T], value: _S, /) -> dict[_T, _S]: ...
12211221
# Positional-only in dict, but not in MutableMapping
12221222
@overload # type: ignore[override]
1223-
def get(self, key: _KT, default: None = None, /) -> _VT | None: ...
1223+
def get(self, key: object, default: None = None, /) -> _VT | None: ...
12241224
@overload
1225-
def get(self, key: _KT, default: _VT, /) -> _VT: ...
1225+
def get(self, key: object, default: _VT, /) -> _VT: ...
12261226
@overload
1227-
def get(self, key: _KT, default: _T, /) -> _VT | _T: ...
1227+
def get(self, key: object, default: _T, /) -> _VT | _T: ...
1228+
# dict.pop allows arbitrary types, which matches runtime semantics.
1229+
# linters may choose to warn if the given type does not overlap with the key type
12281230
@overload
1229-
def pop(self, key: _KT, /) -> _VT: ...
1231+
def pop(self, key: object, /) -> _VT: ...
12301232
@overload
1231-
def pop(self, key: _KT, default: _VT, /) -> _VT: ...
1233+
def pop(self, key: object, default: _VT, /) -> _VT: ...
12321234
@overload
1233-
def pop(self, key: _KT, default: _T, /) -> _VT | _T: ...
1235+
def pop(self, key: object, default: _T, /) -> _VT | _T: ...
12341236
def __len__(self) -> int: ...
12351237
def __getitem__(self, key: _KT, /) -> _VT: ...
12361238
def __setitem__(self, key: _KT, value: _VT, /) -> None: ...

stdlib/collections/__init__.pyi

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -382,11 +382,11 @@ class OrderedDict(dict[_KT, _VT]):
382382
def setdefault(self, key: _KT, default: _VT) -> _VT: ...
383383
# Same as dict.pop, but accepts keyword arguments
384384
@overload
385-
def pop(self, key: _KT) -> _VT: ...
385+
def pop(self, key: object) -> _VT: ...
386386
@overload
387-
def pop(self, key: _KT, default: _VT) -> _VT: ...
387+
def pop(self, key: object, default: _VT) -> _VT: ...
388388
@overload
389-
def pop(self, key: _KT, default: _T) -> _VT | _T: ...
389+
def pop(self, key: object, default: _T) -> _VT | _T: ...
390390
def __eq__(self, value: object, /) -> bool: ...
391391
@overload
392392
def __or__(self, value: dict[_KT, _VT], /) -> Self: ...

stdlib/mailbox.pyi

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -88,7 +88,7 @@ class Mailbox(Generic[_MessageT]):
8888
def __len__(self) -> int: ...
8989
def clear(self) -> None: ...
9090
@overload
91-
def pop(self, key: str, default: None = None) -> _MessageT | None: ...
91+
def pop(self, key: str) -> _MessageT | None: ...
9292
@overload
9393
def pop(self, key: str, default: _T) -> _MessageT | _T: ...
9494
def popitem(self) -> tuple[str, _MessageT]: ...

stubs/boltons/boltons/cacheutils.pyi

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -31,9 +31,9 @@ class LRI(dict[_KT, _VT]):
3131
def get(self, key: _KT, default: _T) -> _T | _VT: ...
3232
def __delitem__(self, key: _KT) -> None: ...
3333
@overload
34-
def pop(self, key: _KT) -> _VT: ...
34+
def pop(self, key: object) -> _VT: ...
3535
@overload
36-
def pop(self, key: _KT, default: _T) -> _T | _VT: ...
36+
def pop(self, key: object, default: _T) -> _T | _VT: ...
3737
def popitem(self) -> tuple[_KT, _VT]: ...
3838
def clear(self) -> None: ...
3939
def copy(self) -> Self: ...

stubs/boltons/boltons/dictutils.pyi

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,7 @@ class OneToOne(dict[_KT, _VT]):
5555
inv: OneToOne[_VT, _KT]
5656
def clear(self) -> None: ...
5757
def copy(self) -> Self: ...
58-
def pop(self, key: _KT, default: _VT | _T = ...) -> _VT | _T: ...
58+
def pop(self, key: object, default: _VT | _T = ...) -> _VT | _T: ...
5959
def popitem(self) -> tuple[_KT, _VT]: ...
6060
def setdefault(self, key: _KT, default: _VT | None = None) -> _VT: ...
6161
@classmethod

stubs/yt-dlp/yt_dlp/utils/networking.pyi

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -21,11 +21,11 @@ class HTTPHeaderDict(dict[str, str]):
2121
@overload
2222
def get(self, key: str, /, default: type[NO_DEFAULT] | _T = ...) -> str | _T | type[NO_DEFAULT]: ...
2323
@overload
24-
def pop(self, key: str, /) -> str: ...
24+
def pop(self, key: object, /) -> str: ...
2525
@overload
26-
def pop(self, key: str, /, default: _T) -> str | _T: ...
26+
def pop(self, key: object, /, default: _T) -> str | _T: ...
2727
@overload
28-
def pop(self, key: str, /, default: type[NO_DEFAULT] | _T | str = ...) -> str | _T | type[NO_DEFAULT]: ...
28+
def pop(self, key: object, /, default: type[NO_DEFAULT] | _T | str = ...) -> str | _T | type[NO_DEFAULT]: ...
2929
@overload
3030
def setdefault(self, key: str, /) -> str: ...
3131
@overload

0 commit comments

Comments
 (0)