From 7e0faae42366db22471e98110e4d118224770631 Mon Sep 17 00:00:00 2001 From: Sebastian Rittau Date: Fri, 19 Dec 2025 18:35:59 +0100 Subject: [PATCH 1/2] Add protocols `SequenceLike` and `MappingLike` `Sequence` and `Mapping` are commonly used in argument types. This can be problematic, since they are not protocols, making it impossible to safely duck type or mock them. Also, not all sequence- or mapping-like types derive from these ABCs at runtime, although in typeshed we often pretend they do. Ideally we'd be able to avoid this discrepancy in the far future. Finally, the ABCs sometimes make more API promises than their sub-classes fulfill. For example, `Mapping` arguments are keyword-or-positional, while its most important subtype `dict` only accepts positional arguments. These protocols have tighter guarantees. `SequenceLike` contains most, `MappingLike` all methods from their respective types, making them an easy substitute in argument types. --- stdlib/_typeshed/__init__.pyi | 47 ++++++++++++++++++++++++++++++++++- 1 file changed, 46 insertions(+), 1 deletion(-) diff --git a/stdlib/_typeshed/__init__.pyi b/stdlib/_typeshed/__init__.pyi index b786923880e1..c1b72485854a 100644 --- a/stdlib/_typeshed/__init__.pyi +++ b/stdlib/_typeshed/__init__.pyi @@ -3,7 +3,18 @@ # See the README.md file in this directory for more information. import sys -from collections.abc import Awaitable, Callable, Iterable, Iterator, Sequence, Set as AbstractSet, Sized +from collections.abc import ( + Awaitable, + Callable, + ItemsView, + Iterable, + Iterator, + KeysView, + Sequence, + Set as AbstractSet, + Sized, + ValuesView, +) from dataclasses import Field from os import PathLike from types import FrameType, TracebackType @@ -179,6 +190,40 @@ class SupportsItemAccess(Protocol[_KT_contra, _VT]): def __setitem__(self, key: _KT_contra, value: _VT, /) -> None: ... def __delitem__(self, key: _KT_contra, /) -> None: ... + +# Protocol for sequence-like objects. This includes commonly used methods +# from collections.abc.Sequence, and can be used in argument types when using +# more specific protocols would be cumbersome. +# +# Please note that this protocol is not yet marked as stable, and may be +# extended in the future to include more methods. +class SequenceLike(Protocol[_T_co]): + def __contains__(self, value: object, /) -> bool: ... + @overload + def __getitem__(self, index: int, /) -> _T_co: ... + # This does not necessarily return a sequence of the same type. + @overload + def __getitem__(self, index: slice, /) -> Sequence[_T_co]: ... + def __iter__(self) -> Iterator[_T_co]: ... + def __len__(self) -> int: ... + +# Protocol for mapping-like objects. This includes the methods from +# collections.abc.Mapping, and can be used in argument types when using +# more specific protocols would be cumbersome. +class MappingLike(Protocol[_KT, _VT_co]): + def __contains__(self, key: object, /) -> bool: ... + def __getitem__(self, key: _KT, /) -> _VT_co: ... + def __len__(self) -> int: ... + @overload + def get(self, key: _KT, /) -> _VT_co | None: ... + @overload + def get(self, key: _KT, default: _VT, /) -> _VT_co | _VT: ... + def items(self) -> ItemsView[_KT, _VT_co]: ... + def keys(self) -> KeysView[_KT]: ... + def values(self) -> ValuesView[_VT_co]: ... + +# Path- and I/O-related types + StrPath: TypeAlias = str | PathLike[str] # stable BytesPath: TypeAlias = bytes | PathLike[bytes] # stable GenericPath: TypeAlias = AnyStr | PathLike[AnyStr] From cf4ac68777b94582e7d8f0b0e324a877f53476fe Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Fri, 19 Dec 2025 17:38:16 +0000 Subject: [PATCH 2/2] [pre-commit.ci] auto fixes from pre-commit.com hooks --- stdlib/_typeshed/__init__.pyi | 1 - 1 file changed, 1 deletion(-) diff --git a/stdlib/_typeshed/__init__.pyi b/stdlib/_typeshed/__init__.pyi index c1b72485854a..f4f43d09a45c 100644 --- a/stdlib/_typeshed/__init__.pyi +++ b/stdlib/_typeshed/__init__.pyi @@ -190,7 +190,6 @@ class SupportsItemAccess(Protocol[_KT_contra, _VT]): def __setitem__(self, key: _KT_contra, value: _VT, /) -> None: ... def __delitem__(self, key: _KT_contra, /) -> None: ... - # Protocol for sequence-like objects. This includes commonly used methods # from collections.abc.Sequence, and can be used in argument types when using # more specific protocols would be cumbersome.