-
-
Notifications
You must be signed in to change notification settings - Fork 1.9k
Open
Description
The grpcio
package provides interceptor base classes (ServerInterceptor
, UnaryUnaryClientInterceptor
, etc.) that clients can subclass in order to intercept calls made by a gRPC client or server. However, the grpcio
package and typeshed disagree about whether they are generic, which makes it difficult to use them with mypy's --disallow-any-generics
or --strict
options without type: ignore
comments.
- In grpc/grpc the interceptor classes are ABCs but not generics, and they do not implement
__class_getitem__
, so they cannot be subscripted at run time. The interceptor example subclasses the interceptor base classes without subscripting. - In typeshed the interceptor classes are ABCs and generics. If you use
--disallow-any-generics
or--strict
, you will get a[type-arg]
error if you subclass an interceptor base class without subscripting.
I also reported this to grpc/grpc as grpc/grpc#40550
Example 1 (no subscripting):
from __future__ import annotations
import grpc
import typing
class MyClientInterceptor(grpc.UnaryUnaryClientInterceptor):
def intercept_unary_unary(
self,
continuation: typing.Callable[[grpc.ClientCallDetails, grpc._TRequest], grpc._CallFuture[grpc._TResponse]],
client_call_details: grpc.ClientCallDetails,
request: grpc._TRequest
) -> grpc._CallFuture[grpc._TResponse]:
return continuation(client_call_details, request)
$ python test.py
$ mypy --disallow-any-generics test.py
test.py:5: error: Missing type parameters for generic type "UnaryUnaryClientInterceptor" [type-arg]
Found 1 error in 1 file (checked 1 source file)
$ mypy --strict test.py
test.py:5: error: Missing type parameters for generic type "UnaryUnaryClientInterceptor" [type-arg]
Found 1 error in 1 file (checked 1 source file)
Example 2 (subscripting):
from __future__ import annotations
import grpc
import typing
TRequest = typing.TypeVar("TRequest")
TResponse = typing.TypeVar("TResponse")
class MyClientInterceptor(
typing.Generic[TRequest, TResponse],
grpc.UnaryUnaryClientInterceptor[TRequest, TResponse]
):
def intercept_unary_unary(
self,
continuation: typing.Callable[[grpc.ClientCallDetails, TRequest], grpc._CallFuture[TResponse]],
client_call_details: grpc.ClientCallDetails,
request: TRequest
) -> grpc._CallFuture[TResponse]:
return continuation(client_call_details, request)
$ python test2.py
Traceback (most recent call last):
File "test2.py", line 10, in <module>
grpc.UnaryUnaryClientInterceptor[TRequest, TResponse]
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^^^^^^^^^^^^^^^^^^^^^
TypeError: type 'UnaryUnaryClientInterceptor' is not subscriptable
$ mypy --disallow-any-generics test2.py
Success: no issues found in 1 source file
$ mypy --strict test2.py
Success: no issues found in 1 source file
Versions used:
- Python 3.11.9 on Windows x64
- Packages
Package Version
----------------- --------------
grpcio 1.74.0
mypy 1.17.1
mypy_extensions 1.1.0
pathspec 0.12.1
pip 24.0
setuptools 65.5.0
types-grpcio 1.0.0.20250703
typing_extensions 4.15.0
Metadata
Metadata
Assignees
Labels
No labels