`ServerInterceptor.intercept_service` return type doesn't match continuation return type
bkeryan opened this issue · 2 comments
Description of issue
ServerInterceptor.intercept_service
returns RpcMethodHandler[TRequest, TResponse]
but the continuation returns Optional[RpcMethodHandler[TRequest, TResponse]]
.
Writing an interceptor that calls return continuation(handler_call_details)
like in request_header_validator_interceptor.py causes mypy to emit this error:
error: Incompatible return value type (got "Optional[RpcMethodHandler[grpc.TRequest, grpc.TResponse]]", expected "RpcMethodHandler[grpc.TRequest, grpc.TResponse]") [return-value]
The docs say that intercept_service
may return None
.
Minimum Reproducible Example
main.py
from __future__ import annotations
import grpc
import typing
class NullServerInterceptor(grpc.ServerInterceptor):
def intercept_service(
self,
continuation: typing.Callable[
[grpc.HandlerCallDetails],
typing.Optional[grpc.RpcMethodHandler[grpc.TRequest, grpc.TResponse]]
],
handler_call_details: grpc.HandlerCallDetails,
) -> grpc.RpcMethodHandler[grpc.TRequest, grpc.TResponse]:
return continuation(handler_call_details)
run.sh
#!/usr/bin/env bash
set -o errexit -o nounset -o pipefail
python -m venv venv
source ./venv/bin/activate
pip install grpcio grpc-stubs mypy
mypy main.py
Full output
Requirement already satisfied: grpcio in ./venv/lib/python3.9/site-packages (1.57.0)
Requirement already satisfied: grpc-stubs in ./venv/lib/python3.9/site-packages (1.53.0.2)
Requirement already satisfied: mypy in ./venv/lib/python3.9/site-packages (1.5.0)
Requirement already satisfied: mypy-extensions>=1.0.0 in ./venv/lib/python3.9/site-packages (from mypy) (1.0.0)
Requirement already satisfied: tomli>=1.1.0 in ./venv/lib/python3.9/site-packages (from mypy) (2.0.1)
Requirement already satisfied: typing-extensions>=4.1.0 in ./venv/lib/python3.9/site-packages (from mypy) (4.7.1)
WARNING: You are using pip version 22.0.4; however, version 23.2.1 is available.
You should consider upgrading via the '/tmp/serverinterceptor/venv/bin/python -m pip install --upgrade pip' command.
main.py:14: error: Incompatible return value type (got "Optional[RpcMethodHandler[grpc.TRequest, grpc.TResponse]]", expected "RpcMethodHandler[grpc.TRequest, grpc.TResponse]") [return-value]
Found 1 error in 1 file (checked 1 source file)
hi @bkeryan. the issue isn't the library in this case.
the return type you have defined for continuation
is typing.Optional[grpc.RpcMethodHandler[grpc.TRequest, grpc.TResponse]]
, which means returning it directly would violate the return type you've defined for intercept_service()
one way to demonstrate this is to raise an exception when the value is None
, this will cause the typing to work out:
class NullServerInterceptor(grpc.ServerInterceptor[grpc.TRequest, grpc.TResponse]):
def intercept_service(
self,
continuation: Callable[
[grpc.HandlerCallDetails],
Optional[grpc.RpcMethodHandler[grpc.TRequest, grpc.TResponse]]
],
handler_call_details: grpc.HandlerCallDetails,
) -> grpc.RpcMethodHandler[grpc.TRequest, grpc.TResponse]:
response = continuation(handler_call_details)
if response is None:
raise NotImplementedError
return response
Hi @macro1,
Thanks for the heads up.
According to the linked documentation, intercept_service
is allowed to return None
. It is not required to raise an exception when the intercepted service returns None
.
The return type in the example was copied from grpc-stubs. At the time I filed this issue, grpc-stubs annotated intercept_service
with a return type of grpc.RpcMethodHandler[grpc.TRequest, grpc.TResponse]
. It has since been fixed by #43, which added typing.Optional
to the return type.