From c57d3abdd7f499025a7fd85118b198a5f508fe95 Mon Sep 17 00:00:00 2001 From: Michael H Date: Tue, 4 Nov 2025 16:53:41 -0500 Subject: [PATCH 1/2] Ammend annotation for `__slots__` This fixes an assignablity issue in subclasses that was caused by using too strict an annotation for the purpose of `__slots__` as a special case for mypy. We can keep an annotation here for mypy if really needed, but it needs to work with subclass assignability. ideally, long term all data model names are understood as part of the specification, but this needs to be permissive enough to allow subclasses to add members. See error in pyright as a result of adding a special case for mypy: https://github.com/microsoft/pyright/issues/11058 --- stdlib/asyncio/protocols.pyi | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/stdlib/asyncio/protocols.pyi b/stdlib/asyncio/protocols.pyi index 2c52ad4be410..33857481d46f 100644 --- a/stdlib/asyncio/protocols.pyi +++ b/stdlib/asyncio/protocols.pyi @@ -14,7 +14,7 @@ class BaseProtocol: class Protocol(BaseProtocol): # Need annotation or mypy will complain about 'Cannot determine type of "__slots__" in base class' - __slots__: tuple[()] = () + __slots__: tuple[str, ...] = () def data_received(self, data: bytes) -> None: ... def eof_received(self) -> bool | None: ... From 2f30352b4fa9547bec8946a14dc587390012642b Mon Sep 17 00:00:00 2001 From: Michael Hall Date: Tue, 4 Nov 2025 17:04:22 -0500 Subject: [PATCH 2/2] other instances of slots typed as a 0 item tuple --- stdlib/asyncio/protocols.pyi | 2 +- stubs/protobuf/google/protobuf/internal/well_known_types.pyi | 4 ++-- stubs/protobuf/google/protobuf/message.pyi | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/stdlib/asyncio/protocols.pyi b/stdlib/asyncio/protocols.pyi index 33857481d46f..3a8965f03e29 100644 --- a/stdlib/asyncio/protocols.pyi +++ b/stdlib/asyncio/protocols.pyi @@ -35,7 +35,7 @@ class DatagramProtocol(BaseProtocol): def error_received(self, exc: Exception) -> None: ... class SubprocessProtocol(BaseProtocol): - __slots__: tuple[()] = () + __slots__: tuple[str, ...] = () def pipe_data_received(self, fd: int, data: bytes) -> None: ... def pipe_connection_lost(self, fd: int, exc: Exception | None) -> None: ... def process_exited(self) -> None: ... diff --git a/stubs/protobuf/google/protobuf/internal/well_known_types.pyi b/stubs/protobuf/google/protobuf/internal/well_known_types.pyi index 69649998db4f..6527d3f6978e 100644 --- a/stubs/protobuf/google/protobuf/internal/well_known_types.pyi +++ b/stubs/protobuf/google/protobuf/internal/well_known_types.pyi @@ -67,7 +67,7 @@ _StructValue: TypeAlias = struct_pb2.Struct | struct_pb2.ListValue | str | float _StructValueArg: TypeAlias = _StructValue | Mapping[str, _StructValueArg] | Sequence[_StructValueArg] class Struct: - __slots__: tuple[()] = () + __slots__: tuple[str, ...] = () def __getitem__(self, key: str) -> _StructValue: ... def __setitem__(self, key: str, value: _StructValueArg) -> None: ... def __delitem__(self, key: str) -> None: ... @@ -81,7 +81,7 @@ class Struct: def update(self, dictionary: SupportsItems[str, _StructValueArg]) -> None: ... class ListValue: - __slots__: tuple[()] = () + __slots__: tuple[str, ...] = () def __len__(self) -> int: ... def append(self, value: _StructValue) -> None: ... def extend(self, elem_seq: Iterable[_StructValue]) -> None: ... diff --git a/stubs/protobuf/google/protobuf/message.pyi b/stubs/protobuf/google/protobuf/message.pyi index 5145b5330a2c..bd2aff9b7676 100644 --- a/stubs/protobuf/google/protobuf/message.pyi +++ b/stubs/protobuf/google/protobuf/message.pyi @@ -12,7 +12,7 @@ class DecodeError(Error): ... class EncodeError(Error): ... class Message: - __slots__: tuple[()] = () + __slots__: tuple[str, ...] = () DESCRIPTOR: Descriptor | _upb_Descriptor def __deepcopy__(self, memo: Any = None) -> Self: ... def __eq__(self, other_msg): ...