From af81a5ec54101cf913c17820644c30376ca727b8 Mon Sep 17 00:00:00 2001 From: pboulos Date: Thu, 11 Jun 2026 21:01:19 -0400 Subject: [PATCH] [grpcio] Fix AioRpcError.trailing_metadata and Metadata iteration [pre-commit.ci] auto fixes from pre-commit.com hooks --- stubs/grpcio/@tests/test_cases/check_aio.py | 11 +++++------ stubs/grpcio/grpc/aio/__init__.pyi | 20 +++++++++++++++++--- 2 files changed, 22 insertions(+), 9 deletions(-) diff --git a/stubs/grpcio/@tests/test_cases/check_aio.py b/stubs/grpcio/@tests/test_cases/check_aio.py index 7338268ed3f8..f76a34987cb5 100644 --- a/stubs/grpcio/@tests/test_cases/check_aio.py +++ b/stubs/grpcio/@tests/test_cases/check_aio.py @@ -17,9 +17,8 @@ async def metadata() -> None: metadata = await cast(grpc.aio.Call, None).initial_metadata() assert_type(metadata["foo"], grpc.aio._MetadataValue) - for k in metadata: - assert_type(k, str) - - for k, v in metadata.items(): - assert_type(k, str) - assert_type(v, grpc.aio._MetadataValue) + # grpc.aio.Metadata is a Collection that iterates as (key, value) tuples, + # not a Mapping that iterates bare keys. + for key, value in metadata: + assert_type(key, str) + assert_type(value, grpc.aio._MetadataValue) diff --git a/stubs/grpcio/grpc/aio/__init__.pyi b/stubs/grpcio/grpc/aio/__init__.pyi index 82ef20f91bf4..469a325793f7 100644 --- a/stubs/grpcio/grpc/aio/__init__.pyi +++ b/stubs/grpcio/grpc/aio/__init__.pyi @@ -1,7 +1,18 @@ import abc import asyncio from _typeshed import Incomplete -from collections.abc import AsyncIterable, AsyncIterator, Awaitable, Callable, Generator, Iterable, Iterator, Mapping, Sequence +from collections.abc import ( + AsyncIterable, + AsyncIterator, + Awaitable, + Callable, + Collection, + Generator, + Iterable, + Iterator, + Mapping, + Sequence, +) from concurrent import futures from types import TracebackType from typing import Any, Generic, NoReturn, TypeAlias, TypeVar, overload, type_check_only @@ -42,6 +53,9 @@ class AioRpcError(RpcError): ) -> None: ... def debug_error_string(self) -> str: ... def initial_metadata(self) -> Metadata: ... + # AioRpcError returns the async Metadata, overriding the synchronous + # grpc.RpcError.trailing_metadata() -> tuple[_Metadatum, ...]. + def trailing_metadata(self) -> Metadata: ... # type: ignore[override] # Create Client: @@ -445,7 +459,7 @@ _MetadatumType: TypeAlias = tuple[_MetadataKey, _MetadataValue] _MetadataType: TypeAlias = Metadata | Sequence[_MetadatumType] _T = TypeVar("_T") -class Metadata(Mapping[_MetadataKey, _MetadataValue]): +class Metadata(Collection[_MetadatumType]): def __init__(self, *args: tuple[_MetadataKey, _MetadataValue]) -> None: ... @classmethod def from_tuple(cls, raw_metadata: tuple[_MetadataKey, _MetadataValue]) -> Metadata: ... @@ -455,7 +469,7 @@ class Metadata(Mapping[_MetadataKey, _MetadataValue]): def __setitem__(self, key: _MetadataKey, value: _MetadataValue) -> None: ... def __delitem__(self, key: _MetadataKey) -> None: ... def delete_all(self, key: _MetadataKey) -> None: ... - def __iter__(self) -> Iterator[_MetadataKey]: ... + def __iter__(self) -> Iterator[_MetadatumType]: ... @overload def get(self, key: _MetadataKey, default: None = None) -> _MetadataValue | None: ...