python-betterproto
python-betterproto copied to clipboard
`_stream_unary` doesn't work with empty iterables
Methods that use _stream_unary
work correctly when I use any iterable that is not empty. However, I noticed that when I try to pass any empty iterable (an empty list for example: []
) then I always get this exception:
grpclib.exceptions.ProtocolError: Request was not sent
I started digging into the source code, and the source of this error is here:
https://github.com/vmagamedov/grpclib/blob/e964bbb2cc2429294e9685d75ac5e2f1c2b13971/grpclib/client.py#L264-L275
The end
method is invoked here, after sending all messages:
https://github.com/danielgtaylor/python-betterproto/blob/bfc0fac7544bbdf4e0e2beabd45482a4958af514/src/betterproto/grpc/grpclib_client.py#L168-L176
If we now look at _stream_unary
:
https://github.com/danielgtaylor/python-betterproto/blob/bfc0fac7544bbdf4e0e2beabd45482a4958af514/src/betterproto/grpc/grpclib_client.py#L111-L131
it goes straight into sending messages with _send_messages
.
Compare that to _stream_stream
:
https://github.com/danielgtaylor/python-betterproto/blob/bfc0fac7544bbdf4e0e2beabd45482a4958af514/src/betterproto/grpc/grpclib_client.py#L135-L166
which first calls send_request
before calling _send_messages
.
It seems that when any messages are present, the request will be sent before the first message if not sent already, but if there are no messages then the request will not be sent and end
will fail. Unless I misunderstand something, it seems that the fix is to simply add await stream.send_request()
in _stream_unary
.
Would you be willing to create a PR for this with a test to prevent a regression like this again?
Sure: #422