diff --git a/mypy/typeshed/stdlib/_typeshed/__init__.pyi b/mypy/typeshed/stdlib/_typeshed/__init__.pyi index 8c0005294bf0..0d4c42afc285 100644 --- a/mypy/typeshed/stdlib/_typeshed/__init__.pyi +++ b/mypy/typeshed/stdlib/_typeshed/__init__.pyi @@ -45,6 +45,26 @@ class SupportsGreaterThan(Protocol): SupportsGreaterThanT = TypeVar("SupportsGreaterThanT", bound=SupportsGreaterThan) # noqa: Y001 +# Comparison protocols + +class SupportsDunderLT(Protocol): + def __lt__(self, __other: Any) -> Any: ... + +class SupportsDunderGT(Protocol): + def __gt__(self, __other: Any) -> Any: ... + +class SupportsDunderLE(Protocol): + def __le__(self, __other: Any) -> Any: ... + +class SupportsDunderGE(Protocol): + def __ge__(self, __other: Any) -> Any: ... + +class SupportsAllComparisons(SupportsDunderLT, SupportsDunderGT, SupportsDunderLE, SupportsDunderGE, Protocol): ... + +SupportsRichComparison = Union[SupportsDunderLT, SupportsDunderGT] +SupportsRichComparisonT = TypeVar("SupportsRichComparisonT", bound=SupportsRichComparison) # noqa: Y001 +SupportsAnyComparison = Union[SupportsDunderLE, SupportsDunderGE, SupportsDunderGT, SupportsDunderLT] + class SupportsDivMod(Protocol[_T_contra, _T_co]): def __divmod__(self, __other: _T_contra) -> _T_co: ... diff --git a/mypy/typeshed/stdlib/builtins.pyi b/mypy/typeshed/stdlib/builtins.pyi index dfafe6f738e5..71efda9b979a 100644 --- a/mypy/typeshed/stdlib/builtins.pyi +++ b/mypy/typeshed/stdlib/builtins.pyi @@ -13,14 +13,12 @@ from _typeshed import ( StrOrBytesPath, SupportsAnext, SupportsDivMod, - SupportsGreaterThan, - SupportsGreaterThanT, SupportsKeysAndGetItem, SupportsLenAndGetItem, - SupportsLessThan, - SupportsLessThanT, SupportsNext, SupportsRDivMod, + SupportsRichComparison, + SupportsRichComparisonT, SupportsTrunc, SupportsWrite, ) @@ -779,9 +777,9 @@ class list(MutableSequence[_T], Generic[_T]): def remove(self, __value: _T) -> None: ... def reverse(self) -> None: ... @overload - def sort(self: list[SupportsLessThanT], *, key: None = ..., reverse: bool = ...) -> None: ... + def sort(self: list[SupportsRichComparisonT], *, key: None = ..., reverse: bool = ...) -> None: ... @overload - def sort(self, *, key: Callable[[_T], SupportsLessThan], reverse: bool = ...) -> None: ... + def sort(self, *, key: Callable[[_T], SupportsRichComparison], reverse: bool = ...) -> None: ... def __len__(self) -> int: ... def __iter__(self) -> Iterator[_T]: ... def __str__(self) -> str: ... @@ -1146,32 +1144,32 @@ class map(Iterator[_S], Generic[_S]): @overload def max( - __arg1: SupportsGreaterThanT, __arg2: SupportsGreaterThanT, *_args: SupportsGreaterThanT, key: None = ... -) -> SupportsGreaterThanT: ... + __arg1: SupportsRichComparisonT, __arg2: SupportsRichComparisonT, *_args: SupportsRichComparisonT, key: None = ... +) -> SupportsRichComparisonT: ... @overload -def max(__arg1: _T, __arg2: _T, *_args: _T, key: Callable[[_T], SupportsGreaterThan]) -> _T: ... +def max(__arg1: _T, __arg2: _T, *_args: _T, key: Callable[[_T], SupportsRichComparison]) -> _T: ... @overload -def max(__iterable: Iterable[SupportsGreaterThanT], *, key: None = ...) -> SupportsGreaterThanT: ... +def max(__iterable: Iterable[SupportsRichComparisonT], *, key: None = ...) -> SupportsRichComparisonT: ... @overload -def max(__iterable: Iterable[_T], *, key: Callable[[_T], SupportsGreaterThan]) -> _T: ... +def max(__iterable: Iterable[_T], *, key: Callable[[_T], SupportsRichComparison]) -> _T: ... @overload -def max(__iterable: Iterable[SupportsGreaterThanT], *, key: None = ..., default: _T) -> SupportsGreaterThanT | _T: ... +def max(__iterable: Iterable[SupportsRichComparisonT], *, key: None = ..., default: _T) -> SupportsRichComparisonT | _T: ... @overload -def max(__iterable: Iterable[_T1], *, key: Callable[[_T1], SupportsGreaterThan], default: _T2) -> _T1 | _T2: ... +def max(__iterable: Iterable[_T1], *, key: Callable[[_T1], SupportsRichComparison], default: _T2) -> _T1 | _T2: ... @overload def min( - __arg1: SupportsLessThanT, __arg2: SupportsLessThanT, *_args: SupportsLessThanT, key: None = ... -) -> SupportsLessThanT: ... + __arg1: SupportsRichComparisonT, __arg2: SupportsRichComparisonT, *_args: SupportsRichComparisonT, key: None = ... +) -> SupportsRichComparisonT: ... @overload -def min(__arg1: _T, __arg2: _T, *_args: _T, key: Callable[[_T], SupportsLessThan]) -> _T: ... +def min(__arg1: _T, __arg2: _T, *_args: _T, key: Callable[[_T], SupportsRichComparison]) -> _T: ... @overload -def min(__iterable: Iterable[SupportsLessThanT], *, key: None = ...) -> SupportsLessThanT: ... +def min(__iterable: Iterable[SupportsRichComparisonT], *, key: None = ...) -> SupportsRichComparisonT: ... @overload -def min(__iterable: Iterable[_T], *, key: Callable[[_T], SupportsLessThan]) -> _T: ... +def min(__iterable: Iterable[_T], *, key: Callable[[_T], SupportsRichComparison]) -> _T: ... @overload -def min(__iterable: Iterable[SupportsLessThanT], *, key: None = ..., default: _T) -> SupportsLessThanT | _T: ... +def min(__iterable: Iterable[SupportsRichComparisonT], *, key: None = ..., default: _T) -> SupportsRichComparisonT | _T: ... @overload -def min(__iterable: Iterable[_T1], *, key: Callable[[_T1], SupportsLessThan], default: _T2) -> _T1 | _T2: ... +def min(__iterable: Iterable[_T1], *, key: Callable[[_T1], SupportsRichComparison], default: _T2) -> _T1 | _T2: ... @overload def next(__i: SupportsNext[_T]) -> _T: ... @overload @@ -1382,9 +1380,9 @@ def round(number: SupportsRound[_T], ndigits: SupportsIndex) -> _T: ... # for why arg 3 of `setattr` should be annotated with `Any` and not `object` def setattr(__obj: object, __name: str, __value: Any) -> None: ... @overload -def sorted(__iterable: Iterable[SupportsLessThanT], *, key: None = ..., reverse: bool = ...) -> list[SupportsLessThanT]: ... +def sorted(__iterable: Iterable[SupportsRichComparisonT], *, key: None = ..., reverse: bool = ...) -> list[SupportsRichComparisonT]: ... @overload -def sorted(__iterable: Iterable[_T], *, key: Callable[[_T], SupportsLessThan], reverse: bool = ...) -> list[_T]: ... +def sorted(__iterable: Iterable[_T], *, key: Callable[[_T], SupportsRichComparison], reverse: bool = ...) -> list[_T]: ... if sys.version_info >= (3, 8): @overload diff --git a/mypy/typeshed/stdlib/inspect.pyi b/mypy/typeshed/stdlib/inspect.pyi index e3711cc85fbe..88002cf205b1 100644 --- a/mypy/typeshed/stdlib/inspect.pyi +++ b/mypy/typeshed/stdlib/inspect.pyi @@ -3,7 +3,7 @@ import sys import types from _typeshed import Self from collections import OrderedDict -from collections.abc import Awaitable, Callable, Generator, Mapping, Sequence +from collections.abc import Awaitable, Callable, Generator, Mapping, Sequence, Set as AbstractSet from types import ( AsyncGeneratorType, BuiltinFunctionType, @@ -313,7 +313,7 @@ class ClosureVars(NamedTuple): nonlocals: Mapping[str, Any] globals: Mapping[str, Any] builtins: Mapping[str, Any] - unbound: set[str] + unbound: AbstractSet[str] def getclosurevars(func: Callable[..., Any]) -> ClosureVars: ... def unwrap(func: Callable[..., Any], *, stop: Callable[[Any], Any] | None = ...) -> Any: ... diff --git a/mypy/typeshed/stdlib/logging/config.pyi b/mypy/typeshed/stdlib/logging/config.pyi index cb9ad5995d9d..8ee9e7b339b5 100644 --- a/mypy/typeshed/stdlib/logging/config.pyi +++ b/mypy/typeshed/stdlib/logging/config.pyi @@ -43,7 +43,12 @@ class _OptionalDictConfigArgs(TypedDict, total=False): class _DictConfigArgs(_OptionalDictConfigArgs, TypedDict): version: Literal[1] -def dictConfig(config: _DictConfigArgs) -> None: ... +# Accept dict[str, Any] to avoid false positives if called with a dict +# type, since dict types are not compatible with TypedDicts. +# +# Also accept a TypedDict type, to allow callers to use TypedDict +# types, and for somewhat stricter type checking of dict literals. +def dictConfig(config: _DictConfigArgs | dict[str, Any]) -> None: ... if sys.version_info >= (3, 10): def fileConfig( diff --git a/mypy/typeshed/stdlib/random.pyi b/mypy/typeshed/stdlib/random.pyi index 699c56351051..73c29d2f78c3 100644 --- a/mypy/typeshed/stdlib/random.pyi +++ b/mypy/typeshed/stdlib/random.pyi @@ -1,6 +1,6 @@ import _random import sys -from collections.abc import Callable, Iterable, MutableSequence, Sequence +from collections.abc import Callable, Iterable, MutableSequence, Sequence, Set as AbstractSet from fractions import Fraction from typing import Any, NoReturn, Tuple, TypeVar @@ -27,9 +27,9 @@ class Random(_random.Random): ) -> list[_T]: ... def shuffle(self, x: MutableSequence[Any], random: Callable[[], float] | None = ...) -> None: ... if sys.version_info >= (3, 9): - def sample(self, population: Sequence[_T] | set[_T], k: int, *, counts: Iterable[_T] | None = ...) -> list[_T]: ... + def sample(self, population: Sequence[_T] | AbstractSet[_T], k: int, *, counts: Iterable[_T] | None = ...) -> list[_T]: ... else: - def sample(self, population: Sequence[_T] | set[_T], k: int) -> list[_T]: ... + def sample(self, population: Sequence[_T] | AbstractSet[_T], k: int) -> list[_T]: ... def random(self) -> float: ... def uniform(self, a: float, b: float) -> float: ... def triangular(self, low: float = ..., high: float = ..., mode: float | None = ...) -> float: ... @@ -66,10 +66,10 @@ def choices( def shuffle(x: MutableSequence[Any], random: Callable[[], float] | None = ...) -> None: ... if sys.version_info >= (3, 9): - def sample(population: Sequence[_T] | set[_T], k: int, *, counts: Iterable[_T] | None = ...) -> list[_T]: ... + def sample(population: Sequence[_T] | AbstractSet[_T], k: int, *, counts: Iterable[_T] | None = ...) -> list[_T]: ... else: - def sample(population: Sequence[_T] | set[_T], k: int) -> list[_T]: ... + def sample(population: Sequence[_T] | AbstractSet[_T], k: int) -> list[_T]: ... def random() -> float: ... def uniform(a: float, b: float) -> float: ...