Skip to content

Permissive behavior on Mapping.get, MutableMapping.pop, and some common mapping types. #12345

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 5 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 5 additions & 5 deletions stdlib/builtins.pyi
Original file line number Diff line number Diff line change
Expand Up @@ -1095,17 +1095,17 @@ class dict(MutableMapping[_KT, _VT]):
def fromkeys(cls, iterable: Iterable[_T], value: _S, /) -> dict[_T, _S]: ...
# Positional-only in dict, but not in MutableMapping
@overload # type: ignore[override]
def get(self, key: _KT, /) -> _VT | None: ...
def get(self, key: object, /) -> _VT | None: ...
@overload
def get(self, key: _KT, default: _VT, /) -> _VT: ...
def get(self, key: object, default: _VT, /) -> _VT: ...
@overload
def get(self, key: _KT, default: _T, /) -> _VT | _T: ...
def get(self, key: object, default: _T, /) -> _VT | _T: ...
@overload
def pop(self, key: _KT, /) -> _VT: ...
@overload
def pop(self, key: _KT, default: _VT, /) -> _VT: ...
def pop(self, key: object, default: _VT, /) -> _VT: ...
@overload
def pop(self, key: _KT, default: _T, /) -> _VT | _T: ...
def pop(self, key: object, default: _T, /) -> _VT | _T: ...
def __len__(self) -> int: ...
def __getitem__(self, key: _KT, /) -> _VT: ...
def __setitem__(self, key: _KT, value: _VT, /) -> None: ...
Expand Down
16 changes: 8 additions & 8 deletions stdlib/collections/__init__.pyi
Original file line number Diff line number Diff line change
Expand Up @@ -110,9 +110,9 @@ class UserDict(MutableMapping[_KT, _VT]):
def __ior__(self, other: Iterable[tuple[_KT, _VT]]) -> Self: ...
if sys.version_info >= (3, 12):
@overload
def get(self, key: _KT, default: None = None) -> _VT | None: ...
def get(self, key: object, default: None = None) -> _VT | None: ...
@overload
def get(self, key: _KT, default: _T) -> _VT | _T: ...
def get(self, key: object, default: _T) -> _VT | _T: ...

class UserList(MutableSequence[_T]):
data: list[_T]
Expand Down Expand Up @@ -382,9 +382,9 @@ class OrderedDict(dict[_KT, _VT], Reversible[_KT], Generic[_KT, _VT]):
@overload
def pop(self, key: _KT) -> _VT: ...
@overload
def pop(self, key: _KT, default: _VT) -> _VT: ...
def pop(self, key: object, default: _VT) -> _VT: ...
@overload
def pop(self, key: _KT, default: _T) -> _VT | _T: ...
def pop(self, key: object, default: _T) -> _VT | _T: ...
def __eq__(self, value: object, /) -> bool: ...
if sys.version_info >= (3, 9):
@overload
Expand Down Expand Up @@ -457,9 +457,9 @@ class ChainMap(MutableMapping[_KT, _VT]):
def __len__(self) -> int: ...
def __contains__(self, key: object) -> bool: ...
@overload
def get(self, key: _KT, default: None = None) -> _VT | None: ...
def get(self, key: object, default: None = None) -> _VT | None: ...
@overload
def get(self, key: _KT, default: _T) -> _VT | _T: ...
def get(self, key: object, default: _T) -> _VT | _T: ...
def __missing__(self, key: _KT) -> _VT: ... # undocumented
def __bool__(self) -> bool: ...
# Keep ChainMap.setdefault in line with MutableMapping.setdefault, modulo positional-only differences.
Expand All @@ -470,9 +470,9 @@ class ChainMap(MutableMapping[_KT, _VT]):
@overload
def pop(self, key: _KT) -> _VT: ...
@overload
def pop(self, key: _KT, default: _VT) -> _VT: ...
def pop(self, key: object, default: _VT) -> _VT: ...
@overload
def pop(self, key: _KT, default: _T) -> _VT | _T: ...
def pop(self, key: object, default: _T) -> _VT | _T: ...
def copy(self) -> Self: ...
__copy__ = copy
# All arguments to `fromkeys` are passed to `dict.fromkeys` at runtime, so the signature should be kept in line with `dict.fromkeys`.
Expand Down
3 changes: 2 additions & 1 deletion stdlib/contextvars.pyi
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,8 @@ def copy_context() -> Context: ...
@final
class Context(Mapping[ContextVar[Any], Any]):
def __init__(self) -> None: ...
@overload
# incompatible with Mapping
@overload # type: ignore[override]
def get(self, key: ContextVar[_T], default: None = None, /) -> _T | None: ...
@overload
def get(self, key: ContextVar[_T], default: _T, /) -> _T: ...
Expand Down
5 changes: 3 additions & 2 deletions stdlib/importlib/metadata/__init__.pyi
Original file line number Diff line number Diff line change
Expand Up @@ -141,13 +141,14 @@ if sys.version_info >= (3, 10) and sys.version_info < (3, 12):
@overload
def get(self, name: _KT) -> _VT | None: ...
@overload
def get(self, name: _KT, default: _T) -> _VT | _T: ...
def get(self, name: object, default: _T) -> _VT | _T: ...
def __iter__(self) -> Iterator[_KT]: ...
def __contains__(self, *args: object) -> bool: ...
def keys(self) -> dict_keys[_KT, _VT]: ...
def values(self) -> dict_values[_KT, _VT]: ...

