You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
[grpcio] Type async handler factories and mixed aio interceptor chains - #16580
Builds on the work by @XiaXia009 and @wolfgang-aura, following @srittau's guidance for a private, type-check-only _AsyncRpcMethodHandler.
Adds async overloads for all four handler factories and preserves handler types through generic registration and aio interceptor chains, including streaming handlers using context.write().
Aio interceptor continuations can return synchronous or asynchronous handlers without adapting their behavior, so their return type includes both. Fully annotated callbacks retain precise handler types. Callbacks accepting both synchronous and asynchronous inputs produce Any to avoid misclassifying ambiguous callbacks. The existing permissive factory fallbacks are retained for compatibility.
The reason will be displayed to describe this comment to others. Learn more.
🔵 Needs a closer look
Factory overloads can erase synchronous handler types or misclassify asynchronous callbacks as synchronous.
No open issues 🎉
2 previously missed issues
In code that hasn't changed since last review
Serializer overload misclassifies asynchronous callbacks as synchronous
stubs/grpcio/grpc/__init__.pyi:166
A non-None serializer does not always distinguish synchronous from asynchronous callbacks. Calling this factory with the test's partial_async_unary and a Callable[[object], bytes] serializer matches this first synchronous overload: the callback accepts the synchronous context through Any, and _TResponse can accommodate its coroutine return. The result is classified as RpcMethodHandler, incorrectly allowing synchronous-server registration. The positional and keyword-only overloads have this problem; stream_unary_rpc_method_handler also has it when both callback inputs are typed Any. Handle awaitable-returning ambiguity before these synchronous overloads, retaining an unknown handler type where necessary without regressing Any-returning synchronous callbacks. Add regression cases using a serializer that accepts object.
Any fallback misclassifies synchronous callbacks without codecs
stubs/grpcio/grpc/__init__.pyi:173
The Any fallback also matches unambiguously synchronous callbacks. For example, a callback annotated (bytes, grpc.ServicerContext) -> bytes, passed without codecs, now returns Any instead of retaining the RpcMethodHandler interface. This disables checks on subsequent handler use. The corresponding overloads in all four factories have the same problem, including when the serializer is optional. Restrict these ambiguity overloads to callbacks accepting both context types, for example by using ServicerContext | aio.ServicerContext[_TRequest, _TResponse] for their context parameter, so synchronous-only callbacks reach the typed fallback. Add regression assertions for fully annotated synchronous callbacks without codecs.
Support async factories, generic and registered handlers, and mixed
sync/async interceptor continuations while retaining sync defaults.
Builds on the async handler helper introduced by wolfgang-aura in
python#16461, with a mixed-handler continuation contract.
Prefer synchronous signatures when a response serializer is supplied.
Keep callbacks with insufficient type information gradual instead of
inferring an incorrect synchronous or asynchronous handler type.
Cover all four factories, keyword serializers, raw callbacks, and
partially annotated async behaviors in regression tests.
Apply the gradual overload to optional response serializers in all four
factories so Any-typed synchronous callbacks remain registrable.
Cover optional codecs and keyword serializers without contextual handler
types, and preserve precise inference for explicitly typed aio callbacks.
Limit gradual inference to callbacks that accept both sync and aio inputs.
Keep typed synchronous handlers precise without codecs, and avoid treating
coroutines as synchronous responses when serializers accept object.
Remove serializer-specific overloads and cover both review regressions.
@srittau Could you take a look when you have time? This follows your guidance in #15497 and also covers factory inference, registration, and mixed synchronous/asynchronous aio interceptor chains.
This branch has not been deployed
No deployments
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Fixes #15495.
Closes #15497 and #16461.
Builds on the work by @XiaXia009 and @wolfgang-aura, following @srittau's guidance for a private, type-check-only
_AsyncRpcMethodHandler.Adds async overloads for all four handler factories and preserves handler types through generic registration and aio interceptor chains, including streaming handlers using
context.write().Aio interceptor continuations can return synchronous or asynchronous handlers without adapting their behavior, so their return type includes both. Fully annotated callbacks retain precise handler types. Callbacks accepting both synchronous and asynchronous inputs produce
Anyto avoid misclassifying ambiguous callbacks. The existing permissive factory fallbacks are retained for compatibility.Runtime references: