Skip to content

Commit 602da37

Browse files
[grpcio] ServerInterceptor and GenericRpcHandler should not be generic (#14785)
1 parent 16c4e13 commit 602da37

File tree

5 files changed

+42
-26
lines changed

5 files changed

+42
-26
lines changed

stubs/grpcio/@tests/test_cases/check_aio.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
from __future__ import annotations
22

3-
from typing import Any, cast
3+
from typing import cast
44
from typing_extensions import assert_type
55

66
import grpc.aio
@@ -9,7 +9,7 @@
99
client_interceptors: list[grpc.aio.ClientInterceptor] = []
1010
grpc.aio.insecure_channel("target", interceptors=client_interceptors)
1111

12-
server_interceptors: list[grpc.aio.ServerInterceptor[Any, Any]] = []
12+
server_interceptors: list[grpc.aio.ServerInterceptor] = []
1313
grpc.aio.server(interceptors=server_interceptors)
1414

1515

stubs/grpcio/@tests/test_cases/check_handler_inheritance.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
from __future__ import annotations
22

3-
from typing import cast
3+
from typing import Any, cast
44
from typing_extensions import assert_type
55

66
import grpc
@@ -19,11 +19,11 @@ def unary_unary_call(rq: Request, ctx: grpc.ServicerContext) -> Response:
1919
return Response()
2020

2121

22-
class ServiceHandler(grpc.ServiceRpcHandler[Request, Response]):
22+
class ServiceHandler(grpc.ServiceRpcHandler):
2323
def service_name(self) -> str:
2424
return "hello"
2525

26-
def service(self, handler_call_details: grpc.HandlerCallDetails) -> grpc.RpcMethodHandler[Request, Response] | None:
26+
def service(self, handler_call_details: grpc.HandlerCallDetails) -> grpc.RpcMethodHandler[Any, Any] | None:
2727
rpc = grpc.RpcMethodHandler[Request, Response]()
2828
rpc.unary_unary = unary_unary_call
2929
return rpc
Lines changed: 22 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,22 +1,35 @@
11
from __future__ import annotations
22

33
from collections.abc import Callable
4+
from concurrent.futures.thread import ThreadPoolExecutor
5+
from typing import Awaitable, TypeVar
46

57
import grpc
8+
import grpc.aio
69

10+
RequestT = TypeVar("RequestT")
11+
ResponseT = TypeVar("ResponseT")
712

8-
class Request:
9-
pass
1013

14+
class NoopInterceptor(grpc.ServerInterceptor):
15+
def intercept_service(
16+
self,
17+
continuation: Callable[[grpc.HandlerCallDetails], grpc.RpcMethodHandler[RequestT, ResponseT] | None],
18+
handler_call_details: grpc.HandlerCallDetails,
19+
) -> grpc.RpcMethodHandler[RequestT, ResponseT] | None:
20+
return continuation(handler_call_details)
1121

12-
class Response:
13-
pass
1422

23+
grpc.server(interceptors=[NoopInterceptor()], thread_pool=ThreadPoolExecutor())
1524

16-
class NoopInterceptor(grpc.ServerInterceptor[Request, Response]):
17-
def intercept_service(
25+
26+
class NoopAioInterceptor(grpc.aio.ServerInterceptor):
27+
async def intercept_service(
1828
self,
19-
continuation: Callable[[grpc.HandlerCallDetails], grpc.RpcMethodHandler[Request, Response] | None],
29+
continuation: Callable[[grpc.HandlerCallDetails], Awaitable[grpc.RpcMethodHandler[RequestT, ResponseT]]],
2030
handler_call_details: grpc.HandlerCallDetails,
21-
) -> grpc.RpcMethodHandler[Request, Response] | None:
22-
return continuation(handler_call_details)
31+
) -> grpc.RpcMethodHandler[RequestT, ResponseT]:
32+
return await continuation(handler_call_details)
33+
34+
35+
grpc.aio.server(interceptors=[NoopAioInterceptor()])

stubs/grpcio/grpc/__init__.pyi

Lines changed: 10 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -108,8 +108,8 @@ def composite_channel_credentials(
108108

109109
def server(
110110
thread_pool: futures.ThreadPoolExecutor,
111-
handlers: list[GenericRpcHandler[Any, Any]] | None = None,
112-
interceptors: list[ServerInterceptor[Any, Any]] | None = None,
111+
handlers: list[GenericRpcHandler] | None = None,
112+
interceptors: list[ServerInterceptor] | None = None,
113113
options: _Options | None = None,
114114
maximum_concurrent_rpcs: int | None = None,
115115
compression: Compression | None = None,
@@ -173,7 +173,7 @@ def stream_stream_rpc_method_handler(
173173
) -> RpcMethodHandler[_TRequest, _TResponse]: ...
174174
def method_handlers_generic_handler(
175175
service: str, method_handlers: dict[str, RpcMethodHandler[Any, Any]]
176-
) -> GenericRpcHandler[Any, Any]: ...
176+
) -> GenericRpcHandler: ...
177177

178178
# Channel Ready Future:
179179

@@ -264,7 +264,7 @@ class Channel(abc.ABC):
264264

265265
class Server(abc.ABC):
266266
@abc.abstractmethod
267-
def add_generic_rpc_handlers(self, generic_rpc_handlers: Iterable[GenericRpcHandler[Any, Any]]) -> None: ...
267+
def add_generic_rpc_handlers(self, generic_rpc_handlers: Iterable[GenericRpcHandler]) -> None: ...
268268

269269
# Returns an integer port on which server will accept RPC requests.
270270
@abc.abstractmethod
@@ -493,17 +493,19 @@ class HandlerCallDetails(abc.ABC):
493493
method: str
494494
invocation_metadata: _Metadata
495495

496-
class GenericRpcHandler(abc.ABC, Generic[_TRequest, _TResponse]):
496+
class GenericRpcHandler(abc.ABC):
497+
# The return type depends on the handler call details.
497498
@abc.abstractmethod
498-
def service(self, handler_call_details: HandlerCallDetails) -> RpcMethodHandler[_TRequest, _TResponse] | None: ...
499+
def service(self, handler_call_details: HandlerCallDetails) -> RpcMethodHandler[Any, Any] | None: ...
499500

500-
class ServiceRpcHandler(GenericRpcHandler[_TRequest, _TResponse], metaclass=abc.ABCMeta):
501+
class ServiceRpcHandler(GenericRpcHandler, metaclass=abc.ABCMeta):
501502
@abc.abstractmethod
502503
def service_name(self) -> str: ...
503504

504505
# Service-Side Interceptor:
505506

506-
class ServerInterceptor(abc.ABC, Generic[_TRequest, _TResponse]):
507+
class ServerInterceptor(abc.ABC):
508+
# This method (not the class) is generic over _TRequest and _TResponse.
507509
@abc.abstractmethod
508510
def intercept_service(
509511
self,

stubs/grpcio/grpc/aio/__init__.pyi

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -65,8 +65,8 @@ def secure_channel(
6565

6666
def server(
6767
migration_thread_pool: futures.Executor | None = None,
68-
handlers: Sequence[GenericRpcHandler[Any, Any]] | None = None,
69-
interceptors: Sequence[ServerInterceptor[Any, Any]] | None = None,
68+
handlers: Sequence[GenericRpcHandler] | None = None,
69+
interceptors: Sequence[ServerInterceptor] | None = None,
7070
options: _Options | None = None,
7171
maximum_concurrent_rpcs: int | None = None,
7272
compression: Compression | None = None,
@@ -125,7 +125,7 @@ class Channel(abc.ABC):
125125

126126
class Server(metaclass=abc.ABCMeta):
127127
@abc.abstractmethod
128-
def add_generic_rpc_handlers(self, generic_rpc_handlers: Iterable[GenericRpcHandler[Any, Any]]) -> None: ...
128+
def add_generic_rpc_handlers(self, generic_rpc_handlers: Iterable[GenericRpcHandler]) -> None: ...
129129

130130
# Returns an integer port on which server will accept RPC requests.
131131
@abc.abstractmethod
@@ -355,7 +355,8 @@ class StreamStreamClientInterceptor(Generic[_TRequest, _TResponse], metaclass=ab
355355

356356
# Server-Side Interceptor:
357357

358-
class ServerInterceptor(Generic[_TRequest, _TResponse], metaclass=abc.ABCMeta):
358+
class ServerInterceptor(metaclass=abc.ABCMeta):
359+
# This method (not the class) is generic over _TRequest and _TResponse.
359360
@abc.abstractmethod
360361
async def intercept_service(
361362
self,

0 commit comments

Comments
 (0)