diff --git a/stdlib/collections/__init__.pyi b/stdlib/collections/__init__.pyi index 08bc521d0040..e534c13c026b 100644 --- a/stdlib/collections/__init__.pyi +++ b/stdlib/collections/__init__.pyi @@ -266,15 +266,16 @@ class Counter(dict[_T, int], Generic[_T]): def subtract(self, __mapping: Mapping[_T, int]) -> None: ... @overload def subtract(self, __iterable: Iterable[_T]) -> None: ... - # The Iterable[Tuple[...]] argument type is not actually desirable - # (the tuples will be added as keys, breaking type safety) but - # it's included so that the signature is compatible with - # Dict.update. Not sure if we should use '# type: ignore' instead - # and omit the type from the union. + # Unlike dict.update(), use Mapping instead of SupportsKeysAndGetItem for the first overload + # (source code does an `isinstance(other, Mapping)` check) + # + # The second overload is also deliberately different to dict.update() + # (if it were `Iterable[_T] | Iterable[tuple[_T, int]]`, + # the tuples would be added as keys, breaking type safety) + @overload # type: ignore[override] + def update(self, __m: Mapping[_T, int], **kwargs: int) -> None: ... @overload - def update(self, __m: SupportsKeysAndGetItem[_T, int], **kwargs: int) -> None: ... - @overload - def update(self, __m: Iterable[_T] | Iterable[tuple[_T, int]], **kwargs: int) -> None: ... + def update(self, __m: Iterable[_T], **kwargs: int) -> None: ... @overload def update(self, __m: None = ..., **kwargs: int) -> None: ... def __missing__(self, key: _T) -> int: ... @@ -283,22 +284,23 @@ class Counter(dict[_T, int], Generic[_T]): def __eq__(self, other: object) -> bool: ... def __ne__(self, other: object) -> bool: ... - def __add__(self, other: Counter[_T]) -> Counter[_T]: ... + def __add__(self, other: Counter[_S]) -> Counter[_T | _S]: ... def __sub__(self, other: Counter[_T]) -> Counter[_T]: ... def __and__(self, other: Counter[_T]) -> Counter[_T]: ... - def __or__(self, other: Counter[_T]) -> Counter[_T]: ... # type: ignore[override] + def __or__(self, other: Counter[_S]) -> Counter[_T | _S]: ... # type: ignore[override] def __pos__(self) -> Counter[_T]: ... def __neg__(self) -> Counter[_T]: ... - def __iadd__(self: Self, other: Counter[_T]) -> Self: ... + # several type: ignores because __iadd__ is supposedly incompatible with __add__, etc. + def __iadd__(self: Self, other: Counter[_T]) -> Self: ... # type: ignore[misc] def __isub__(self: Self, other: Counter[_T]) -> Self: ... def __iand__(self: Self, other: Counter[_T]) -> Self: ... - def __ior__(self: Self, other: Counter[_T]) -> Self: ... # type: ignore[override] + def __ior__(self: Self, other: Counter[_T]) -> Self: ... # type: ignore[override,misc] if sys.version_info >= (3, 10): def total(self) -> int: ... - def __le__(self, other: Counter[object]) -> bool: ... - def __lt__(self, other: Counter[object]) -> bool: ... - def __ge__(self, other: Counter[object]) -> bool: ... - def __gt__(self, other: Counter[object]) -> bool: ... + def __le__(self, other: Counter[Any]) -> bool: ... + def __lt__(self, other: Counter[Any]) -> bool: ... + def __ge__(self, other: Counter[Any]) -> bool: ... + def __gt__(self, other: Counter[Any]) -> bool: ... @final class _OrderedDictKeysView(dict_keys[_KT_co, _VT_co], Reversible[_KT_co]): # type: ignore[misc]