From 23dcbc269580ce48ed20b49ae08118e7b209ecf4 Mon Sep 17 00:00:00 2001 From: boukeversteegh Date: Sat, 4 Jul 2020 15:35:42 +0200 Subject: [PATCH 1/4] Fixes circular import problem when a non-circular dependency triangle is flattened into two python packages --- betterproto/compile/importing.py | 12 ++-- betterproto/plugin.py | 2 +- betterproto/templates/template.py.j2 | 16 +++--- betterproto/tests/inputs/config.py | 1 - betterproto/tests/test_get_ref_type.py | 76 +++++++++++++++----------- 5 files changed, 59 insertions(+), 48 deletions(-) diff --git a/betterproto/compile/importing.py b/betterproto/compile/importing.py index 40441f8..57ef376 100644 --- a/betterproto/compile/importing.py +++ b/betterproto/compile/importing.py @@ -86,7 +86,7 @@ def reference_absolute(imports, py_package, py_type): string_import = ".".join(py_package) string_alias = safe_snake_case(string_import) imports.add(f"import {string_import} as {string_alias}") - return f"{string_alias}.{py_type}" + return f'"{string_alias}.{py_type}"' def reference_sibling(py_type: str) -> str: @@ -109,10 +109,10 @@ def reference_descendent( if string_from: string_alias = "_".join(importing_descendent) imports.add(f"from .{string_from} import {string_import} as {string_alias}") - return f"{string_alias}.{py_type}" + return f'"{string_alias}.{py_type}"' else: imports.add(f"from . import {string_import}") - return f"{string_import}.{py_type}" + return f'"{string_import}.{py_type}"' def reference_ancestor( @@ -130,11 +130,11 @@ def reference_ancestor( string_alias = f"_{'_' * distance_up}{string_import}__" string_from = f"..{'.' * distance_up}" imports.add(f"from {string_from} import {string_import} as {string_alias}") - return f"{string_alias}.{py_type}" + return f'"{string_alias}.{py_type}"' else: string_alias = f"{'_' * distance_up}{py_type}__" imports.add(f"from .{'.' * distance_up} import {py_type} as {string_alias}") - return string_alias + return f'"{string_alias}"' def reference_cousin( @@ -157,4 +157,4 @@ def reference_cousin( + "__" ) imports.add(f"from {string_from} import {string_import} as {string_alias}") - return f"{string_alias}.{py_type}" + return f'"{string_alias}.{py_type}"' diff --git a/betterproto/plugin.py b/betterproto/plugin.py index e835fab..9f4df64 100755 --- a/betterproto/plugin.py +++ b/betterproto/plugin.py @@ -329,7 +329,7 @@ def generate_code(request, response): output["imports"], method.output_type, unwrap=False, - ).strip('"'), + ), "client_streaming": method.client_streaming, "server_streaming": method.server_streaming, } diff --git a/betterproto/templates/template.py.j2 b/betterproto/templates/template.py.j2 index 3894619..b2d9112 100644 --- a/betterproto/templates/template.py.j2 +++ b/betterproto/templates/template.py.j2 @@ -16,10 +16,6 @@ import betterproto import grpclib {% endif %} -{% for i in description.imports %} -{{ i }} -{% endfor %} - {% if description.enums %}{% for enum in description.enums %} class {{ enum.py_name }}(betterproto.Enum): @@ -102,14 +98,14 @@ class {{ service.py_name }}Stub(betterproto.ServiceStub): "{{ method.route }}", request_iterator, {{ method.input }}, - {{ method.output }}, + {{ method.output.strip('"') }}, ): yield response {% else %}{# i.e. not client streaming #} async for response in self._unary_stream( "{{ method.route }}", request, - {{ method.output }}, + {{ method.output.strip('"') }}, ): yield response @@ -120,16 +116,20 @@ class {{ service.py_name }}Stub(betterproto.ServiceStub): "{{ method.route }}", request_iterator, {{ method.input }}, - {{ method.output }} + {{ method.output.strip('"') }} ) {% else %}{# i.e. not client streaming #} return await self._unary_unary( "{{ method.route }}", request, - {{ method.output }} + {{ method.output.strip('"') }} ) {% endif %}{# client streaming #} {% endif %} {% endfor %} {% endfor %} + +{% for i in description.imports %} +{{ i }} +{% endfor %} \ No newline at end of file diff --git a/betterproto/tests/inputs/config.py b/betterproto/tests/inputs/config.py index eab5ea4..38e9603 100644 --- a/betterproto/tests/inputs/config.py +++ b/betterproto/tests/inputs/config.py @@ -1,7 +1,6 @@ # Test cases that are expected to fail, e.g. unimplemented features or bug-fixes. # Remove from list when fixed. xfail = { - "import_circular_dependency", "oneof_enum", # 63 "namespace_keywords", # 70 "namespace_builtin_types", # 53 diff --git a/betterproto/tests/test_get_ref_type.py b/betterproto/tests/test_get_ref_type.py index 2bedf76..5a1722b 100644 --- a/betterproto/tests/test_get_ref_type.py +++ b/betterproto/tests/test_get_ref_type.py @@ -8,22 +8,22 @@ from ..compile.importing import get_type_reference, parse_source_type_name [ ( ".google.protobuf.Empty", - "betterproto_lib_google_protobuf.Empty", + '"betterproto_lib_google_protobuf.Empty"', "import betterproto.lib.google.protobuf as betterproto_lib_google_protobuf", ), ( ".google.protobuf.Struct", - "betterproto_lib_google_protobuf.Struct", + '"betterproto_lib_google_protobuf.Struct"', "import betterproto.lib.google.protobuf as betterproto_lib_google_protobuf", ), ( ".google.protobuf.ListValue", - "betterproto_lib_google_protobuf.ListValue", + '"betterproto_lib_google_protobuf.ListValue"', "import betterproto.lib.google.protobuf as betterproto_lib_google_protobuf", ), ( ".google.protobuf.Value", - "betterproto_lib_google_protobuf.Value", + '"betterproto_lib_google_protobuf.Value"', "import betterproto.lib.google.protobuf as betterproto_lib_google_protobuf", ), ], @@ -67,15 +67,27 @@ def test_referenceing_google_wrappers_unwraps_them( @pytest.mark.parametrize( ["google_type", "expected_name"], [ - (".google.protobuf.DoubleValue", "betterproto_lib_google_protobuf.DoubleValue"), - (".google.protobuf.FloatValue", "betterproto_lib_google_protobuf.FloatValue"), - (".google.protobuf.Int32Value", "betterproto_lib_google_protobuf.Int32Value"), - (".google.protobuf.Int64Value", "betterproto_lib_google_protobuf.Int64Value"), - (".google.protobuf.UInt32Value", "betterproto_lib_google_protobuf.UInt32Value"), - (".google.protobuf.UInt64Value", "betterproto_lib_google_protobuf.UInt64Value"), - (".google.protobuf.BoolValue", "betterproto_lib_google_protobuf.BoolValue"), - (".google.protobuf.StringValue", "betterproto_lib_google_protobuf.StringValue"), - (".google.protobuf.BytesValue", "betterproto_lib_google_protobuf.BytesValue"), + ( + ".google.protobuf.DoubleValue", + '"betterproto_lib_google_protobuf.DoubleValue"', + ), + (".google.protobuf.FloatValue", '"betterproto_lib_google_protobuf.FloatValue"'), + (".google.protobuf.Int32Value", '"betterproto_lib_google_protobuf.Int32Value"'), + (".google.protobuf.Int64Value", '"betterproto_lib_google_protobuf.Int64Value"'), + ( + ".google.protobuf.UInt32Value", + '"betterproto_lib_google_protobuf.UInt32Value"', + ), + ( + ".google.protobuf.UInt64Value", + '"betterproto_lib_google_protobuf.UInt64Value"', + ), + (".google.protobuf.BoolValue", '"betterproto_lib_google_protobuf.BoolValue"'), + ( + ".google.protobuf.StringValue", + '"betterproto_lib_google_protobuf.StringValue"', + ), + (".google.protobuf.BytesValue", '"betterproto_lib_google_protobuf.BytesValue"'), ], ) def test_referenceing_google_wrappers_without_unwrapping( @@ -95,7 +107,7 @@ def test_reference_child_package_from_package(): ) assert imports == {"from . import child"} - assert name == "child.Message" + assert name == '"child.Message"' def test_reference_child_package_from_root(): @@ -103,7 +115,7 @@ def test_reference_child_package_from_root(): name = get_type_reference(package="", imports=imports, source_type="child.Message") assert imports == {"from . import child"} - assert name == "child.Message" + assert name == '"child.Message"' def test_reference_camel_cased(): @@ -113,7 +125,7 @@ def test_reference_camel_cased(): ) assert imports == {"from . import child_package"} - assert name == "child_package.ExampleMessage" + assert name == '"child_package.ExampleMessage"' def test_reference_nested_child_from_root(): @@ -123,7 +135,7 @@ def test_reference_nested_child_from_root(): ) assert imports == {"from .nested import child as nested_child"} - assert name == "nested_child.Message" + assert name == '"nested_child.Message"' def test_reference_deeply_nested_child_from_root(): @@ -133,7 +145,7 @@ def test_reference_deeply_nested_child_from_root(): ) assert imports == {"from .deeply.nested import child as deeply_nested_child"} - assert name == "deeply_nested_child.Message" + assert name == '"deeply_nested_child.Message"' def test_reference_deeply_nested_child_from_package(): @@ -145,7 +157,7 @@ def test_reference_deeply_nested_child_from_package(): ) assert imports == {"from .deeply.nested import child as deeply_nested_child"} - assert name == "deeply_nested_child.Message" + assert name == '"deeply_nested_child.Message"' def test_reference_root_sibling(): @@ -181,7 +193,7 @@ def test_reference_parent_package_from_child(): ) assert imports == {"from ... import package as __package__"} - assert name == "__package__.Message" + assert name == '"__package__.Message"' def test_reference_parent_package_from_deeply_nested_child(): @@ -193,7 +205,7 @@ def test_reference_parent_package_from_deeply_nested_child(): ) assert imports == {"from ... import nested as __nested__"} - assert name == "__nested__.Message" + assert name == '"__nested__.Message"' def test_reference_ancestor_package_from_nested_child(): @@ -205,7 +217,7 @@ def test_reference_ancestor_package_from_nested_child(): ) assert imports == {"from .... import ancestor as ___ancestor__"} - assert name == "___ancestor__.Message" + assert name == '"___ancestor__.Message"' def test_reference_root_package_from_child(): @@ -215,7 +227,7 @@ def test_reference_root_package_from_child(): ) assert imports == {"from ... import Message as __Message__"} - assert name == "__Message__" + assert name == '"__Message__"' def test_reference_root_package_from_deeply_nested_child(): @@ -225,7 +237,7 @@ def test_reference_root_package_from_deeply_nested_child(): ) assert imports == {"from ..... import Message as ____Message__"} - assert name == "____Message__" + assert name == '"____Message__"' def test_reference_unrelated_package(): @@ -233,7 +245,7 @@ def test_reference_unrelated_package(): name = get_type_reference(package="a", imports=imports, source_type="p.Message") assert imports == {"from .. import p as _p__"} - assert name == "_p__.Message" + assert name == '"_p__.Message"' def test_reference_unrelated_nested_package(): @@ -241,7 +253,7 @@ def test_reference_unrelated_nested_package(): name = get_type_reference(package="a.b", imports=imports, source_type="p.q.Message") assert imports == {"from ...p import q as __p_q__"} - assert name == "__p_q__.Message" + assert name == '"__p_q__.Message"' def test_reference_unrelated_deeply_nested_package(): @@ -251,7 +263,7 @@ def test_reference_unrelated_deeply_nested_package(): ) assert imports == {"from .....p.q.r import s as ____p_q_r_s__"} - assert name == "____p_q_r_s__.Message" + assert name == '"____p_q_r_s__.Message"' def test_reference_cousin_package(): @@ -259,7 +271,7 @@ def test_reference_cousin_package(): name = get_type_reference(package="a.x", imports=imports, source_type="a.y.Message") assert imports == {"from .. import y as _y__"} - assert name == "_y__.Message" + assert name == '"_y__.Message"' def test_reference_cousin_package_different_name(): @@ -269,7 +281,7 @@ def test_reference_cousin_package_different_name(): ) assert imports == {"from ...cousin import package2 as __cousin_package2__"} - assert name == "__cousin_package2__.Message" + assert name == '"__cousin_package2__.Message"' def test_reference_cousin_package_same_name(): @@ -279,7 +291,7 @@ def test_reference_cousin_package_same_name(): ) assert imports == {"from ...cousin import package as __cousin_package__"} - assert name == "__cousin_package__.Message" + assert name == '"__cousin_package__.Message"' def test_reference_far_cousin_package(): @@ -289,7 +301,7 @@ def test_reference_far_cousin_package(): ) assert imports == {"from ...b import c as __b_c__"} - assert name == "__b_c__.Message" + assert name == '"__b_c__.Message"' def test_reference_far_far_cousin_package(): @@ -299,7 +311,7 @@ def test_reference_far_far_cousin_package(): ) assert imports == {"from ....b.c import d as ___b_c_d__"} - assert name == "___b_c_d__.Message" + assert name == '"___b_c_d__.Message"' @pytest.mark.parametrize( From a8d8159d27081a7e25ed78e6a5e36a1496ed5336 Mon Sep 17 00:00:00 2001 From: Arun Babu Neelicattu Date: Tue, 7 Jul 2020 13:15:46 +0200 Subject: [PATCH 2/4] Add missing async/await keywords when casing --- betterproto/casing.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/betterproto/casing.py b/betterproto/casing.py index 543df68..c8dc2e2 100644 --- a/betterproto/casing.py +++ b/betterproto/casing.py @@ -20,6 +20,8 @@ def safe_snake_case(value: str) -> str: "and", "as", "assert", + "async", + "await", "break", "class", "continue", From 0f3ad25770565b657acc7b75902aa53e276fd480 Mon Sep 17 00:00:00 2001 From: Arun Babu Neelicattu Date: Tue, 7 Jul 2020 19:06:43 +0200 Subject: [PATCH 3/4] Minor non-functional changes - fix few typos - remove unused imports - fix minor code-quality issues - replace `grpclib._protocols` with `grpclib._typing` - fix boolean and None assertions in test cases --- betterproto/__init__.py | 11 ++-- betterproto/_types.py | 2 +- betterproto/grpc/grpclib_client.py | 5 +- betterproto/grpc/util/async_channel.py | 52 +++++++++---------- betterproto/plugin.py | 4 +- betterproto/tests/generate.py | 1 - betterproto/tests/grpc/test_grpclib_client.py | 21 ++++---- betterproto/tests/grpc/thing_service.py | 4 +- .../test_googletypes_response.py | 2 +- betterproto/tests/test_features.py | 16 +++--- 10 files changed, 57 insertions(+), 61 deletions(-) diff --git a/betterproto/__init__.py b/betterproto/__init__.py index 6c07feb..6fb2004 100644 --- a/betterproto/__init__.py +++ b/betterproto/__init__.py @@ -22,7 +22,7 @@ from typing import ( ) from ._types import T -from .casing import camel_case, safe_snake_case, safe_snake_case, snake_case +from .casing import camel_case, safe_snake_case, snake_case from .grpc.grpclib_client import ServiceStub if not (sys.version_info.major == 3 and sys.version_info.minor >= 7): @@ -378,7 +378,7 @@ def decode_varint(buffer: bytes, pos: int, signed: bool = False) -> Tuple[int, i result |= (b & 0x7F) << shift pos += 1 if not (b & 0x80): - return (result, pos) + return result, pos shift += 7 if shift >= 64: raise ValueError("Too many bytes when decoding varint.") @@ -479,7 +479,7 @@ class ProtoClassMetadata: assert meta.map_types kt = cls._cls_for(field, index=0) vt = cls._cls_for(field, index=1) - Entry = dataclasses.make_dataclass( + field_cls[field.name] = dataclasses.make_dataclass( "Entry", [ ("key", kt, dataclass_field(1, meta.map_types[0])), @@ -487,7 +487,6 @@ class ProtoClassMetadata: ], bases=(Message,), ) - field_cls[field.name] = Entry field_cls[field.name + ".value"] = vt else: field_cls[field.name] = cls._cls_for(field) @@ -588,7 +587,7 @@ class Message(ABC): serialize_empty = False if isinstance(value, Message) and value._serialized_on_wire: # Empty messages can still be sent on the wire if they were - # set (or recieved empty). + # set (or received empty). serialize_empty = True if value == self._get_field_default(field_name) and not ( @@ -926,7 +925,7 @@ def which_one_of(message: Message, group_name: str) -> Tuple[str, Any]: # Circular import workaround: google.protobuf depends on base classes defined above. -from .lib.google.protobuf import ( +from .lib.google.protobuf import ( # noqa Duration, Timestamp, BoolValue, diff --git a/betterproto/_types.py b/betterproto/_types.py index d03432c..bc3748f 100644 --- a/betterproto/_types.py +++ b/betterproto/_types.py @@ -2,7 +2,7 @@ from typing import TYPE_CHECKING, TypeVar if TYPE_CHECKING: from . import Message - from grpclib._protocols import IProtoMessage + from grpclib._typing import IProtoMessage # Bound type variable to allow methods to return `self` of subclasses T = TypeVar("T", bound="Message") diff --git a/betterproto/grpc/grpclib_client.py b/betterproto/grpc/grpclib_client.py index 7f48fb9..1068cce 100644 --- a/betterproto/grpc/grpclib_client.py +++ b/betterproto/grpc/grpclib_client.py @@ -2,7 +2,6 @@ from abc import ABC import asyncio import grpclib.const from typing import ( - Any, AsyncIterable, AsyncIterator, Collection, @@ -17,8 +16,8 @@ from typing import ( from .._types import ST, T if TYPE_CHECKING: - from grpclib._protocols import IProtoMessage - from grpclib.client import Channel, Stream + from grpclib._typing import IProtoMessage + from grpclib.client import Channel from grpclib.metadata import Deadline diff --git a/betterproto/grpc/util/async_channel.py b/betterproto/grpc/util/async_channel.py index de020a6..0cd9f03 100644 --- a/betterproto/grpc/util/async_channel.py +++ b/betterproto/grpc/util/async_channel.py @@ -21,7 +21,7 @@ class ChannelClosed(Exception): class ChannelDone(Exception): """ - An exception raised on an attempt to send recieve from a channel that is both closed + An exception raised on an attempt to send receive from a channel that is both closed and empty. """ @@ -32,41 +32,41 @@ class AsyncChannel(AsyncIterable[T]): """ A buffered async channel for sending items between coroutines with FIFO ordering. - This makes decoupled bidirection steaming gRPC requests easy if used like: + This makes decoupled bidirectional steaming gRPC requests easy if used like: .. code-block:: python client = GeneratedStub(grpclib_chan) - request_chan = await AsyncChannel() + request_channel = await AsyncChannel() # We can start be sending all the requests we already have - await request_chan.send_from([ReqestObject(...), ReqestObject(...)]) - async for response in client.rpc_call(request_chan): + await request_channel.send_from([RequestObject(...), RequestObject(...)]) + async for response in client.rpc_call(request_channel): # The response iterator will remain active until the connection is closed ... # More items can be sent at any time - await request_chan.send(ReqestObject(...)) + await request_channel.send(RequestObject(...)) ... # The channel must be closed to complete the gRPC connection - request_chan.close() + request_channel.close() Items can be sent through the channel by either: - providing an iterable to the send_from method - passing them to the send method one at a time - Items can be recieved from the channel by either: + Items can be received from the channel by either: - iterating over the channel with a for loop to get all items - - calling the recieve method to get one item at a time + - calling the receive method to get one item at a time - If the channel is empty then recievers will wait until either an item appears or the + If the channel is empty then receivers will wait until either an item appears or the channel is closed. Once the channel is closed then subsequent attempt to send through the channel will fail with a ChannelClosed exception. - When th channel is closed and empty then it is done, and further attempts to recieve + When th channel is closed and empty then it is done, and further attempts to receive from it will fail with a ChannelDone exception - If multiple coroutines recieve from the channel concurrently, each item sent will be - recieved by only one of the recievers. + If multiple coroutines receive from the channel concurrently, each item sent will be + received by only one of the receivers. :param source: An optional iterable will items that should be sent through the channel @@ -74,7 +74,7 @@ class AsyncChannel(AsyncIterable[T]): :param buffer_limit: Limit the number of items that can be buffered in the channel, A value less than 1 implies no limit. If the channel is full then attempts to send more items will - result in the sender waiting until an item is recieved from the channel. + result in the sender waiting until an item is received from the channel. :param close: If set to True then the channel will automatically close after exhausting source or immediately if no source is provided. @@ -85,7 +85,7 @@ class AsyncChannel(AsyncIterable[T]): ): self._queue: asyncio.Queue[Union[T, object]] = asyncio.Queue(buffer_limit) self._closed = False - self._waiting_recievers: int = 0 + self._waiting_receivers: int = 0 # Track whether flush has been invoked so it can only happen once self._flushed = False @@ -95,14 +95,14 @@ class AsyncChannel(AsyncIterable[T]): async def __anext__(self) -> T: if self.done(): raise StopAsyncIteration - self._waiting_recievers += 1 + self._waiting_receivers += 1 try: result = await self._queue.get() if result is self.__flush: raise StopAsyncIteration return result finally: - self._waiting_recievers -= 1 + self._waiting_receivers -= 1 self._queue.task_done() def closed(self) -> bool: @@ -116,12 +116,12 @@ class AsyncChannel(AsyncIterable[T]): Check if this channel is done. :return: True if this channel is closed and and has been drained of items in - which case any further attempts to recieve an item from this channel will raise + which case any further attempts to receive an item from this channel will raise a ChannelDone exception. """ # After close the channel is not yet done until there is at least one waiting - # reciever per enqueued item. - return self._closed and self._queue.qsize() <= self._waiting_recievers + # receiver per enqueued item. + return self._closed and self._queue.qsize() <= self._waiting_receivers async def send_from( self, source: Union[Iterable[T], AsyncIterable[T]], close: bool = False @@ -158,22 +158,22 @@ class AsyncChannel(AsyncIterable[T]): await self._queue.put(item) return self - async def recieve(self) -> Optional[T]: + async def receive(self) -> Optional[T]: """ Returns the next item from this channel when it becomes available, or None if the channel is closed before another item is sent. :return: An item from the channel """ if self.done(): - raise ChannelDone("Cannot recieve from a closed channel") - self._waiting_recievers += 1 + raise ChannelDone("Cannot receive from a closed channel") + self._waiting_receivers += 1 try: result = await self._queue.get() if result is self.__flush: return None return result finally: - self._waiting_recievers -= 1 + self._waiting_receivers -= 1 self._queue.task_done() def close(self): @@ -190,8 +190,8 @@ class AsyncChannel(AsyncIterable[T]): """ if not self._flushed: self._flushed = True - deadlocked_recievers = max(0, self._waiting_recievers - self._queue.qsize()) - for _ in range(deadlocked_recievers): + deadlocked_receivers = max(0, self._waiting_receivers - self._queue.qsize()) + for _ in range(deadlocked_receivers): await self._queue.put(self.__flush) # A special signal object for flushing the queue when the channel is closed diff --git a/betterproto/plugin.py b/betterproto/plugin.py index e835fab..ad48b43 100755 --- a/betterproto/plugin.py +++ b/betterproto/plugin.py @@ -77,7 +77,7 @@ def get_py_zero(type_num: int) -> Union[str, float]: def traverse(proto_file): def _traverse(path, items, prefix=""): for i, item in enumerate(items): - # Adjust the name since we flatten the heirarchy. + # Adjust the name since we flatten the hierarchy. item.name = next_prefix = prefix + item.name yield item, path + [i] @@ -355,7 +355,7 @@ def generate_code(request, response): # Render and then format the output file. f.content = black.format_str( template.render(description=output), - mode=black.FileMode(target_versions=set([black.TargetVersion.PY37])), + mode=black.FileMode(target_versions={black.TargetVersion.PY37}), ) # Make each output directory a package with __init__ file diff --git a/betterproto/tests/generate.py b/betterproto/tests/generate.py index 5c555ff..539bd1c 100755 --- a/betterproto/tests/generate.py +++ b/betterproto/tests/generate.py @@ -3,7 +3,6 @@ import asyncio import os from pathlib import Path import shutil -import subprocess import sys from typing import Set diff --git a/betterproto/tests/grpc/test_grpclib_client.py b/betterproto/tests/grpc/test_grpclib_client.py index 6c34ece..67eb085 100644 --- a/betterproto/tests/grpc/test_grpclib_client.py +++ b/betterproto/tests/grpc/test_grpclib_client.py @@ -3,7 +3,6 @@ from betterproto.tests.output_betterproto.service.service import ( DoThingResponse, DoThingRequest, GetThingRequest, - GetThingResponse, TestStub as ThingServiceClient, ) import grpclib @@ -18,14 +17,14 @@ async def _test_client(client, name="clean room", **kwargs): assert response.names == [name] -def _assert_request_meta_recieved(deadline, metadata): +def _assert_request_meta_received(deadline, metadata): def server_side_test(stream): assert stream.deadline._timestamp == pytest.approx( deadline._timestamp, 1 - ), "The provided deadline should be recieved serverside" + ), "The provided deadline should be received serverside" assert ( stream.metadata["authorization"] == metadata["authorization"] - ), "The provided authorization metadata should be recieved serverside" + ), "The provided authorization metadata should be received serverside" return server_side_test @@ -42,7 +41,7 @@ async def test_service_call_with_upfront_request_params(): deadline = grpclib.metadata.Deadline.from_timeout(22) metadata = {"authorization": "12345"} async with ChannelFor( - [ThingService(test_hook=_assert_request_meta_recieved(deadline, metadata),)] + [ThingService(test_hook=_assert_request_meta_received(deadline, metadata),)] ) as channel: await _test_client( ThingServiceClient(channel, deadline=deadline, metadata=metadata) @@ -53,7 +52,7 @@ async def test_service_call_with_upfront_request_params(): deadline = grpclib.metadata.Deadline.from_timeout(timeout) metadata = {"authorization": "12345"} async with ChannelFor( - [ThingService(test_hook=_assert_request_meta_recieved(deadline, metadata),)] + [ThingService(test_hook=_assert_request_meta_received(deadline, metadata),)] ) as channel: await _test_client( ThingServiceClient(channel, timeout=timeout, metadata=metadata) @@ -70,7 +69,7 @@ async def test_service_call_lower_level_with_overrides(): kwarg_deadline = grpclib.metadata.Deadline.from_timeout(28) kwarg_metadata = {"authorization": "12345"} async with ChannelFor( - [ThingService(test_hook=_assert_request_meta_recieved(deadline, metadata),)] + [ThingService(test_hook=_assert_request_meta_received(deadline, metadata),)] ) as channel: client = ThingServiceClient(channel, deadline=deadline, metadata=metadata) response = await client._unary_unary( @@ -92,7 +91,7 @@ async def test_service_call_lower_level_with_overrides(): async with ChannelFor( [ ThingService( - test_hook=_assert_request_meta_recieved(kwarg_deadline, kwarg_metadata), + test_hook=_assert_request_meta_received(kwarg_deadline, kwarg_metadata), ) ] ) as channel: @@ -140,8 +139,8 @@ async def test_async_gen_for_stream_stream_request(): assert response.version == response_index + 1 response_index += 1 if more_things: - # Send some more requests as we recieve reponses to be sure coordination of - # send/recieve events doesn't matter + # Send some more requests as we receive responses to be sure coordination of + # send/receive events doesn't matter await request_chan.send(GetThingRequest(more_things.pop(0))) elif not send_initial_requests.done(): # Make sure the sending task it completed @@ -151,4 +150,4 @@ async def test_async_gen_for_stream_stream_request(): request_chan.close() assert response_index == len( expected_things - ), "Didn't recieve all exptected responses" + ), "Didn't receive all expected responses" diff --git a/betterproto/tests/grpc/thing_service.py b/betterproto/tests/grpc/thing_service.py index bc9fff8..cc863f2 100644 --- a/betterproto/tests/grpc/thing_service.py +++ b/betterproto/tests/grpc/thing_service.py @@ -3,10 +3,10 @@ from betterproto.tests.output_betterproto.service.service import ( DoThingRequest, GetThingRequest, GetThingResponse, - TestStub as ThingServiceClient, ) import grpclib -from typing import Any, Dict +import grpclib.server +from typing import Dict class ThingService: diff --git a/betterproto/tests/inputs/googletypes_response/test_googletypes_response.py b/betterproto/tests/inputs/googletypes_response/test_googletypes_response.py index 2e37f88..a7e4938 100644 --- a/betterproto/tests/inputs/googletypes_response/test_googletypes_response.py +++ b/betterproto/tests/inputs/googletypes_response/test_googletypes_response.py @@ -21,7 +21,7 @@ test_cases = [ @pytest.mark.asyncio @pytest.mark.parametrize(["service_method", "wrapper_class", "value"], test_cases) -async def test_channel_recieves_wrapped_type( +async def test_channel_receives_wrapped_type( service_method: Callable[[TestStub], Any], wrapper_class: Callable, value ): wrapped_value = wrapper_class() diff --git a/betterproto/tests/test_features.py b/betterproto/tests/test_features.py index 47019e1..3a4a7c7 100644 --- a/betterproto/tests/test_features.py +++ b/betterproto/tests/test_features.py @@ -14,23 +14,23 @@ def test_has_field(): # Unset by default foo = Foo() - assert betterproto.serialized_on_wire(foo.bar) == False + assert betterproto.serialized_on_wire(foo.bar) is False # Serialized after setting something foo.bar.baz = 1 - assert betterproto.serialized_on_wire(foo.bar) == True + assert betterproto.serialized_on_wire(foo.bar) is True # Still has it after setting the default value foo.bar.baz = 0 - assert betterproto.serialized_on_wire(foo.bar) == True + assert betterproto.serialized_on_wire(foo.bar) is True # Manual override (don't do this) foo.bar._serialized_on_wire = False - assert betterproto.serialized_on_wire(foo.bar) == False + assert betterproto.serialized_on_wire(foo.bar) is False # Can manually set it but defaults to false foo.bar = Bar() - assert betterproto.serialized_on_wire(foo.bar) == False + assert betterproto.serialized_on_wire(foo.bar) is False def test_class_init(): @@ -118,7 +118,7 @@ def test_oneof_support(): # Group 1 shouldn't be touched, group 2 should have reset assert foo.sub.val == 0 - assert betterproto.serialized_on_wire(foo.sub) == False + assert betterproto.serialized_on_wire(foo.sub) is False assert betterproto.which_one_of(foo, "group2")[0] == "abc" # Zero value should always serialize for one-of @@ -175,8 +175,8 @@ def test_optional_flag(): assert bytes(Request(flag=False)) == b"\n\x00" # Differentiate between not passed and the zero-value. - assert Request().parse(b"").flag == None - assert Request().parse(b"\n\x00").flag == False + assert Request().parse(b"").flag is None + assert Request().parse(b"\n\x00").flag is False def test_to_dict_default_values(): From 0338fcba291683d1d0fb5e548b5d899b1f56edba Mon Sep 17 00:00:00 2001 From: Arun Babu Neelicattu Date: Tue, 7 Jul 2020 18:26:52 +0200 Subject: [PATCH 4/4] Ignore commonly used .venv directory --- .gitignore | 1 + 1 file changed, 1 insertion(+) diff --git a/.gitignore b/.gitignore index 93227fc..bb48db1 100644 --- a/.gitignore +++ b/.gitignore @@ -14,3 +14,4 @@ output .idea .DS_Store .tox +.venv