class SelectableGroups(Deprecated[str, EntryPoints], dict[str, EntryPoints]): # use as dict is deprecated since 3.10
# use as dict is deprecated since 3.10
class SelectableGroups(Deprecated[str, EntryPoints], dict[str, EntryPoints]): # type: ignore[misc]
@classmethod
def load(cls, eps: Iterable[EntryPoint]) -> Self: ...
@property
Expand Down
8 changes: 4 additions & 4 deletions stdlib/multiprocessing/managers.pyi
Original file line number Diff line number Diff line change
Expand Up @@ -71,15 +71,15 @@ class DictProxy(BaseProxy, MutableMapping[_KT, _VT]):
@overload # type: ignore[override]
def get(self, key: _KT, /) -> _VT | None: ...
@overload
def get(self, key: _KT, default: _VT, /) -> _VT: ...
def get(self, key: object, default: _VT, /) -> _VT: ...
@overload
def get(self, key: _KT, default: _T, /) -> _VT | _T: ...
def get(self, key: object, default: _T, /) -> _VT | _T: ...
@overload
def pop(self, key: _KT, /) -> _VT: ...
@overload
def pop(self, key: _KT, default: _VT, /) -> _VT: ...
def pop(self, key: object, default: _VT, /) -> _VT: ...
@overload
def pop(self, key: _KT, default: _T, /) -> _VT | _T: ...
def pop(self, key: object, default: _T, /) -> _VT | _T: ...
def keys(self) -> list[_KT]: ... # type: ignore[override]
def items(self) -> list[tuple[_KT, _VT]]: ... # type: ignore[override]
def values(self) -> list[_VT]: ... # type: ignore[override]
Expand Down
8 changes: 4 additions & 4 deletions stdlib/typing.pyi
Original file line number Diff line number Diff line change
Expand Up @@ -694,9 +694,9 @@ class Mapping(Collection[_KT], Generic[_KT, _VT_co]):
def __getitem__(self, key: _KT, /) -> _VT_co: ...
# Mixin methods
@overload
def get(self, key: _KT, /) -> _VT_co | None: ...
def get(self, key: object, /) -> _VT_co | None: ...
@overload
def get(self, key: _KT, /, default: _VT_co | _T) -> _VT_co | _T: ...
def get(self, key: object, /, default: _VT_co | _T) -> _VT_co | _T: ...
def items(self) -> ItemsView[_KT, _VT_co]: ...
def keys(self) -> KeysView[_KT]: ...
def values(self) -> ValuesView[_VT_co]: ...
Expand All @@ -712,9 +712,9 @@ class MutableMapping(Mapping[_KT, _VT]):
@overload
def pop(self, key: _KT, /) -> _VT: ...
@overload
def pop(self, key: _KT, /, default: _VT) -> _VT: ...
def pop(self, key: object, /, default: _VT) -> _VT: ...
@overload
def pop(self, key: _KT, /, default: _T) -> _VT | _T: ...
def pop(self, key: object, /, default: _T) -> _VT | _T: ...
def popitem(self) -> tuple[_KT, _VT]: ...
# This overload should be allowed only if the value type is compatible with None.
#
Expand Down
16 changes: 8 additions & 8 deletions stdlib/weakref.pyi
Original file line number Diff line number Diff line change
Expand Up @@ -76,9 +76,9 @@ class WeakValueDictionary(MutableMapping[_KT, _VT]):
__copy__ = copy
def __deepcopy__(self, memo: Any) -> Self: ...
@overload
def get(self, key: _KT, default: None = None) -> _VT | None: ...
def get(self, key: object, default: None = None) -> _VT | None: ...
@overload
def get(self, key: _KT, default: _T) -> _VT | _T: ...
def get(self, key: object, default: _T) -> _VT | _T: ...
# These are incompatible with Mapping
def keys(self) -> Iterator[_KT]: ... # type: ignore[override]
def values(self) -> Iterator[_VT]: ... # type: ignore[override]
Expand All @@ -89,9 +89,9 @@ class WeakValueDictionary(MutableMapping[_KT, _VT]):
@overload
def pop(self, key: _KT) -> _VT: ...
@overload
def pop(self, key: _KT, default: _VT) -> _VT: ...
def pop(self, key: object, default: _VT) -> _VT: ...
@overload
def pop(self, key: _KT, default: _T) -> _VT | _T: ...
def pop(self, key: object, default: _T) -> _VT | _T: ...
if sys.version_info >= (3, 9):
def __or__(self, other: Mapping[_T1, _T2]) -> WeakValueDictionary[_KT | _T1, _VT | _T2]: ...
def __ror__(self, other: Mapping[_T1, _T2]) -> WeakValueDictionary[_KT | _T1, _VT | _T2]: ...
Expand Down Expand Up @@ -121,9 +121,9 @@ class WeakKeyDictionary(MutableMapping[_KT, _VT]):
__copy__ = copy
def __deepcopy__(self, memo: Any) -> Self: ...
@overload
def get(self, key: _KT, default: None = None) -> _VT | None: ...
def get(self, key: object, default: None = None) -> _VT | None: ...
@overload
def get(self, key: _KT, default: _T) -> _VT | _T: ...
def get(self, key: object, default: _T) -> _VT | _T: ...
# These are incompatible with Mapping
def keys(self) -> Iterator[_KT]: ... # type: ignore[override]
def values(self) -> Iterator[_VT]: ... # type: ignore[override]
Expand All @@ -137,9 +137,9 @@ class WeakKeyDictionary(MutableMapping[_KT, _VT]):
@overload
def pop(self, key: _KT) -> _VT: ...
@overload
def pop(self, key: _KT, default: _VT) -> _VT: ...
def pop(self, key: object, default: _VT) -> _VT: ...
@overload
def pop(self, key: _KT, default: _T) -> _VT | _T: ...
def pop(self, key: object, default: _T) -> _VT | _T: ...
if sys.version_info >= (3, 9):
def __or__(self, other: Mapping[_T1, _T2]) -> WeakKeyDictionary[_KT | _T1, _VT | _T2]: ...
def __ror__(self, other: Mapping[_T1, _T2]) -> WeakKeyDictionary[_KT | _T1, _VT | _T2]: ...
Expand Down
4 changes: 2 additions & 2 deletions stubs/WebOb/webob/cookies.pyi
Original file line number Diff line number Diff line change
Expand Up @@ -25,9 +25,9 @@ class RequestCookies(MutableMapping[str, str]):
def __setitem__(self, name: str, value: str) -> None: ...
def __getitem__(self, name: str) -> str: ...
@overload
def get(self, name: str, default: None = None) -> str | None: ...
def get(self, name: object, default: None = None) -> str | None: ...
@overload
def get(self, name: str, default: str | _T) -> str | _T: ...
def get(self, name: object, default: str | _T) -> str | _T: ...
def __delitem__(self, name: str) -> None: ...
def keys(self) -> KeysView[str]: ...
def values(self) -> ValuesView[str]: ...
Expand Down
8 changes: 4 additions & 4 deletions stubs/WebOb/webob/multidict.pyi
Original file line number Diff line number Diff line change
Expand Up @@ -29,9 +29,9 @@ class MultiDict(MutableMapping[_KT, _VT]):
def __setitem__(self, key: _KT, value: _VT) -> None: ...
def add(self, key: _KT, value: _VT) -> None: ...
@overload
def get(self, key: _KT) -> _VT | None: ...
def get(self, key: object) -> _VT | None: ...
@overload
def get(self, key: _KT, default: _T) -> _VT | _T: ...
def get(self, key: object, default: _T) -> _VT | _T: ...
def getall(self, key: _KT) -> list[_VT]: ...
def getone(self, key: _KT) -> _VT: ...
def mixed(self) -> dict[_KT, _VT | list[_VT]]: ...
Expand All @@ -48,7 +48,7 @@ class MultiDict(MutableMapping[_KT, _VT]):
@overload
def pop(self, key: _KT) -> _VT: ...
@overload
def pop(self, key: _KT, default: _T) -> _VT | _T: ...
def pop(self, key: object, default: _T) -> _VT | _T: ...
def popitem(self) -> tuple[_KT, _VT]: ...
@overload # type: ignore[override]
def update(self, m: Collection[tuple[_KT, _VT]], /, **kwargs: _VT) -> None: ...
Expand Down Expand Up @@ -84,7 +84,7 @@ class NestedMultiDict(MultiDict[_KT, _VT]):
def __delitem__(self, key: _KT) -> None: ...
def clear(self) -> None: ...
def setdefault(self, key: _KT, default: _VT | None = ...) -> Any: ...
def pop(self, key: _KT, default: Any = ...) -> Any: ...
def pop(self, key: object, default: Any = ...) -> Any: ...
def popitem(self) -> tuple[_KT, _VT]: ...
def update(self, *args: Any, **kwargs: _VT) -> None: ...
def copy(self) -> MultiDict[_KT, _VT]: ... # type: ignore[override]
Expand Down
6 changes: 3 additions & 3 deletions stubs/boltons/boltons/cacheutils.pyi
Original file line number Diff line number Diff line change
Expand Up @@ -23,14 +23,14 @@ class LRI(dict[_KT, _VT]):
def __setitem__(self, key: _KT, value: _VT) -> None: ...
def __getitem__(self, key: _KT) -> _VT: ...
@overload
def get(self, key: _KT, default: None = None) -> _VT | None: ...
def get(self, key: object, default: None = None) -> _VT | None: ...
@overload
def get(self, key: _KT, default: _T) -> _T | _VT: ...
def get(self, key: object, default: _T) -> _T | _VT: ...
def __delitem__(self, key: _KT) -> None: ...
@overload
def pop(self, key: _KT) -> _VT: ...
@overload
def pop(self, key: _KT, default: _T) -> _T | _VT: ...
def pop(self, key: object, default: _T) -> _T | _VT: ...
def popitem(self) -> tuple[_KT, _VT]: ...
def clear(self) -> None: ...
def copy(self: Self) -> Self: ...
Expand Down
2 changes: 1 addition & 1 deletion stubs/boltons/boltons/dictutils.pyi
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ class OneToOne(dict[_KT, _VT]):
inv: dict[_VT, _KT]
def clear(self) -> None: ...
def copy(self) -> Self: ...
def pop(self, key: _KT, default: _VT | _T = ...) -> _VT | _T: ...
def pop(self, key: object, default: _VT | _T = ...) -> _VT | _T: ...
def popitem(self) -> tuple[_KT, _VT]: ...
def setdefault(self, key: _KT, default: _VT | None = None) -> _VT: ...
@classmethod
Expand Down
2 changes: 1 addition & 1 deletion stubs/cachetools/cachetools/__init__.pyi
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ class Cache(MutableMapping[_KT, _VT]):
@overload
def pop(self, key: _KT) -> _VT: ...
@overload
def pop(self, key: _KT, default: _VT | _T) -> _VT | _T: ...
def pop(self, key: object, default: _VT | _T) -> _VT | _T: ...
def setdefault(self, key: _KT, default: _VT | None = None) -> _VT: ...
@property
def maxsize(self) -> float: ...
Expand Down
2 changes: 1 addition & 1 deletion stubs/gdb/gdb/__init__.pyi
Original file line number Diff line number Diff line change
Expand Up @@ -170,7 +170,7 @@ class Type(Mapping[str, Field]):
def target(self) -> Type: ...
def template_argument(self, n: int, block: Block = ...) -> Type: ...
def optimized_out(self) -> Value: ...
def get(self, key: str, default: Any = ...) -> Field | Any: ...
def get(self, key: str, default: Any = ...) -> Field | Any: ... # type: ignore[override]
def has_key(self, key: str) -> bool: ...
def __len__(self) -> int: ...
def __getitem__(self, key: str) -> Field: ...
Expand Down
2 changes: 1 addition & 1 deletion stubs/icalendar/icalendar/caselessdict.pyi
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ class CaselessDict(OrderedDict[str, _VT]):
def __setitem__(self, key: str | bytes, value: _VT) -> None: ...
def __delitem__(self, key: str | bytes) -> None: ...
def __contains__(self, key: str | bytes) -> bool: ... # type: ignore[override]
@overload
@overload # type: ignore[override]
def get(self, key: str | bytes, default: None = None) -> _VT: ...
@overload
def get(self, key: str | bytes, default: _VT) -> _VT: ...
Expand Down
4 changes: 2 additions & 2 deletions stubs/inifile/inifile.pyi
Original file line number Diff line number Diff line change
Expand Up @@ -69,9 +69,9 @@ class IniData(MutableMapping[str, str]):
def to_dict(self) -> dict[str, str]: ...
def __len__(self) -> int: ...
@overload
def get(self, name: str) -> str | None: ...
def get(self, name: object) -> str | None: ...
@overload
def get(self, name: str, default: _T) -> str | _T: ...
def get(self, name: object, default: _T) -> str | _T: ...
@overload
def get_ascii(self, name: str) -> str | None: ...
@overload
Expand Down
8 changes: 4 additions & 4 deletions stubs/protobuf/google/protobuf/internal/containers.pyi
Original file line number Diff line number Diff line change
Expand Up @@ -70,9 +70,9 @@ class ScalarMap(MutableMapping[_K, _ScalarV]):
def __iter__(self) -> Iterator[_K]: ...
def __eq__(self, other: object) -> bool: ...
@overload
def get(self, key: _K, default: None = None) -> _ScalarV | None: ...
def get(self, key: object, default: None = None) -> _ScalarV | None: ...
@overload
def get(self, key: _K, default: _ScalarV | _T) -> _ScalarV | _T: ...
def get(self, key: object, default: _ScalarV | _T) -> _ScalarV | _T: ...
def MergeFrom(self: _M, other: _M): ...
def InvalidateIterators(self) -> None: ...
def GetEntryClass(self) -> GeneratedProtocolMessageType: ...
Expand All @@ -92,9 +92,9 @@ class MessageMap(MutableMapping[_K, _MessageV]):
def __iter__(self) -> Iterator[_K]: ...
def __eq__(self, other: object) -> bool: ...
@overload
def get(self, key: _K, default: None = None) -> _MessageV | None: ...
def get(self, key: object, default: None = None) -> _MessageV | None: ...
@overload
def get(self, key: _K, default: _MessageV | _T) -> _MessageV | _T: ...
def get(self, key: object, default: _MessageV | _T) -> _MessageV | _T: ...
def get_or_create(self, key: _K) -> _MessageV: ...
def MergeFrom(self: _M, other: _M): ...
def InvalidateIterators(self) -> None: ...
Expand Down
2 changes: 1 addition & 1 deletion stubs/redis/redis/client.pyi
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ NEVER_DECODE: str
class CaseInsensitiveDict(dict[_StrType, _VT]):
def __init__(self, data: SupportsItems[_StrType, _VT]) -> None: ...
def update(self, data: SupportsItems[_StrType, _VT]) -> None: ... # type: ignore[override]
@overload
@overload # type: ignore[override]
def get(self, k: _StrType, default: None = None) -> _VT | None: ...
@overload
def get(self, k: _StrType, default: _VT | _T) -> _VT | _T: ...
Expand Down
4 changes: 2 additions & 2 deletions stubs/requests/requests/structures.pyi
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,6 @@ class LookupDict(dict[str, _VT]):
def __getitem__(self, key: str) -> _VT | None: ... # type: ignore[override]
def __setattr__(self, attr: str, value: _VT, /) -> None: ...
@overload
def get(self, key: str, default: None = None) -> _VT | None: ...
def get(self, key: object, default: None = None) -> _VT | None: ...
@overload
def get(self, key: str, default: _D | _VT) -> _D | _VT: ...
def get(self, key: object, default: _D | _VT) -> _D | _VT: ...