From 061bf86a9cce960d0bdff78baabb7269c7facd3f Mon Sep 17 00:00:00 2001 From: Danny Weinberg Date: Thu, 4 Jun 2020 11:04:36 -0700 Subject: [PATCH] Set serialized_on_wire when message contains only lists This fixes a bug where serialized_on_wire was not set when a message contained only repeated values (eg in a list or map). The fix here is to just set it to true in the `parse` method as soon as we receive any valid data. This also adds a test to expose the behavior. --- betterproto/__init__.py | 3 ++ .../tests/inputs/repeated/repeated.proto | 6 +++ .../tests/inputs/repeated/test_repeated.py | 39 +++++++++++++++++++ 3 files changed, 48 insertions(+) create mode 100644 betterproto/tests/inputs/repeated/test_repeated.py diff --git a/betterproto/__init__.py b/betterproto/__init__.py index f394b41..c728a7c 100644 --- a/betterproto/__init__.py +++ b/betterproto/__init__.py @@ -747,6 +747,9 @@ class Message(ABC): self._unknown_fields += parsed.raw continue + # Got some data over the wire + self._serialized_on_wire = True + meta = self._betterproto.meta_by_field_name[field_name] value: Any diff --git a/betterproto/tests/inputs/repeated/repeated.proto b/betterproto/tests/inputs/repeated/repeated.proto index 42c1132..816bb26 100644 --- a/betterproto/tests/inputs/repeated/repeated.proto +++ b/betterproto/tests/inputs/repeated/repeated.proto @@ -1,5 +1,11 @@ syntax = "proto3"; +package repeated; + message Test { repeated string names = 1; } + +service ExampleService { + rpc DoThing (Test) returns (Test); +} diff --git a/betterproto/tests/inputs/repeated/test_repeated.py b/betterproto/tests/inputs/repeated/test_repeated.py new file mode 100644 index 0000000..7182a63 --- /dev/null +++ b/betterproto/tests/inputs/repeated/test_repeated.py @@ -0,0 +1,39 @@ +from typing import Dict + +import grpclib.const +import grpclib.server +import pytest +from grpclib.testing import ChannelFor + +import betterproto +from betterproto.tests.output_betterproto.repeated.repeated import ( + ExampleServiceStub, + Test, +) + + +class ExampleService: + async def DoThing( + self, stream: "grpclib.server.Stream[Test, Test]" + ): + request = await stream.recv_message() + await stream.send_message(request) + + def __mapping__(self) -> Dict[str, grpclib.const.Handler]: + return { + "/repeated.ExampleService/DoThing": grpclib.const.Handler( + self.DoThing, + grpclib.const.Cardinality.UNARY_UNARY, + Test, + Test, + ), + } + + +@pytest.mark.asyncio +async def test_sets_serialized_on_wire() -> None: + async with ChannelFor([ExampleService()]) as channel: + stub = ExampleServiceStub(channel) + response = await stub.do_thing(names=['a', 'b', 'c']) + assert betterproto.serialized_on_wire(response) + assert response.names == ['a', 'b', 'c']