diff --git a/stdlib/@tests/stubtest_allowlists/py313.txt b/stdlib/@tests/stubtest_allowlists/py313.txt index 3929791d4ef4..e0f2f3903be2 100644 --- a/stdlib/@tests/stubtest_allowlists/py313.txt +++ b/stdlib/@tests/stubtest_allowlists/py313.txt @@ -105,9 +105,6 @@ multiprocessing.managers._BaseDictProxy.keys multiprocessing.managers._BaseDictProxy.popitem multiprocessing.managers._BaseDictProxy.values -# To match `dict`, we lie about the runtime, but use overloads to match the correct behavior -types.MappingProxyType.get - typing_extensions.Protocol # Super-special typing primitive diff --git a/stdlib/@tests/stubtest_allowlists/py314.txt b/stdlib/@tests/stubtest_allowlists/py314.txt index 64a6fa7d2752..e59a8b059fd6 100644 --- a/stdlib/@tests/stubtest_allowlists/py314.txt +++ b/stdlib/@tests/stubtest_allowlists/py314.txt @@ -139,9 +139,6 @@ multiprocessing.managers._BaseDictProxy.keys multiprocessing.managers._BaseDictProxy.popitem multiprocessing.managers._BaseDictProxy.values -# To match `dict`, we lie about the runtime, but use overloads to match the correct behavior -types.MappingProxyType.get - typing_extensions.Protocol # Super-special typing primitive diff --git a/stdlib/@tests/test_cases/builtins/check_dict.py b/stdlib/@tests/test_cases/builtins/check_dict.py index fe74ad49408e..2ac86597cef7 100644 --- a/stdlib/@tests/test_cases/builtins/check_dict.py +++ b/stdlib/@tests/test_cases/builtins/check_dict.py @@ -71,34 +71,35 @@ def test_iterable_tuple_overload(x: Iterable[tuple[int, str]]) -> dict[int, str] int_value = 1 assert_type(d_any["key"], Any) -assert_type(d_any.get("key"), Union[Any, None]) -assert_type(d_any.get("key", None), Union[Any, None]) +assert_type(d_any.get("key"), Any | None) +assert_type(d_any.get("key", None), Any | None) assert_type(d_any.get("key", any_value), Any) -assert_type(d_any.get("key", str_value), Any) -assert_type(d_any.get("key", int_value), Any) +assert_type(d_any.get("key", str_value), Any | str) +assert_type(d_any.get("key", int_value), Any | int) assert_type(d_str["key"], str) -assert_type(d_str.get("key"), Union[str, None]) -assert_type(d_str.get("key", None), Union[str, None]) +assert_type(d_str.get("key"), str | None) +assert_type(d_str.get("key", None), str | None) # Pyright has str instead of Any here -assert_type(d_str.get("key", any_value), Any) # pyright: ignore[reportAssertTypeFailure] +assert_type(d_str.get("key", any_value), str | Any) assert_type(d_str.get("key", str_value), str) -assert_type(d_str.get("key", int_value), Union[str, int]) +assert_type(d_str.get("key", int_value), str | int) # Now with context! +# Note: One would expect 'assignment' rather than 'arg-type' error code, +# but this is a bug in mypy (https://github.com/python/mypy/issues/20576) result: str result = d_any["key"] result = d_any.get("key") # type: ignore[assignment] -result = d_any.get("key", None) # type: ignore[assignment] +result = d_any.get("key", None) # type: ignore[arg-type] result = d_any.get("key", any_value) result = d_any.get("key", str_value) -result = d_any.get("key", int_value) +result = d_any.get("key", int_value) # type: ignore[arg-type] result = d_str["key"] result = d_str.get("key") # type: ignore[assignment] -result = d_str.get("key", None) # type: ignore[assignment] -# Pyright has str | None here, see https://github.com/microsoft/pyright/discussions/9570 -result = d_str.get("key", any_value) # pyright: ignore[reportAssignmentType] +result = d_str.get("key", None) # type: ignore[arg-type] +result = d_str.get("key", any_value) result = d_str.get("key", str_value) result = d_str.get("key", int_value) # type: ignore[arg-type] @@ -140,11 +141,15 @@ def test8() -> str: def test9() -> str: - return d_str.get("key", None) # type: ignore[return-value] + # Note: One would expect 'return-value' rather than 'arg-type' error code, + # but this is a bug in mypy (https://github.com/python/mypy/issues/20576) + return d_str.get("key", None) # type: ignore[arg-type] -def test10() -> str: - return d_str.get("key", any_value) # type: ignore[no-any-return] +# Pyright doesn't have a version of no-any-return, +# and mypy doesn't have a type: ignore that pyright will ignore. +# def test10() -> str: +# return d_str.get("key", any_value) # mypy: ignore[no-any-return] def test11() -> str: diff --git a/stdlib/builtins.pyi b/stdlib/builtins.pyi index 0fe6d9a69651..20af2ef6b7ce 100644 --- a/stdlib/builtins.pyi +++ b/stdlib/builtins.pyi @@ -1330,9 +1330,7 @@ class dict(MutableMapping[_KT, _VT]): # Positional-only in dict, but not in MutableMapping @overload # type: ignore[override] - def get(self, key: _KT, default: None = None, /) -> _VT | None: ... - @overload - def get(self, key: _KT, default: _VT, /) -> _VT: ... + def get(self, key: _KT, /) -> _VT | None: ... @overload def get(self, key: _KT, default: _T, /) -> _VT | _T: ... diff --git a/stdlib/collections/__init__.pyi b/stdlib/collections/__init__.pyi index d9c2e342c587..58caefe65479 100644 --- a/stdlib/collections/__init__.pyi +++ b/stdlib/collections/__init__.pyi @@ -111,9 +111,7 @@ class UserDict(MutableMapping[_KT, _VT]): if sys.version_info >= (3, 12): @overload - def get(self, key: _KT, default: None = None) -> _VT | None: ... - @overload - def get(self, key: _KT, default: _VT) -> _VT: ... + def get(self, key: _KT) -> _VT | None: ... @overload def get(self, key: _KT, default: _T) -> _VT | _T: ... @@ -504,9 +502,7 @@ class ChainMap(MutableMapping[_KT, _VT]): def __contains__(self, key: object) -> bool: ... @overload - def get(self, key: _KT, default: None = None) -> _VT | None: ... - @overload - def get(self, key: _KT, default: _VT) -> _VT: ... + def get(self, key: _KT) -> _VT | None: ... @overload def get(self, key: _KT, default: _T) -> _VT | _T: ... diff --git a/stdlib/importlib/metadata/__init__.pyi b/stdlib/importlib/metadata/__init__.pyi index 866fd969e2fe..08d7df8766c3 100644 --- a/stdlib/importlib/metadata/__init__.pyi +++ b/stdlib/importlib/metadata/__init__.pyi @@ -164,9 +164,7 @@ if sys.version_info < (3, 12): def __getitem__(self, name: _KT) -> _VT: ... @overload - def get(self, name: _KT, default: None = None) -> _VT | None: ... - @overload - def get(self, name: _KT, default: _VT) -> _VT: ... + def get(self, name: _KT) -> _VT | None: ... @overload def get(self, name: _KT, default: _T) -> _VT | _T: ... diff --git a/stdlib/os/__init__.pyi b/stdlib/os/__init__.pyi index 913e0833665a..0f708dd92d11 100644 --- a/stdlib/os/__init__.pyi +++ b/stdlib/os/__init__.pyi @@ -721,9 +721,7 @@ class _Environ(MutableMapping[AnyStr, AnyStr], Generic[AnyStr]): ) -> None: ... @overload - def get(self, key: AnyStr, default: None = None) -> AnyStr | None: ... - @overload - def get(self, key: AnyStr, default: AnyStr) -> AnyStr: ... + def get(self, key: AnyStr) -> AnyStr | None: ... @overload def get(self, key: AnyStr, default: _T) -> AnyStr | _T: ... diff --git a/stdlib/types.pyi b/stdlib/types.pyi index b9771ffc72da..75bd86c62759 100644 --- a/stdlib/types.pyi +++ b/stdlib/types.pyi @@ -283,8 +283,6 @@ class MappingProxyType(Mapping[_KT_co, _VT_co]): # type: ignore[type-var] # py @overload def get(self, key: _KT_co, /) -> _VT_co | None: ... # type: ignore[misc] # pyright: ignore[reportGeneralTypeIssues] # Covariant type as parameter @overload - def get(self, key: _KT_co, default: _VT_co, /) -> _VT_co: ... # type: ignore[misc] # pyright: ignore[reportGeneralTypeIssues] # Covariant type as parameter - @overload def get(self, key: _KT_co, default: _T2, /) -> _VT_co | _T2: ... # type: ignore[misc] # pyright: ignore[reportGeneralTypeIssues] # Covariant type as parameter def __class_getitem__(cls, item: Any, /) -> GenericAlias: ... diff --git a/stdlib/typing.pyi b/stdlib/typing.pyi index 2018a835c632..e4d2559423cf 100644 --- a/stdlib/typing.pyi +++ b/stdlib/typing.pyi @@ -814,8 +814,6 @@ class Mapping(Collection[_KT], Generic[_KT, _VT_co]): @overload def get(self, key: _KT, /) -> _VT_co | None: ... @overload - def get(self, key: _KT, default: _VT_co, /) -> _VT_co: ... # type: ignore[misc] # pyright: ignore[reportGeneralTypeIssues] # Covariant type as parameter - @overload def get(self, key: _KT, default: _T, /) -> _VT_co | _T: ... def items(self) -> ItemsView[_KT, _VT_co]: ... diff --git a/stdlib/weakref.pyi b/stdlib/weakref.pyi index 3308ae42e1cf..78cbb0a43129 100644 --- a/stdlib/weakref.pyi +++ b/stdlib/weakref.pyi @@ -101,9 +101,7 @@ class WeakValueDictionary(MutableMapping[_KT, _VT]): def __deepcopy__(self, memo: Any) -> Self: ... @overload - def get(self, key: _KT, default: None = None) -> _VT | None: ... - @overload - def get(self, key: _KT, default: _VT) -> _VT: ... + def get(self, key: _KT) -> _VT | None: ... @overload def get(self, key: _KT, default: _T) -> _VT | _T: ... @@ -161,9 +159,7 @@ class WeakKeyDictionary(MutableMapping[_KT, _VT]): def __deepcopy__(self, memo: Any) -> Self: ... @overload - def get(self, key: _KT, default: None = None) -> _VT | None: ... - @overload - def get(self, key: _KT, default: _VT) -> _VT: ... + def get(self, key: _KT) -> _VT | None: ... @overload def get(self, key: _KT, default: _T) -> _VT | _T: ... diff --git a/stubs/WebOb/webob/cookies.pyi b/stubs/WebOb/webob/cookies.pyi index 3bda178fc43f..6947eb73ba5b 100644 --- a/stubs/WebOb/webob/cookies.pyi +++ b/stubs/WebOb/webob/cookies.pyi @@ -36,9 +36,7 @@ class RequestCookies(MutableMapping[str, str]): def __getitem__(self, name: str) -> str: ... @overload - def get(self, name: str, default: None = None) -> str | None: ... - @overload - def get(self, name: str, default: str) -> str: ... + def get(self, name: str) -> str | None: ... @overload def get(self, name: str, default: _T) -> str | _T: ... diff --git a/stubs/WebOb/webob/multidict.pyi b/stubs/WebOb/webob/multidict.pyi index 4272d2197564..9302d464ede3 100644 --- a/stubs/WebOb/webob/multidict.pyi +++ b/stubs/WebOb/webob/multidict.pyi @@ -51,9 +51,7 @@ class MultiDict(MutableMapping[_KT, _VT]): def add(self, key: _KT, value: _VT) -> None: ... @overload - def get(self, key: _KT, default: None = None) -> _VT | None: ... - @overload - def get(self, key: _KT, default: _VT) -> _VT: ... + def get(self, key: _KT) -> _VT | None: ... @overload def get(self, key: _KT, default: _T) -> _VT | _T: ... diff --git a/stubs/boltons/boltons/cacheutils.pyi b/stubs/boltons/boltons/cacheutils.pyi index 978da569d563..66f4130c8bd1 100644 --- a/stubs/boltons/boltons/cacheutils.pyi +++ b/stubs/boltons/boltons/cacheutils.pyi @@ -25,11 +25,9 @@ class LRI(dict[_KT, _VT]): def __getitem__(self, key: _KT) -> _VT: ... @overload - def get(self, key: _KT, default: None = None) -> _VT | None: ... + def get(self, key: _KT) -> _VT | None: ... @overload - def get(self, key: _KT, default: _VT) -> _VT: ... - @overload - def get(self, key: _KT, default: _T) -> _T | _VT: ... + def get(self, key: _KT, default: _T) -> _VT | _T: ... def __delitem__(self, key: _KT) -> None: ... diff --git a/stubs/grpcio/grpc/aio/__init__.pyi b/stubs/grpcio/grpc/aio/__init__.pyi index 82ef20f91bf4..52509fa7ce31 100644 --- a/stubs/grpcio/grpc/aio/__init__.pyi +++ b/stubs/grpcio/grpc/aio/__init__.pyi @@ -458,9 +458,7 @@ class Metadata(Mapping[_MetadataKey, _MetadataValue]): def __iter__(self) -> Iterator[_MetadataKey]: ... @overload - def get(self, key: _MetadataKey, default: None = None) -> _MetadataValue | None: ... - @overload - def get(self, key: _MetadataKey, default: _MetadataValue) -> _MetadataValue: ... + def get(self, key: _MetadataKey) -> _MetadataValue | None: ... @overload def get(self, key: _MetadataKey, default: _T) -> _MetadataValue | _T: ... diff --git a/stubs/inifile/inifile.pyi b/stubs/inifile/inifile.pyi index db23bc4e06ce..21aba3017390 100644 --- a/stubs/inifile/inifile.pyi +++ b/stubs/inifile/inifile.pyi @@ -69,9 +69,7 @@ class IniData(MutableMapping[str, str]): def __len__(self) -> int: ... @overload - def get(self, name: str, default: None = None) -> str | None: ... - @overload - def get(self, name: str, default: str) -> str: ... + def get(self, name: str) -> str | None: ... @overload def get(self, name: str, default: _T) -> str | _T: ... diff --git a/stubs/protobuf/google/protobuf/internal/containers.pyi b/stubs/protobuf/google/protobuf/internal/containers.pyi index bb48c5bb6ddd..4f4d96186a01 100644 --- a/stubs/protobuf/google/protobuf/internal/containers.pyi +++ b/stubs/protobuf/google/protobuf/internal/containers.pyi @@ -85,9 +85,7 @@ class ScalarMap(MutableMapping[_K, _ScalarV]): def __getitem__(self, key: _K) -> _ScalarV: ... @overload - def get(self, key: _K, default: None = None) -> _ScalarV | None: ... - @overload - def get(self, key: _K, default: _ScalarV) -> _ScalarV: ... + def get(self, key: _K) -> _ScalarV | None: ... @overload def get(self, key: _K, default: _T) -> _ScalarV | _T: ... @@ -115,9 +113,7 @@ class MessageMap(MutableMapping[_K, _MessageV]): def get_or_create(self, key: _K) -> _MessageV: ... @overload - def get(self, key: _K, default: None = None) -> _MessageV | None: ... - @overload - def get(self, key: _K, default: _MessageV) -> _MessageV: ... + def get(self, key: _K) -> _MessageV | None: ... @overload def get(self, key: _K, default: _T) -> _MessageV | _T: ... diff --git a/stubs/setuptools/setuptools/__init__.pyi b/stubs/setuptools/setuptools/__init__.pyi index 5b2c77ab99f2..43d652d8b08e 100644 --- a/stubs/setuptools/setuptools/__init__.pyi +++ b/stubs/setuptools/setuptools/__init__.pyi @@ -38,6 +38,7 @@ _CommandT = TypeVar("_CommandT", bound=_Command) _DistributionT = TypeVar("_DistributionT", bound=_Distribution, default=Distribution) _KT = TypeVar("_KT") _VT_co = TypeVar("_VT_co", covariant=True) +_T = TypeVar("_T") __all__ = [ "setup", @@ -58,7 +59,11 @@ __version__: str @type_check_only class _DictLike(Protocol[_KT, _VT_co]): # See note about using _VT_co instead of Any - def get(self, key: _KT, default: Any | None = None, /) -> _VT_co | None: ... + @overload + def get(self, key: _KT, /) -> _VT_co | None: ... + @overload + def get(self, key: _KT, default: _T, /) -> _VT_co | _T: ... + def items(self) -> ItemsView[_KT, _VT_co]: ... def keys(self) -> Iterable[_KT]: ... def __getitem__(self, key: _KT, /) -> _VT_co: ...