diff --git a/stdlib/_compression.pyi b/stdlib/_compression.pyi index 80d38b4db824..aa67df2ab478 100644 --- a/stdlib/_compression.pyi +++ b/stdlib/_compression.pyi @@ -3,10 +3,11 @@ from _typeshed import Incomplete, WriteableBuffer from collections.abc import Callable from io import DEFAULT_BUFFER_SIZE, BufferedIOBase, RawIOBase -from typing import Any, Protocol +from typing import Any, Protocol, type_check_only BUFFER_SIZE = DEFAULT_BUFFER_SIZE +@type_check_only class _Reader(Protocol): def read(self, n: int, /) -> bytes: ... def seekable(self) -> bool: ... diff --git a/stdlib/_ctypes.pyi b/stdlib/_ctypes.pyi index 192ebefd8fc8..0972585d8baf 100644 --- a/stdlib/_ctypes.pyi +++ b/stdlib/_ctypes.pyi @@ -103,7 +103,10 @@ class _SimpleCData(_CData, Generic[_T], metaclass=_PyCSimpleType): def __init__(self, value: _T = ...) -> None: ... # pyright: ignore[reportInvalidTypeVarUse] def __ctypes_from_outparam__(self, /) -> _T: ... # type: ignore[override] +@type_check_only class _CanCastTo(_CData): ... + +@type_check_only class _PointerLike(_CanCastTo): ... # This type is not exposed. It calls itself _ctypes.PyCPointerType. diff --git a/stdlib/_gdbm.pyi b/stdlib/_gdbm.pyi index 1d1d541f5477..2cb5fba29dfa 100644 --- a/stdlib/_gdbm.pyi +++ b/stdlib/_gdbm.pyi @@ -1,7 +1,7 @@ import sys from _typeshed import ReadOnlyBuffer, StrOrBytesPath from types import TracebackType -from typing import TypeVar, overload +from typing import TypeVar, overload, type_check_only from typing_extensions import Self, TypeAlias if sys.platform != "win32": @@ -13,6 +13,7 @@ if sys.platform != "win32": class error(OSError): ... # Actual typename gdbm, not exposed by the implementation + @type_check_only class _gdbm: def firstkey(self) -> bytes | None: ... def nextkey(self, key: _KeyType) -> bytes | None: ... diff --git a/stdlib/_io.pyi b/stdlib/_io.pyi index c77d75287c25..e368ddef7f4e 100644 --- a/stdlib/_io.pyi +++ b/stdlib/_io.pyi @@ -88,6 +88,7 @@ class BytesIO(BufferedIOBase, _BufferedIOBase, BinaryIO): # type: ignore[misc] def readlines(self, size: int | None = None, /) -> list[bytes]: ... def seek(self, pos: int, whence: int = 0, /) -> int: ... +@type_check_only class _BufferedReaderStream(Protocol): def read(self, n: int = ..., /) -> bytes: ... # Optional: def readall(self) -> bytes: ... diff --git a/stdlib/_msi.pyi b/stdlib/_msi.pyi index 779fda3b67fe..ef45ff6dc3c8 100644 --- a/stdlib/_msi.pyi +++ b/stdlib/_msi.pyi @@ -1,8 +1,10 @@ import sys +from typing import type_check_only if sys.platform == "win32": class MSIError(Exception): ... # Actual typename View, not exposed by the implementation + @type_check_only class _View: def Execute(self, params: _Record | None = ...) -> None: ... def GetColumnInfo(self, kind: int) -> _Record: ... @@ -14,6 +16,7 @@ if sys.platform == "win32": __init__: None # type: ignore[assignment] # Actual typename SummaryInformation, not exposed by the implementation + @type_check_only class _SummaryInformation: def GetProperty(self, field: int) -> int | bytes | None: ... def GetPropertyCount(self) -> int: ... @@ -24,6 +27,7 @@ if sys.platform == "win32": __init__: None # type: ignore[assignment] # Actual typename Database, not exposed by the implementation + @type_check_only class _Database: def OpenView(self, sql: str) -> _View: ... def Commit(self) -> None: ... @@ -34,6 +38,7 @@ if sys.platform == "win32": __init__: None # type: ignore[assignment] # Actual typename Record, not exposed by the implementation + @type_check_only class _Record: def GetFieldCount(self) -> int: ... def GetInteger(self, field: int) -> int: ... diff --git a/stdlib/_operator.pyi b/stdlib/_operator.pyi index 0106a832cb2f..cb1c1bcfc4aa 100644 --- a/stdlib/_operator.pyi +++ b/stdlib/_operator.pyi @@ -28,6 +28,7 @@ class _SupportsDunderGT(Protocol): class _SupportsDunderLE(Protocol): def __le__(self, other: Any, /) -> Any: ... +@type_check_only class _SupportsDunderGE(Protocol): def __ge__(self, other: Any, /) -> Any: ... diff --git a/stdlib/_pickle.pyi b/stdlib/_pickle.pyi index 8e8afb600efa..03051bb09d3c 100644 --- a/stdlib/_pickle.pyi +++ b/stdlib/_pickle.pyi @@ -4,6 +4,7 @@ from pickle import PickleBuffer as PickleBuffer from typing import Any, Protocol, type_check_only from typing_extensions import TypeAlias +@type_check_only class _ReadableFileobj(Protocol): def read(self, n: int, /) -> bytes: ... def readline(self) -> bytes: ... diff --git a/stdlib/_ssl.pyi b/stdlib/_ssl.pyi index 7ab880e4def7..88dd06780904 100644 --- a/stdlib/_ssl.pyi +++ b/stdlib/_ssl.pyi @@ -12,7 +12,7 @@ from ssl import ( SSLWantWriteError as SSLWantWriteError, SSLZeroReturnError as SSLZeroReturnError, ) -from typing import Any, ClassVar, Literal, TypedDict, final, overload +from typing import Any, ClassVar, Literal, TypedDict, final, overload, type_check_only from typing_extensions import NotRequired, Self, TypeAlias _PasswordType: TypeAlias = Callable[[], str | bytes | bytearray] | str | bytes | bytearray @@ -20,6 +20,7 @@ _PCTRTT: TypeAlias = tuple[tuple[str, str], ...] _PCTRTTT: TypeAlias = tuple[_PCTRTT, ...] _PeerCertRetDictType: TypeAlias = dict[str, str | _PCTRTTT | _PCTRTT] +@type_check_only class _Cipher(TypedDict): aead: bool alg_bits: int @@ -33,6 +34,7 @@ class _Cipher(TypedDict): strength_bits: int symmetric: str +@type_check_only class _CertInfo(TypedDict): subject: tuple[tuple[tuple[str, str], ...], ...] issuer: tuple[tuple[tuple[str, str], ...], ...] diff --git a/stdlib/ast.pyi b/stdlib/ast.pyi index fcd6e8b01e74..3ba56f55932a 100644 --- a/stdlib/ast.pyi +++ b/stdlib/ast.pyi @@ -10,7 +10,7 @@ from _ast import ( ) from _typeshed import ReadableBuffer, Unused from collections.abc import Iterable, Iterator, Sequence -from typing import Any, ClassVar, Generic, Literal, TypedDict, TypeVar as _TypeVar, overload +from typing import Any, ClassVar, Generic, Literal, TypedDict, TypeVar as _TypeVar, overload, type_check_only from typing_extensions import Self, Unpack, deprecated if sys.version_info >= (3, 13): @@ -20,6 +20,7 @@ if sys.version_info >= (3, 13): _EndPositionT = typing_extensions.TypeVar("_EndPositionT", int, int | None, default=int | None) # Corresponds to the names in the `_attributes` class variable which is non-empty in certain AST nodes +@type_check_only class _Attributes(TypedDict, Generic[_EndPositionT], total=False): lineno: int col_offset: int @@ -1698,8 +1699,14 @@ if sys.version_info >= (3, 12): self, *, name: str = ..., default_value: expr | None = ..., **kwargs: Unpack[_Attributes[int]] ) -> Self: ... -class _ABC(type): - def __init__(cls, *args: Unused) -> None: ... +if sys.version_info >= (3, 14): + @type_check_only + class _ABC(type): + def __init__(cls, *args: Unused) -> None: ... + +else: + class _ABC(type): + def __init__(cls, *args: Unused) -> None: ... if sys.version_info < (3, 14): @deprecated("Replaced by ast.Constant; removed in Python 3.14") diff --git a/stdlib/asyncio/events.pyi b/stdlib/asyncio/events.pyi index 6cceff71ceda..a37f6f697b9a 100644 --- a/stdlib/asyncio/events.pyi +++ b/stdlib/asyncio/events.pyi @@ -12,7 +12,7 @@ from collections.abc import Callable, Sequence from concurrent.futures import Executor from contextvars import Context from socket import AddressFamily, SocketKind, _Address, _RetAddress, socket -from typing import IO, Any, Literal, Protocol, TypeVar, overload +from typing import IO, Any, Literal, Protocol, TypeVar, overload, type_check_only from typing_extensions import Self, TypeAlias, TypeVarTuple, Unpack, deprecated from . import _AwaitableLike, _CoroutineLike @@ -68,6 +68,7 @@ _ExceptionHandler: TypeAlias = Callable[[AbstractEventLoop, _Context], object] _ProtocolFactory: TypeAlias = Callable[[], BaseProtocol] _SSLContext: TypeAlias = bool | None | ssl.SSLContext +@type_check_only class _TaskFactory(Protocol): def __call__(self, loop: AbstractEventLoop, factory: _CoroutineLike[_T], /) -> Future[_T]: ... @@ -599,6 +600,9 @@ class AbstractEventLoop: @abstractmethod async def shutdown_default_executor(self) -> None: ... +# This class does not exist at runtime, but stubtest complains if it's marked as +# @type_check_only because it has an alias that does exist at runtime. See mypy#19568. +# @type_check_only class _AbstractEventLoopPolicy: @abstractmethod def get_event_loop(self) -> AbstractEventLoop: ... diff --git a/stdlib/asyncio/format_helpers.pyi b/stdlib/asyncio/format_helpers.pyi index 41505b14cd08..597eb9e56e1a 100644 --- a/stdlib/asyncio/format_helpers.pyi +++ b/stdlib/asyncio/format_helpers.pyi @@ -3,9 +3,10 @@ import sys import traceback from collections.abc import Iterable from types import FrameType, FunctionType -from typing import Any, overload +from typing import Any, overload, type_check_only from typing_extensions import TypeAlias +@type_check_only class _HasWrapper: __wrapper__: _HasWrapper | FunctionType diff --git a/stdlib/asyncio/streams.pyi b/stdlib/asyncio/streams.pyi index 43df5ae2d0c8..bf8db0246ee2 100644 --- a/stdlib/asyncio/streams.pyi +++ b/stdlib/asyncio/streams.pyi @@ -3,7 +3,7 @@ import sys from _typeshed import ReadableBuffer, StrPath from collections.abc import Awaitable, Callable, Iterable, Sequence, Sized from types import ModuleType -from typing import Any, Protocol, SupportsIndex +from typing import Any, Protocol, SupportsIndex, type_check_only from typing_extensions import Self, TypeAlias from . import events, protocols, transports @@ -25,6 +25,7 @@ else: _ClientConnectedCallback: TypeAlias = Callable[[StreamReader, StreamWriter], Awaitable[None] | None] +@type_check_only class _ReaduntilBuffer(ReadableBuffer, Sized, Protocol): ... if sys.version_info >= (3, 10): diff --git a/stdlib/asyncio/tasks.pyi b/stdlib/asyncio/tasks.pyi index a088e95af653..4104b3ecfeee 100644 --- a/stdlib/asyncio/tasks.pyi +++ b/stdlib/asyncio/tasks.pyi @@ -8,7 +8,7 @@ from _asyncio import ( _unregister_task as _unregister_task, ) from collections.abc import AsyncIterator, Awaitable, Coroutine, Generator, Iterable, Iterator -from typing import Any, Literal, Protocol, TypeVar, overload +from typing import Any, Literal, Protocol, TypeVar, overload, type_check_only from typing_extensions import TypeAlias from . import _CoroutineLike @@ -87,6 +87,7 @@ FIRST_EXCEPTION = concurrent.futures.FIRST_EXCEPTION ALL_COMPLETED = concurrent.futures.ALL_COMPLETED if sys.version_info >= (3, 13): + @type_check_only class _SyncAndAsyncIterator(Iterator[_T_co], AsyncIterator[_T_co], Protocol[_T_co]): ... def as_completed(fs: Iterable[_FutureLike[_T]], *, timeout: float | None = None) -> _SyncAndAsyncIterator[Future[_T]]: ... @@ -445,6 +446,7 @@ elif sys.version_info >= (3, 12): if sys.version_info >= (3, 12): _TaskT_co = TypeVar("_TaskT_co", bound=Task[Any], covariant=True) + @type_check_only class _CustomTaskConstructor(Protocol[_TaskT_co]): def __call__( self, @@ -457,6 +459,7 @@ if sys.version_info >= (3, 12): eager_start: bool, ) -> _TaskT_co: ... + @type_check_only class _EagerTaskFactoryType(Protocol[_TaskT_co]): def __call__( self, diff --git a/stdlib/builtins.pyi b/stdlib/builtins.pyi index 4b1c4b68bef3..aeacbb96eec3 100644 --- a/stdlib/builtins.pyi +++ b/stdlib/builtins.pyi @@ -1340,6 +1340,9 @@ class property: def __set__(self, instance: Any, value: Any, /) -> None: ... def __delete__(self, instance: Any, /) -> None: ... +# This class does not exist at runtime, but stubtest complains if it's marked as +# @type_check_only because it has an alias that does exist at runtime. See mypy#19568. +# @type_check_only @final class _NotImplementedType(Any): __call__: None @@ -1513,7 +1516,7 @@ help: _sitebuiltins._Helper def hex(number: int | SupportsIndex, /) -> str: ... def id(obj: object, /) -> int: ... def input(prompt: object = "", /) -> str: ... - +@type_check_only class _GetItemIterable(Protocol[_T_co]): def __getitem__(self, i: int, /) -> _T_co: ... @@ -1768,7 +1771,7 @@ def open( opener: _Opener | None = None, ) -> IO[Any]: ... def ord(c: str | bytes | bytearray, /) -> int: ... - +@type_check_only class _SupportsWriteAndFlush(SupportsWrite[_T_contra], SupportsFlush, Protocol[_T_contra]): ... @overload @@ -1787,12 +1790,15 @@ def print( _E_contra = TypeVar("_E_contra", contravariant=True) _M_contra = TypeVar("_M_contra", contravariant=True) +@type_check_only class _SupportsPow2(Protocol[_E_contra, _T_co]): def __pow__(self, other: _E_contra, /) -> _T_co: ... +@type_check_only class _SupportsPow3NoneOnly(Protocol[_E_contra, _T_co]): def __pow__(self, other: _E_contra, modulo: None = None, /) -> _T_co: ... +@type_check_only class _SupportsPow3(Protocol[_E_contra, _M_contra, _T_co]): def __pow__(self, other: _E_contra, modulo: _M_contra, /) -> _T_co: ... @@ -1857,9 +1863,11 @@ def repr(obj: object, /) -> str: ... # and https://github.com/python/typeshed/pull/9151 # on why we don't use `SupportsRound` from `typing.pyi` +@type_check_only class _SupportsRound1(Protocol[_T_co]): def __round__(self) -> _T_co: ... +@type_check_only class _SupportsRound2(Protocol[_T_co]): def __round__(self, ndigits: int, /) -> _T_co: ... @@ -1881,6 +1889,7 @@ def sorted(iterable: Iterable[_T], /, *, key: Callable[[_T], SupportsRichCompari _AddableT1 = TypeVar("_AddableT1", bound=SupportsAdd[Any, Any]) _AddableT2 = TypeVar("_AddableT2", bound=SupportsAdd[Any, Any]) +@type_check_only class _SupportsSumWithNoDefaultGiven(SupportsAdd[Any, Any], SupportsRAdd[int, Any], Protocol): ... _SupportsSumNoDefaultT = TypeVar("_SupportsSumNoDefaultT", bound=_SupportsSumWithNoDefaultGiven) diff --git a/stdlib/bz2.pyi b/stdlib/bz2.pyi index dce6187a2da1..7bd829d040cb 100644 --- a/stdlib/bz2.pyi +++ b/stdlib/bz2.pyi @@ -3,7 +3,7 @@ from _bz2 import BZ2Compressor as BZ2Compressor, BZ2Decompressor as BZ2Decompres from _typeshed import ReadableBuffer, StrOrBytesPath, WriteableBuffer from collections.abc import Iterable from io import TextIOWrapper -from typing import IO, Literal, Protocol, SupportsIndex, overload +from typing import IO, Literal, Protocol, SupportsIndex, overload, type_check_only from typing_extensions import Self, TypeAlias if sys.version_info >= (3, 14): @@ -16,8 +16,10 @@ __all__ = ["BZ2File", "BZ2Compressor", "BZ2Decompressor", "open", "compress", "d # The following attributes and methods are optional: # def fileno(self) -> int: ... # def close(self) -> object: ... +@type_check_only class _ReadableFileobj(_Reader, Protocol): ... +@type_check_only class _WritableFileobj(Protocol): def write(self, b: bytes, /) -> object: ... # The following attributes and methods are optional: diff --git a/stdlib/codecs.pyi b/stdlib/codecs.pyi index 579d09c66a1b..15e184fc1038 100644 --- a/stdlib/codecs.pyi +++ b/stdlib/codecs.pyi @@ -3,7 +3,7 @@ from _codecs import * from _typeshed import ReadableBuffer from abc import abstractmethod from collections.abc import Callable, Generator, Iterable -from typing import Any, BinaryIO, ClassVar, Final, Literal, Protocol, TextIO, overload +from typing import Any, BinaryIO, ClassVar, Final, Literal, Protocol, TextIO, overload, type_check_only from typing_extensions import Self, TypeAlias __all__ = [ @@ -73,16 +73,19 @@ _BufferedEncoding: TypeAlias = Literal[ "utf-8-sig", ] +@type_check_only class _WritableStream(Protocol): def write(self, data: bytes, /) -> object: ... def seek(self, offset: int, whence: int, /) -> object: ... def close(self) -> object: ... +@type_check_only class _ReadableStream(Protocol): def read(self, size: int = ..., /) -> bytes: ... def seek(self, offset: int, whence: int, /) -> object: ... def close(self) -> object: ... +@type_check_only class _Stream(_WritableStream, _ReadableStream, Protocol): ... # TODO: this only satisfies the most common interface, where @@ -91,24 +94,31 @@ class _Stream(_WritableStream, _ReadableStream, Protocol): ... # There *are* bytes->bytes and str->str encodings in the standard library. # They were much more common in Python 2 than in Python 3. +@type_check_only class _Encoder(Protocol): def __call__(self, input: str, errors: str = ..., /) -> tuple[bytes, int]: ... # signature of Codec().encode +@type_check_only class _Decoder(Protocol): def __call__(self, input: ReadableBuffer, errors: str = ..., /) -> tuple[str, int]: ... # signature of Codec().decode +@type_check_only class _StreamReader(Protocol): def __call__(self, stream: _ReadableStream, errors: str = ..., /) -> StreamReader: ... +@type_check_only class _StreamWriter(Protocol): def __call__(self, stream: _WritableStream, errors: str = ..., /) -> StreamWriter: ... +@type_check_only class _IncrementalEncoder(Protocol): def __call__(self, errors: str = ...) -> IncrementalEncoder: ... +@type_check_only class _IncrementalDecoder(Protocol): def __call__(self, errors: str = ...) -> IncrementalDecoder: ... +@type_check_only class _BufferedIncrementalDecoder(Protocol): def __call__(self, errors: str = ...) -> BufferedIncrementalDecoder: ... diff --git a/stdlib/collections/__init__.pyi b/stdlib/collections/__init__.pyi index bc33d91caa1d..df9449ef4c9b 100644 --- a/stdlib/collections/__init__.pyi +++ b/stdlib/collections/__init__.pyi @@ -2,7 +2,7 @@ import sys from _collections_abc import dict_items, dict_keys, dict_values from _typeshed import SupportsItems, SupportsKeysAndGetItem, SupportsRichComparison, SupportsRichComparisonT from types import GenericAlias -from typing import Any, ClassVar, Generic, NoReturn, SupportsIndex, TypeVar, final, overload +from typing import Any, ClassVar, Generic, NoReturn, SupportsIndex, TypeVar, final, overload, type_check_only from typing_extensions import Self if sys.version_info >= (3, 10): @@ -342,14 +342,17 @@ class _OrderedDictValuesView(ValuesView[_VT_co]): # but they are not exposed anywhere) # pyright doesn't have a specific error code for subclassing error! @final +@type_check_only class _odict_keys(dict_keys[_KT_co, _VT_co]): # type: ignore[misc] # pyright: ignore[reportGeneralTypeIssues] def __reversed__(self) -> Iterator[_KT_co]: ... @final +@type_check_only class _odict_items(dict_items[_KT_co, _VT_co]): # type: ignore[misc] # pyright: ignore[reportGeneralTypeIssues] def __reversed__(self) -> Iterator[tuple[_KT_co, _VT_co]]: ... @final +@type_check_only class _odict_values(dict_values[_KT_co, _VT_co]): # type: ignore[misc] # pyright: ignore[reportGeneralTypeIssues] def __reversed__(self) -> Iterator[_VT_co]: ... diff --git a/stdlib/concurrent/futures/_base.pyi b/stdlib/concurrent/futures/_base.pyi index fbf07a3fc78f..4063027f3eed 100644 --- a/stdlib/concurrent/futures/_base.pyi +++ b/stdlib/concurrent/futures/_base.pyi @@ -4,7 +4,7 @@ from _typeshed import Unused from collections.abc import Callable, Iterable, Iterator from logging import Logger from types import GenericAlias, TracebackType -from typing import Any, Final, Generic, NamedTuple, Protocol, TypeVar +from typing import Any, Final, Generic, NamedTuple, Protocol, TypeVar, type_check_only from typing_extensions import ParamSpec, Self FIRST_COMPLETED: Final = "FIRST_COMPLETED" @@ -74,6 +74,7 @@ class Executor: self, exc_type: type[BaseException] | None, exc_val: BaseException | None, exc_tb: TracebackType | None ) -> bool | None: ... +@type_check_only class _AsCompletedFuture(Protocol[_T_co]): # as_completed only mutates non-generic aspects of passed Futures and does not do any nominal # checks. Therefore, we can use a Protocol here to allow as_completed to act covariantly. diff --git a/stdlib/configparser.pyi b/stdlib/configparser.pyi index 121b8606a92a..fb02701e3711 100644 --- a/stdlib/configparser.pyi +++ b/stdlib/configparser.pyi @@ -2,7 +2,7 @@ import sys from _typeshed import MaybeNone, StrOrBytesPath, SupportsWrite from collections.abc import Callable, ItemsView, Iterable, Iterator, Mapping, MutableMapping, Sequence from re import Pattern -from typing import Any, ClassVar, Final, Literal, TypeVar, overload +from typing import Any, ClassVar, Final, Literal, TypeVar, overload, type_check_only from typing_extensions import TypeAlias if sys.version_info >= (3, 14): @@ -104,7 +104,9 @@ else: ] if sys.version_info >= (3, 13): + @type_check_only class _UNNAMED_SECTION: ... + UNNAMED_SECTION: _UNNAMED_SECTION _SectionName: TypeAlias = str | _UNNAMED_SECTION diff --git a/stdlib/dataclasses.pyi b/stdlib/dataclasses.pyi index c76b0b0e61e2..b3183f57ebd2 100644 --- a/stdlib/dataclasses.pyi +++ b/stdlib/dataclasses.pyi @@ -165,6 +165,7 @@ else: ) -> Callable[[type[_T]], type[_T]]: ... # See https://github.com/python/mypy/issues/10750 +@type_check_only class _DefaultFactory(Protocol[_T_co]): def __call__(self) -> _T_co: ... diff --git a/stdlib/dbm/__init__.pyi b/stdlib/dbm/__init__.pyi index 7f344060f9ab..7cbb63cf2f06 100644 --- a/stdlib/dbm/__init__.pyi +++ b/stdlib/dbm/__init__.pyi @@ -76,6 +76,7 @@ _TFlags: TypeAlias = Literal[ "nusf", ] +@type_check_only class _Database(MutableMapping[_KeyType, bytes]): def close(self) -> None: ... def __getitem__(self, key: _KeyType) -> bytes: ... diff --git a/stdlib/email/headerregistry.pyi b/stdlib/email/headerregistry.pyi index dc641c8c952b..dff9593b731f 100644 --- a/stdlib/email/headerregistry.pyi +++ b/stdlib/email/headerregistry.pyi @@ -13,7 +13,7 @@ from email._header_value_parser import ( ) from email.errors import MessageDefect from email.policy import Policy -from typing import Any, ClassVar, Literal, Protocol +from typing import Any, ClassVar, Literal, Protocol, type_check_only from typing_extensions import Self class BaseHeader(str): @@ -137,6 +137,7 @@ class MessageIDHeader: @staticmethod def value_parser(value: str) -> MessageID: ... +@type_check_only class _HeaderParser(Protocol): max_count: ClassVar[Literal[1] | None] @staticmethod diff --git a/stdlib/email/message.pyi b/stdlib/email/message.pyi index e4d14992168a..794882b140e6 100644 --- a/stdlib/email/message.pyi +++ b/stdlib/email/message.pyi @@ -5,7 +5,7 @@ from email.charset import Charset from email.contentmanager import ContentManager from email.errors import MessageDefect from email.policy import Policy -from typing import Any, Generic, Literal, Protocol, TypeVar, overload +from typing import Any, Generic, Literal, Protocol, TypeVar, overload, type_check_only from typing_extensions import Self, TypeAlias __all__ = ["Message", "EmailMessage"] @@ -24,9 +24,11 @@ _EncodedPayloadType: TypeAlias = Message | bytes _MultipartPayloadType: TypeAlias = list[_PayloadType] _CharsetType: TypeAlias = Charset | str | None +@type_check_only class _SupportsEncodeToPayload(Protocol): def encode(self, encoding: str, /) -> _PayloadType | _MultipartPayloadType | _SupportsDecodeToPayload: ... +@type_check_only class _SupportsDecodeToPayload(Protocol): def decode(self, encoding: str, errors: str, /) -> _PayloadType | _MultipartPayloadType: ... diff --git a/stdlib/functools.pyi b/stdlib/functools.pyi index e31399fb8705..6e17ba7d35dc 100644 --- a/stdlib/functools.pyi +++ b/stdlib/functools.pyi @@ -3,7 +3,7 @@ import types from _typeshed import SupportsAllComparisons, SupportsItems from collections.abc import Callable, Hashable, Iterable, Sized from types import GenericAlias -from typing import Any, Final, Generic, Literal, NamedTuple, TypedDict, TypeVar, final, overload +from typing import Any, Final, Generic, Literal, NamedTuple, TypedDict, TypeVar, final, overload, type_check_only from typing_extensions import ParamSpec, Self, TypeAlias __all__ = [ @@ -48,6 +48,7 @@ class _CacheInfo(NamedTuple): maxsize: int | None currsize: int +@type_check_only class _CacheParameters(TypedDict): maxsize: int typed: bool @@ -96,6 +97,7 @@ else: WRAPPER_UPDATES: tuple[Literal["__dict__"]] +@type_check_only class _Wrapped(Generic[_PWrapped, _RWrapped, _PWrapper, _RWrapper]): __wrapped__: Callable[_PWrapped, _RWrapped] def __call__(self, *args: _PWrapper.args, **kwargs: _PWrapper.kwargs) -> _RWrapper: ... @@ -103,6 +105,7 @@ class _Wrapped(Generic[_PWrapped, _RWrapped, _PWrapper, _RWrapper]): __name__: str __qualname__: str +@type_check_only class _Wrapper(Generic[_PWrapped, _RWrapped]): def __call__(self, f: Callable[_PWrapper, _RWrapper]) -> _Wrapped[_PWrapped, _RWrapped, _PWrapper, _RWrapper]: ... @@ -180,6 +183,7 @@ if sys.version_info >= (3, 11): else: _RegType: TypeAlias = type[Any] +@type_check_only class _SingleDispatchCallable(Generic[_T]): registry: types.MappingProxyType[Any, Callable[..., _T]] def dispatch(self, cls: Any) -> Callable[..., _T]: ... diff --git a/stdlib/hashlib.pyi b/stdlib/hashlib.pyi index b32c0e992574..924136301b21 100644 --- a/stdlib/hashlib.pyi +++ b/stdlib/hashlib.pyi @@ -20,7 +20,7 @@ from _hashlib import ( ) from _typeshed import ReadableBuffer from collections.abc import Callable, Set as AbstractSet -from typing import Protocol +from typing import Protocol, type_check_only if sys.version_info >= (3, 11): __all__ = ( @@ -72,9 +72,11 @@ algorithms_guaranteed: AbstractSet[str] algorithms_available: AbstractSet[str] if sys.version_info >= (3, 11): + @type_check_only class _BytesIOLike(Protocol): def getbuffer(self) -> ReadableBuffer: ... + @type_check_only class _FileDigestFileObj(Protocol): def readinto(self, buf: bytearray, /) -> int: ... def readable(self) -> bool: ... diff --git a/stdlib/imp.pyi b/stdlib/imp.pyi index ee5a0cd7bc72..f045fd969b27 100644 --- a/stdlib/imp.pyi +++ b/stdlib/imp.pyi @@ -13,7 +13,7 @@ from _imp import ( from _typeshed import StrPath from os import PathLike from types import TracebackType -from typing import IO, Any, Protocol +from typing import IO, Any, Protocol, type_check_only SEARCH_ERROR: int PY_SOURCE: int @@ -39,6 +39,7 @@ class NullImporter: # Technically, a text file has to support a slightly different set of operations than a binary file, # but we ignore that here. +@type_check_only class _FileLike(Protocol): closed: bool mode: str diff --git a/stdlib/logging/__init__.pyi b/stdlib/logging/__init__.pyi index 24529bd48d6a..03c79cc3e265 100644 --- a/stdlib/logging/__init__.pyi +++ b/stdlib/logging/__init__.pyi @@ -7,7 +7,7 @@ from re import Pattern from string import Template from time import struct_time from types import FrameType, GenericAlias, TracebackType -from typing import Any, ClassVar, Final, Generic, Literal, Protocol, TextIO, TypeVar, overload +from typing import Any, ClassVar, Final, Generic, Literal, Protocol, TextIO, TypeVar, overload, type_check_only from typing_extensions import Self, TypeAlias, deprecated __all__ = [ @@ -67,11 +67,13 @@ _Level: TypeAlias = int | str _FormatStyle: TypeAlias = Literal["%", "{", "$"] if sys.version_info >= (3, 12): + @type_check_only class _SupportsFilter(Protocol): def filter(self, record: LogRecord, /) -> bool | LogRecord: ... _FilterType: TypeAlias = Filter | Callable[[LogRecord], bool | LogRecord] | _SupportsFilter else: + @type_check_only class _SupportsFilter(Protocol): def filter(self, record: LogRecord, /) -> bool: ... diff --git a/stdlib/logging/handlers.pyi b/stdlib/logging/handlers.pyi index 9636b81dc4f3..e231d1de3fb5 100644 --- a/stdlib/logging/handlers.pyi +++ b/stdlib/logging/handlers.pyi @@ -9,7 +9,7 @@ from re import Pattern from socket import SocketKind, socket from threading import Thread from types import TracebackType -from typing import Any, ClassVar, Final, Protocol, TypeVar +from typing import Any, ClassVar, Final, Protocol, TypeVar, type_check_only from typing_extensions import Self _T = TypeVar("_T") @@ -225,6 +225,7 @@ class HTTPHandler(Handler): def mapLogRecord(self, record: LogRecord) -> dict[str, Any]: ... def getConnection(self, host: str, secure: bool) -> http.client.HTTPConnection: ... # undocumented +@type_check_only class _QueueLike(Protocol[_T]): def get(self) -> _T: ... def put_nowait(self, item: _T, /) -> None: ... diff --git a/stdlib/mailbox.pyi b/stdlib/mailbox.pyi index ff605c0661fb..89bd998b4dfe 100644 --- a/stdlib/mailbox.pyi +++ b/stdlib/mailbox.pyi @@ -6,7 +6,7 @@ from abc import ABCMeta, abstractmethod from collections.abc import Callable, Iterable, Iterator, Mapping, Sequence from email._policybase import _MessageT from types import GenericAlias, TracebackType -from typing import IO, Any, AnyStr, Generic, Literal, Protocol, TypeVar, overload +from typing import IO, Any, AnyStr, Generic, Literal, Protocol, TypeVar, overload, type_check_only from typing_extensions import Self, TypeAlias __all__ = [ @@ -31,13 +31,16 @@ __all__ = [ _T = TypeVar("_T") +@type_check_only class _SupportsReadAndReadline(SupportsRead[bytes], SupportsNoArgReadline[bytes], Protocol): ... _MessageData: TypeAlias = email.message.Message | bytes | str | io.StringIO | _SupportsReadAndReadline +@type_check_only class _HasIteritems(Protocol): def iteritems(self) -> Iterator[tuple[str, _MessageData]]: ... +@type_check_only class _HasItems(Protocol): def items(self) -> Iterator[tuple[str, _MessageData]]: ... diff --git a/stdlib/multiprocessing/heap.pyi b/stdlib/multiprocessing/heap.pyi index b5e2ced5e8ee..38191a099f1e 100644 --- a/stdlib/multiprocessing/heap.pyi +++ b/stdlib/multiprocessing/heap.pyi @@ -2,7 +2,7 @@ import sys from _typeshed import Incomplete from collections.abc import Callable from mmap import mmap -from typing import Protocol +from typing import Protocol, type_check_only from typing_extensions import TypeAlias __all__ = ["BufferWrapper"] @@ -20,6 +20,7 @@ class Arena: _Block: TypeAlias = tuple[Arena, int, int] if sys.platform != "win32": + @type_check_only class _SupportsDetach(Protocol): def detach(self) -> int: ... diff --git a/stdlib/multiprocessing/sharedctypes.pyi b/stdlib/multiprocessing/sharedctypes.pyi index 5283445d8545..e2ec15f05ea2 100644 --- a/stdlib/multiprocessing/sharedctypes.pyi +++ b/stdlib/multiprocessing/sharedctypes.pyi @@ -5,7 +5,7 @@ from ctypes import _SimpleCData, c_char from multiprocessing.context import BaseContext from multiprocessing.synchronize import _LockLike from types import TracebackType -from typing import Any, Generic, Literal, Protocol, TypeVar, overload +from typing import Any, Generic, Literal, Protocol, TypeVar, overload, type_check_only __all__ = ["RawValue", "RawArray", "Value", "Array", "copy", "synchronized"] @@ -81,7 +81,7 @@ def synchronized( ) -> SynchronizedArray[_T]: ... @overload def synchronized(obj: _CT, lock: _LockLike | None = None, ctx: Any | None = None) -> SynchronizedBase[_CT]: ... - +@type_check_only class _AcquireFunc(Protocol): def __call__(self, block: bool = ..., timeout: float | None = ..., /) -> bool: ... diff --git a/stdlib/numbers.pyi b/stdlib/numbers.pyi index 02d469ce0ee5..b24591719cff 100644 --- a/stdlib/numbers.pyi +++ b/stdlib/numbers.pyi @@ -8,7 +8,7 @@ # nor `float` as a subtype of `numbers.Real`, etc.) from abc import ABCMeta, abstractmethod -from typing import ClassVar, Literal, Protocol, overload +from typing import ClassVar, Literal, Protocol, overload, type_check_only __all__ = ["Number", "Complex", "Real", "Rational", "Integral"] @@ -22,6 +22,7 @@ __all__ = ["Number", "Complex", "Real", "Rational", "Integral"] # NOTE: We can't include `__complex__` here, # as we want `int` to be seen as a subtype of `_ComplexLike`, # and `int.__complex__` does not exist :( +@type_check_only class _ComplexLike(Protocol): def __neg__(self) -> _ComplexLike: ... def __pos__(self) -> _ComplexLike: ... @@ -29,6 +30,7 @@ class _ComplexLike(Protocol): # _RealLike is a structural-typing approximation # of the `Real` ABC, which is not (and cannot be) a protocol +@type_check_only class _RealLike(_ComplexLike, Protocol): def __trunc__(self) -> _IntegralLike: ... def __floor__(self) -> _IntegralLike: ... @@ -41,6 +43,7 @@ class _RealLike(_ComplexLike, Protocol): # _IntegralLike is a structural-typing approximation # of the `Integral` ABC, which is not (and cannot be) a protocol +@type_check_only class _IntegralLike(_RealLike, Protocol): def __invert__(self) -> _IntegralLike: ... def __int__(self) -> int: ... diff --git a/stdlib/os/__init__.pyi b/stdlib/os/__init__.pyi index 4521d8240c85..4047bb0f1c4d 100644 --- a/stdlib/os/__init__.pyi +++ b/stdlib/os/__init__.pyi @@ -39,6 +39,7 @@ from typing import ( final, overload, runtime_checkable, + type_check_only, ) from typing_extensions import Self, TypeAlias, Unpack, deprecated @@ -1241,6 +1242,7 @@ def replace( ) -> None: ... def rmdir(path: StrOrBytesPath, *, dir_fd: int | None = None) -> None: ... @final +@type_check_only class _ScandirIterator(Generic[AnyStr]): def __del__(self) -> None: ... def __iter__(self) -> Self: ... diff --git a/stdlib/pydoc.pyi b/stdlib/pydoc.pyi index f14b9d1bb699..3c78f9d2de8e 100644 --- a/stdlib/pydoc.pyi +++ b/stdlib/pydoc.pyi @@ -5,7 +5,7 @@ from builtins import list as _list # "list" conflicts with method name from collections.abc import Callable, Container, Mapping, MutableMapping from reprlib import Repr from types import MethodType, ModuleType, TracebackType -from typing import IO, Any, AnyStr, Final, NoReturn, Protocol, TypeVar +from typing import IO, Any, AnyStr, Final, NoReturn, Protocol, TypeVar, type_check_only from typing_extensions import TypeGuard, deprecated __all__ = ["help"] @@ -17,6 +17,7 @@ __date__: Final[str] __version__: Final[str] __credits__: Final[str] +@type_check_only class _Pager(Protocol): def __call__(self, text: str, title: str = "") -> None: ... diff --git a/stdlib/quopri.pyi b/stdlib/quopri.pyi index b652e139bd0e..be6892fcbcd7 100644 --- a/stdlib/quopri.pyi +++ b/stdlib/quopri.pyi @@ -1,8 +1,9 @@ from _typeshed import ReadableBuffer, SupportsNoArgReadline, SupportsRead, SupportsWrite -from typing import Protocol +from typing import Protocol, type_check_only __all__ = ["encode", "decode", "encodestring", "decodestring"] +@type_check_only class _Input(SupportsRead[bytes], SupportsNoArgReadline[bytes], Protocol): ... def encode(input: _Input, output: SupportsWrite[bytes], quotetabs: int, header: bool = False) -> None: ... diff --git a/stdlib/shutil.pyi b/stdlib/shutil.pyi index c66d8fa128be..cc26cfc556a0 100644 --- a/stdlib/shutil.pyi +++ b/stdlib/shutil.pyi @@ -3,7 +3,7 @@ import sys from _typeshed import BytesPath, ExcInfo, FileDescriptorOrPath, MaybeNone, StrOrBytesPath, StrPath, SupportsRead, SupportsWrite from collections.abc import Callable, Iterable, Sequence from tarfile import _TarfileFilter -from typing import Any, AnyStr, NamedTuple, NoReturn, Protocol, TypeVar, overload +from typing import Any, AnyStr, NamedTuple, NoReturn, Protocol, TypeVar, overload, type_check_only from typing_extensions import TypeAlias, deprecated __all__ = [ @@ -79,6 +79,7 @@ def copytree( _OnErrorCallback: TypeAlias = Callable[[Callable[..., Any], str, ExcInfo], object] _OnExcCallback: TypeAlias = Callable[[Callable[..., Any], str, BaseException], object] +@type_check_only class _RmtreeType(Protocol): avoids_symlink_attacks: bool if sys.version_info >= (3, 12): diff --git a/stdlib/smtplib.pyi b/stdlib/smtplib.pyi index 609b3e6426c4..3d392c047993 100644 --- a/stdlib/smtplib.pyi +++ b/stdlib/smtplib.pyi @@ -7,7 +7,7 @@ from re import Pattern from socket import socket from ssl import SSLContext from types import TracebackType -from typing import Any, Protocol, overload +from typing import Any, Protocol, overload, type_check_only from typing_extensions import Self, TypeAlias __all__ = [ @@ -65,7 +65,7 @@ class SMTPAuthenticationError(SMTPResponseException): ... def quoteaddr(addrstring: str) -> str: ... def quotedata(data: str) -> str: ... - +@type_check_only class _AuthObject(Protocol): @overload def __call__(self, challenge: None = None, /) -> str | None: ... diff --git a/stdlib/sqlite3/__init__.pyi b/stdlib/sqlite3/__init__.pyi index 0e5edd309f6a..bcfea3a13021 100644 --- a/stdlib/sqlite3/__init__.pyi +++ b/stdlib/sqlite3/__init__.pyi @@ -223,22 +223,26 @@ _Parameters: TypeAlias = SupportsLenAndGetItem[_AdaptedInputData] | Mapping[str, # Controls the legacy transaction handling mode of sqlite3. _IsolationLevel: TypeAlias = Literal["DEFERRED", "EXCLUSIVE", "IMMEDIATE"] | None +@type_check_only class _AnyParamWindowAggregateClass(Protocol): def step(self, *args: Any) -> object: ... def inverse(self, *args: Any) -> object: ... def value(self) -> _SqliteData: ... def finalize(self) -> _SqliteData: ... +@type_check_only class _WindowAggregateClass(Protocol): step: Callable[..., object] inverse: Callable[..., object] def value(self) -> _SqliteData: ... def finalize(self) -> _SqliteData: ... +@type_check_only class _AggregateProtocol(Protocol): def step(self, value: int, /) -> object: ... def finalize(self) -> int: ... +@type_check_only class _SingleParamWindowAggregateClass(Protocol): def step(self, param: Any, /) -> object: ... def inverse(self, param: Any, /) -> object: ... diff --git a/stdlib/ssl.pyi b/stdlib/ssl.pyi index ac90f975a96e..1b8631d3fb12 100644 --- a/stdlib/ssl.pyi +++ b/stdlib/ssl.pyi @@ -50,6 +50,7 @@ _SrvnmeCbType: TypeAlias = Callable[[SSLSocket | SSLObject, str | None, SSLSocke socket_error = OSError +@type_check_only class _Cipher(TypedDict): aead: bool alg_bits: int diff --git a/stdlib/sys/__init__.pyi b/stdlib/sys/__init__.pyi index a5c2ad36026e..149f374d6e17 100644 --- a/stdlib/sys/__init__.pyi +++ b/stdlib/sys/__init__.pyi @@ -378,6 +378,7 @@ def settrace(function: TraceFunction | None, /) -> None: ... if sys.platform == "win32": # A tuple of length 5, even though it has more than 5 attributes. @final + @type_check_only class _WinVersion(_UninstantiableStructseq, tuple[int, int, int, int, str]): @property def major(self) -> int: ... diff --git a/stdlib/time.pyi b/stdlib/time.pyi index 6d2538ea7e3e..a921722b62c5 100644 --- a/stdlib/time.pyi +++ b/stdlib/time.pyi @@ -1,6 +1,6 @@ import sys from _typeshed import structseq -from typing import Any, Final, Literal, Protocol, final +from typing import Any, Final, Literal, Protocol, final, type_check_only from typing_extensions import TypeAlias _TimeTuple: TypeAlias = tuple[int, int, int, int, int, int, int, int, int] @@ -80,6 +80,7 @@ def time() -> float: ... if sys.platform != "win32": def tzset() -> None: ... # Unix only +@type_check_only class _ClockInfo(Protocol): adjustable: bool implementation: str diff --git a/stdlib/tkinter/__init__.pyi b/stdlib/tkinter/__init__.pyi index db0e34d737a6..b802d5e97c84 100644 --- a/stdlib/tkinter/__init__.pyi +++ b/stdlib/tkinter/__init__.pyi @@ -366,12 +366,14 @@ def getboolean(s): ... _Ts = TypeVarTuple("_Ts") +@type_check_only class _GridIndexInfo(TypedDict, total=False): minsize: _ScreenUnits pad: _ScreenUnits uniform: str | None weight: int +@type_check_only class _BusyInfo(TypedDict): cursor: _Cursor @@ -1039,6 +1041,7 @@ def Tcl(screenName: str | None = None, baseName: str | None = None, className: s _InMiscTotal = TypedDict("_InMiscTotal", {"in": Misc}) _InMiscNonTotal = TypedDict("_InMiscNonTotal", {"in": Misc}, total=False) +@type_check_only class _PackInfo(_InMiscTotal): # 'before' and 'after' never appear in _PackInfo anchor: _Anchor @@ -1080,6 +1083,7 @@ class Pack: forget = pack_forget propagate = Misc.pack_propagate +@type_check_only class _PlaceInfo(_InMiscNonTotal): # empty dict if widget hasn't been placed anchor: _Anchor bordermode: Literal["inside", "outside", "ignore"] @@ -1116,6 +1120,7 @@ class Place: place = place_configure info = place_info +@type_check_only class _GridInfo(_InMiscNonTotal): # empty dict if widget hasn't been gridded column: int columnspan: int diff --git a/stdlib/tkinter/dnd.pyi b/stdlib/tkinter/dnd.pyi index fe2961701c61..521f451a9b2c 100644 --- a/stdlib/tkinter/dnd.pyi +++ b/stdlib/tkinter/dnd.pyi @@ -1,8 +1,9 @@ from tkinter import Event, Misc, Tk, Widget -from typing import ClassVar, Protocol +from typing import ClassVar, Protocol, type_check_only __all__ = ["dnd_start", "DndHandler"] +@type_check_only class _DndSource(Protocol): def dnd_end(self, target: Widget | None, event: Event[Misc] | None, /) -> None: ... diff --git a/stdlib/tkinter/font.pyi b/stdlib/tkinter/font.pyi index cab97490be34..327ba7a2432e 100644 --- a/stdlib/tkinter/font.pyi +++ b/stdlib/tkinter/font.pyi @@ -2,7 +2,7 @@ import _tkinter import itertools import sys import tkinter -from typing import Any, ClassVar, Final, Literal, TypedDict, overload +from typing import Any, ClassVar, Final, Literal, TypedDict, overload, type_check_only from typing_extensions import TypeAlias, Unpack __all__ = ["NORMAL", "ROMAN", "BOLD", "ITALIC", "nametofont", "Font", "families", "names"] @@ -23,6 +23,7 @@ _FontDescription: TypeAlias = ( | _tkinter.Tcl_Obj # A font object constructed in Tcl ) +@type_check_only class _FontDict(TypedDict): family: str size: int @@ -31,6 +32,7 @@ class _FontDict(TypedDict): underline: bool overstrike: bool +@type_check_only class _MetricsDict(TypedDict): ascent: int descent: int diff --git a/stdlib/tkinter/ttk.pyi b/stdlib/tkinter/ttk.pyi index 50b9cd8f9bcd..c46239df81eb 100644 --- a/stdlib/tkinter/ttk.pyi +++ b/stdlib/tkinter/ttk.pyi @@ -3,7 +3,7 @@ import tkinter from _typeshed import Incomplete, MaybeNone from collections.abc import Callable from tkinter.font import _FontDescription -from typing import Any, Literal, TypedDict, overload +from typing import Any, Literal, TypedDict, overload, type_check_only from typing_extensions import TypeAlias __all__ = [ @@ -928,6 +928,7 @@ class Spinbox(Entry): config = configure # type: ignore[assignment] def set(self, value: Any) -> None: ... +@type_check_only class _TreeviewItemDict(TypedDict): text: str image: list[str] | Literal[""] # no idea why it's wrapped in list @@ -935,6 +936,7 @@ class _TreeviewItemDict(TypedDict): open: bool # actually 0 or 1 tags: list[str] | Literal[""] +@type_check_only class _TreeviewTagDict(TypedDict): # There is also 'text' and 'anchor', but they don't seem to do anything, using them is likely a bug foreground: str @@ -942,6 +944,7 @@ class _TreeviewTagDict(TypedDict): font: _FontDescription image: str # not wrapped in list :D +@type_check_only class _TreeviewHeaderDict(TypedDict): text: str image: list[str] | Literal[""] @@ -949,6 +952,7 @@ class _TreeviewHeaderDict(TypedDict): command: str state: str # Doesn't seem to appear anywhere else than in these dicts +@type_check_only class _TreeviewColumnDict(TypedDict): width: int minwidth: int diff --git a/stdlib/turtle.pyi b/stdlib/turtle.pyi index e036a6e3c0d7..7d39026b8041 100644 --- a/stdlib/turtle.pyi +++ b/stdlib/turtle.pyi @@ -3,7 +3,7 @@ from _typeshed import StrPath from collections.abc import Callable, Generator, Sequence from contextlib import contextmanager from tkinter import Canvas, Frame, Misc, PhotoImage, Scrollbar -from typing import Any, ClassVar, Literal, TypedDict, overload +from typing import Any, ClassVar, Literal, TypedDict, overload, type_check_only from typing_extensions import Self, TypeAlias __all__ = [ @@ -146,6 +146,7 @@ if sys.version_info < (3, 13): _Color: TypeAlias = str | tuple[float, float, float] _AnyColor: TypeAlias = Any +@type_check_only class _PenState(TypedDict): shown: bool pendown: bool diff --git a/stdlib/typing.pyi b/stdlib/typing.pyi index d296c8d92149..a85aa2e2dc83 100644 --- a/stdlib/typing.pyi +++ b/stdlib/typing.pyi @@ -419,6 +419,7 @@ def type_check_only(func_or_cls: _FT) -> _FT: ... # Type aliases and type constructors +@type_check_only class _Alias: # Class for defining generic aliases for library types. def __getitem__(self, typeargs: Any) -> Any: ... @@ -1125,6 +1126,7 @@ if sys.version_info >= (3, 13): def is_protocol(tp: type, /) -> bool: ... def get_protocol_members(tp: type, /) -> frozenset[str]: ... @final + @type_check_only class _NoDefaultType: ... NoDefault: _NoDefaultType diff --git a/stdlib/typing_extensions.pyi b/stdlib/typing_extensions.pyi index a8875450d767..22b6ada8ffb7 100644 --- a/stdlib/typing_extensions.pyi +++ b/stdlib/typing_extensions.pyi @@ -472,6 +472,7 @@ else: def is_protocol(tp: type, /) -> bool: ... def get_protocol_members(tp: type, /) -> frozenset[str]: ... @final + @type_check_only class _NoDefaultType: ... NoDefault: _NoDefaultType @@ -603,6 +604,7 @@ class Doc: def __eq__(self, other: object) -> bool: ... # PEP 728 +@type_check_only class _NoExtraItemsType: ... NoExtraItems: _NoExtraItemsType diff --git a/stdlib/unittest/case.pyi b/stdlib/unittest/case.pyi index 22d39c78feac..a602196e73c6 100644 --- a/stdlib/unittest/case.pyi +++ b/stdlib/unittest/case.pyi @@ -7,7 +7,7 @@ from collections.abc import Callable, Container, Iterable, Mapping, Sequence, Se from contextlib import AbstractContextManager from re import Pattern from types import GenericAlias, TracebackType -from typing import Any, AnyStr, Final, Generic, NoReturn, Protocol, SupportsAbs, SupportsRound, TypeVar, overload +from typing import Any, AnyStr, Final, Generic, NoReturn, Protocol, SupportsAbs, SupportsRound, TypeVar, overload, type_check_only from typing_extensions import Never, ParamSpec, Self from unittest._log import _AssertLogsContext, _LoggingWatcher from warnings import WarningMessage @@ -56,6 +56,7 @@ def skipUnless(condition: object, reason: str) -> Callable[[_FT], _FT]: ... class SkipTest(Exception): def __init__(self, reason: str) -> None: ... +@type_check_only class _SupportsAbsAndDunderGE(SupportsDunderGE[Any], SupportsAbs[Any], Protocol): ... class TestCase: diff --git a/stdlib/unittest/main.pyi b/stdlib/unittest/main.pyi index 22f2ec10634d..152e9c33209c 100644 --- a/stdlib/unittest/main.pyi +++ b/stdlib/unittest/main.pyi @@ -5,12 +5,13 @@ import unittest.result import unittest.suite from collections.abc import Iterable from types import ModuleType -from typing import Any, Final, Protocol +from typing import Any, Final, Protocol, type_check_only from typing_extensions import deprecated MAIN_EXAMPLES: Final[str] MODULE_EXAMPLES: Final[str] +@type_check_only class _TestRunner(Protocol): def run(self, test: unittest.suite.TestSuite | unittest.case.TestCase, /) -> unittest.result.TestResult: ... diff --git a/stdlib/unittest/mock.pyi b/stdlib/unittest/mock.pyi index ec5fced32ea4..6b0941a91719 100644 --- a/stdlib/unittest/mock.pyi +++ b/stdlib/unittest/mock.pyi @@ -3,7 +3,7 @@ from _typeshed import MaybeNone from collections.abc import Awaitable, Callable, Coroutine, Iterable, Mapping, Sequence from contextlib import _GeneratorContextManager from types import TracebackType -from typing import Any, ClassVar, Final, Generic, Literal, TypeVar, overload +from typing import Any, ClassVar, Final, Generic, Literal, TypeVar, overload, type_check_only from typing_extensions import ParamSpec, Self, TypeAlias _T = TypeVar("_T") @@ -262,6 +262,7 @@ class _patch(Generic[_T]): # This class does not exist at runtime, it's a hack to make this work: # @patch("foo") # def bar(..., mock: MagicMock) -> None: ... +@type_check_only class _patch_pass_arg(_patch[_T]): @overload def __call__(self, func: _TT) -> _TT: ... @@ -288,6 +289,7 @@ class _patch_dict: # This class does not exist at runtime, it's a hack to add methods to the # patch() function. +@type_check_only class _patcher: TEST_PREFIX: str dict: type[_patch_dict] diff --git a/stdlib/unittest/runner.pyi b/stdlib/unittest/runner.pyi index 783764464a53..f76771f55e13 100644 --- a/stdlib/unittest/runner.pyi +++ b/stdlib/unittest/runner.pyi @@ -4,15 +4,17 @@ import unittest.result import unittest.suite from _typeshed import SupportsFlush, SupportsWrite from collections.abc import Callable, Iterable -from typing import Any, Generic, Protocol, TypeVar +from typing import Any, Generic, Protocol, TypeVar, type_check_only from typing_extensions import Never, TypeAlias from warnings import _ActionKind _ResultClassType: TypeAlias = Callable[[_TextTestStream, bool, int], TextTestResult[Any]] +@type_check_only class _SupportsWriteAndFlush(SupportsWrite[str], SupportsFlush, Protocol): ... # All methods used by unittest.runner.TextTestResult's stream +@type_check_only class _TextTestStream(_SupportsWriteAndFlush, Protocol): def writeln(self, arg: str | None = None, /) -> None: ... diff --git a/stdlib/urllib/request.pyi b/stdlib/urllib/request.pyi index d8fc5e0d8f48..b99577c1cf71 100644 --- a/stdlib/urllib/request.pyi +++ b/stdlib/urllib/request.pyi @@ -6,7 +6,7 @@ from email.message import Message from http.client import HTTPConnection, HTTPMessage, HTTPResponse from http.cookiejar import CookieJar from re import Pattern -from typing import IO, Any, ClassVar, NoReturn, Protocol, TypeVar, overload +from typing import IO, Any, ClassVar, NoReturn, Protocol, TypeVar, overload, type_check_only from typing_extensions import TypeAlias, deprecated from urllib.error import HTTPError as HTTPError from urllib.response import addclosehook, addinfourl @@ -237,6 +237,7 @@ class ProxyDigestAuthHandler(BaseHandler, AbstractDigestAuthHandler): auth_header: ClassVar[str] # undocumented def http_error_407(self, req: Request, fp: IO[bytes], code: int, msg: str, headers: HTTPMessage) -> _UrlopenRet | None: ... +@type_check_only class _HTTPConnectionProtocol(Protocol): def __call__( self, diff --git a/stdlib/xml/dom/minidom.pyi b/stdlib/xml/dom/minidom.pyi index ab2ef87e38a8..b9da9f3558ff 100644 --- a/stdlib/xml/dom/minidom.pyi +++ b/stdlib/xml/dom/minidom.pyi @@ -3,7 +3,7 @@ from _collections_abc import dict_keys, dict_values from _typeshed import Incomplete, ReadableBuffer, SupportsRead, SupportsWrite from collections.abc import Iterable, Sequence from types import TracebackType -from typing import Any, ClassVar, Generic, Literal, NoReturn, Protocol, TypeVar, overload +from typing import Any, ClassVar, Generic, Literal, NoReturn, Protocol, TypeVar, overload, type_check_only from typing_extensions import Self, TypeAlias from xml.dom.minicompat import EmptyNodeList, NodeList from xml.dom.xmlbuilder import DocumentLS, DOMImplementationLS @@ -40,9 +40,11 @@ _ImportableNodeVar = TypeVar( | Notation, ) +@type_check_only class _DOMErrorHandler(Protocol): def handleError(self, error: Exception) -> bool: ... +@type_check_only class _UserDataHandler(Protocol): def handle(self, operation: int, key: str, data: Any, src: Node, dst: Node) -> None: ... diff --git a/stdlib/xml/etree/ElementInclude.pyi b/stdlib/xml/etree/ElementInclude.pyi index 8f20ee15a14e..fd829fdaa5ff 100644 --- a/stdlib/xml/etree/ElementInclude.pyi +++ b/stdlib/xml/etree/ElementInclude.pyi @@ -1,7 +1,8 @@ from _typeshed import FileDescriptorOrPath -from typing import Final, Literal, Protocol, overload +from typing import Final, Literal, Protocol, overload, type_check_only from xml.etree.ElementTree import Element +@type_check_only class _Loader(Protocol): @overload def __call__(self, href: FileDescriptorOrPath, parse: Literal["xml"], encoding: str | None = None) -> Element: ... diff --git a/stdlib/xml/etree/ElementTree.pyi b/stdlib/xml/etree/ElementTree.pyi index 4c55a1a7452e..1d7e1725dd8e 100644 --- a/stdlib/xml/etree/ElementTree.pyi +++ b/stdlib/xml/etree/ElementTree.pyi @@ -335,6 +335,7 @@ class C14NWriterTarget: # The target type is tricky, because the implementation doesn't # require any particular attribute to be present. This documents the attributes # that can be present, but uncommenting any of them would require them. +@type_check_only class _Target(Protocol): # start: Callable[str, dict[str, str], Any] | None # end: Callable[[str], Any] | None diff --git a/stdlib/xml/sax/__init__.pyi b/stdlib/xml/sax/__init__.pyi index ebe92d28c74d..5a82b48c1e19 100644 --- a/stdlib/xml/sax/__init__.pyi +++ b/stdlib/xml/sax/__init__.pyi @@ -1,7 +1,7 @@ import sys from _typeshed import ReadableBuffer, StrPath, SupportsRead, _T_co from collections.abc import Iterable -from typing import Protocol +from typing import Protocol, type_check_only from typing_extensions import TypeAlias from xml.sax._exceptions import ( SAXException as SAXException, @@ -13,6 +13,7 @@ from xml.sax._exceptions import ( from xml.sax.handler import ContentHandler as ContentHandler, ErrorHandler as ErrorHandler from xml.sax.xmlreader import InputSource as InputSource, XMLReader +@type_check_only class _SupportsReadClose(SupportsRead[_T_co], Protocol[_T_co]): def close(self) -> None: ... diff --git a/stdlib/xmlrpc/client.pyi b/stdlib/xmlrpc/client.pyi index 6cc4361f4a09..42420ee85848 100644 --- a/stdlib/xmlrpc/client.pyi +++ b/stdlib/xmlrpc/client.pyi @@ -6,9 +6,10 @@ from collections.abc import Callable, Iterable, Mapping from datetime import datetime from io import BytesIO from types import TracebackType -from typing import Any, ClassVar, Final, Literal, Protocol, overload +from typing import Any, ClassVar, Final, Literal, Protocol, overload, type_check_only from typing_extensions import Self, TypeAlias +@type_check_only class _SupportsTimeTuple(Protocol): def timetuple(self) -> time.struct_time: ... diff --git a/stdlib/xmlrpc/server.pyi b/stdlib/xmlrpc/server.pyi index 5f497aa7190e..286aaf980fbf 100644 --- a/stdlib/xmlrpc/server.pyi +++ b/stdlib/xmlrpc/server.pyi @@ -4,28 +4,34 @@ import socketserver from _typeshed import ReadableBuffer from collections.abc import Callable, Iterable, Mapping from re import Pattern -from typing import Any, ClassVar, Protocol +from typing import Any, ClassVar, Protocol, type_check_only from typing_extensions import TypeAlias from xmlrpc.client import Fault, _Marshallable # The dispatch accepts anywhere from 0 to N arguments, no easy way to allow this in mypy +@type_check_only class _DispatchArity0(Protocol): def __call__(self) -> _Marshallable: ... +@type_check_only class _DispatchArity1(Protocol): def __call__(self, arg1: _Marshallable, /) -> _Marshallable: ... +@type_check_only class _DispatchArity2(Protocol): def __call__(self, arg1: _Marshallable, arg2: _Marshallable, /) -> _Marshallable: ... +@type_check_only class _DispatchArity3(Protocol): def __call__(self, arg1: _Marshallable, arg2: _Marshallable, arg3: _Marshallable, /) -> _Marshallable: ... +@type_check_only class _DispatchArity4(Protocol): def __call__( self, arg1: _Marshallable, arg2: _Marshallable, arg3: _Marshallable, arg4: _Marshallable, / ) -> _Marshallable: ... +@type_check_only class _DispatchArityN(Protocol): def __call__(self, *args: _Marshallable) -> _Marshallable: ... diff --git a/stdlib/zipfile/__init__.pyi b/stdlib/zipfile/__init__.pyi index 220ae02c3b8c..73e3a92fd0e2 100644 --- a/stdlib/zipfile/__init__.pyi +++ b/stdlib/zipfile/__init__.pyi @@ -5,7 +5,7 @@ from collections.abc import Callable, Iterable, Iterator from io import TextIOWrapper from os import PathLike from types import TracebackType -from typing import IO, Final, Literal, Protocol, overload +from typing import IO, Final, Literal, Protocol, overload, type_check_only from typing_extensions import Self, TypeAlias __all__ = [ @@ -41,6 +41,7 @@ error = BadZipfile class LargeZipFile(Exception): ... +@type_check_only class _ZipStream(Protocol): def read(self, n: int, /) -> bytes: ... # The following methods are optional: @@ -49,11 +50,13 @@ class _ZipStream(Protocol): # def seek(self, n: int, /) -> object: ... # Stream shape as required by _EndRecData() and _EndRecData64(). +@type_check_only class _SupportsReadSeekTell(Protocol): def read(self, n: int = ..., /) -> bytes: ... def seek(self, cookie: int, whence: int, /) -> object: ... def tell(self) -> int: ... +@type_check_only class _ClosableZipStream(_ZipStream, Protocol): def close(self) -> object: ... @@ -93,18 +96,23 @@ class ZipExtFile(io.BufferedIOBase): def read1(self, n: int | None) -> bytes: ... # type: ignore[override] def seek(self, offset: int, whence: int = 0) -> int: ... +@type_check_only class _Writer(Protocol): def write(self, s: str, /) -> object: ... +@type_check_only class _ZipReadable(Protocol): def seek(self, offset: int, whence: int = 0, /) -> int: ... def read(self, n: int = -1, /) -> bytes: ... +@type_check_only class _ZipTellable(Protocol): def tell(self) -> int: ... +@type_check_only class _ZipReadableTellable(_ZipReadable, _ZipTellable, Protocol): ... +@type_check_only class _ZipWritable(Protocol): def flush(self) -> None: ... def close(self) -> None: ... diff --git a/stdlib/zoneinfo/_common.pyi b/stdlib/zoneinfo/_common.pyi index a2f29f2d14f0..e6d2d83caac1 100644 --- a/stdlib/zoneinfo/_common.pyi +++ b/stdlib/zoneinfo/_common.pyi @@ -1,6 +1,7 @@ import io -from typing import Any, Protocol +from typing import Any, Protocol, type_check_only +@type_check_only class _IOBytes(Protocol): def read(self, size: int, /) -> bytes: ... def seek(self, size: int, whence: int = ..., /) -> Any: ...