From d968aedce661d3bda8d6238bd89408334da02d7e Mon Sep 17 00:00:00 2001 From: James Hilton-Balfe Date: Mon, 11 Apr 2022 21:46:38 +0100 Subject: [PATCH 01/27] Remove abc.ABC as base class for Message --- src/betterproto/__init__.py | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/betterproto/__init__.py b/src/betterproto/__init__.py index e6af1bcb8..e1bd598ce 100644 --- a/src/betterproto/__init__.py +++ b/src/betterproto/__init__.py @@ -6,7 +6,6 @@ import sys import typing import warnings -from abc import ABC from base64 import ( b64decode, b64encode, @@ -605,7 +604,7 @@ def _get_cls_by_field( return field_cls -class Message(ABC): +class Message: """ The base class for protobuf messages, all generated messages will inherit from this. This class registers the message fields which are used by the serializers and From 06c19263583c429e8e56d76b1d121466af236dcd Mon Sep 17 00:00:00 2001 From: James Hilton-Balfe Date: Mon, 11 Apr 2022 21:48:44 +0100 Subject: [PATCH 02/27] Use frozensets for contains checks --- src/betterproto/__init__.py | 110 +++++++++++++++++++----------------- 1 file changed, 59 insertions(+), 51 deletions(-) diff --git a/src/betterproto/__init__.py b/src/betterproto/__init__.py index e1bd598ce..378e5db76 100644 --- a/src/betterproto/__init__.py +++ b/src/betterproto/__init__.py @@ -65,35 +65,41 @@ # Fields that use a fixed amount of space (4 or 8 bytes) -FIXED_TYPES = [ - TYPE_FLOAT, - TYPE_DOUBLE, - TYPE_FIXED32, - TYPE_SFIXED32, - TYPE_FIXED64, - TYPE_SFIXED64, -] +FIXED_TYPES = frozenset( + { + TYPE_FLOAT, + TYPE_DOUBLE, + TYPE_FIXED32, + TYPE_SFIXED32, + TYPE_FIXED64, + TYPE_SFIXED64, + } +) # Fields that are numerical 64-bit types -INT_64_TYPES = [TYPE_INT64, TYPE_UINT64, TYPE_SINT64, TYPE_FIXED64, TYPE_SFIXED64] - -# Fields that are efficiently packed when -PACKED_TYPES = [ - TYPE_ENUM, - TYPE_BOOL, - TYPE_INT32, - TYPE_INT64, - TYPE_UINT32, - TYPE_UINT64, - TYPE_SINT32, - TYPE_SINT64, - TYPE_FLOAT, - TYPE_DOUBLE, - TYPE_FIXED32, - TYPE_SFIXED32, - TYPE_FIXED64, - TYPE_SFIXED64, -] +INT_64_TYPES = frozenset( + {TYPE_INT64, TYPE_UINT64, TYPE_SINT64, TYPE_FIXED64, TYPE_SFIXED64} +) + +# Fields that are efficiently packed when serialised +PACKED_TYPES = frozenset( + { + TYPE_ENUM, + TYPE_BOOL, + TYPE_INT32, + TYPE_INT64, + TYPE_UINT32, + TYPE_UINT64, + TYPE_SINT32, + TYPE_SINT64, + TYPE_FLOAT, + TYPE_DOUBLE, + TYPE_FIXED32, + TYPE_SFIXED32, + TYPE_FIXED64, + TYPE_SFIXED64, + } +) # Wire types # https://developers.google.com/protocol-buffers/docs/encoding#structure @@ -103,20 +109,22 @@ WIRE_FIXED_32 = 5 # Mappings of which Proto 3 types correspond to which wire types. -WIRE_VARINT_TYPES = [ - TYPE_ENUM, - TYPE_BOOL, - TYPE_INT32, - TYPE_INT64, - TYPE_UINT32, - TYPE_UINT64, - TYPE_SINT32, - TYPE_SINT64, -] - -WIRE_FIXED_32_TYPES = [TYPE_FLOAT, TYPE_FIXED32, TYPE_SFIXED32] -WIRE_FIXED_64_TYPES = [TYPE_DOUBLE, TYPE_FIXED64, TYPE_SFIXED64] -WIRE_LEN_DELIM_TYPES = [TYPE_STRING, TYPE_BYTES, TYPE_MESSAGE, TYPE_MAP] +WIRE_VARINT_TYPES = frozenset( + { + TYPE_ENUM, + TYPE_BOOL, + TYPE_INT32, + TYPE_INT64, + TYPE_UINT32, + TYPE_UINT64, + TYPE_SINT32, + TYPE_SINT64, + } +) + +WIRE_FIXED_32_TYPES = frozenset({TYPE_FLOAT, TYPE_FIXED32, TYPE_SFIXED32}) +WIRE_FIXED_64_TYPES = frozenset({TYPE_DOUBLE, TYPE_FIXED64, TYPE_SFIXED64}) +WIRE_LEN_DELIM_TYPES = frozenset({TYPE_STRING, TYPE_BYTES, TYPE_MESSAGE, TYPE_MAP}) # Protobuf datetimes start at the Unix Epoch in 1970 in UTC. @@ -358,16 +366,16 @@ def encode_varint(value: int) -> bytes: def _preprocess_single(proto_type: str, wraps: str, value: Any) -> bytes: """Adjusts values before serialization.""" - if proto_type in ( + if proto_type in { TYPE_ENUM, TYPE_BOOL, TYPE_INT32, TYPE_INT64, TYPE_UINT32, TYPE_UINT64, - ): + }: return encode_varint(value) - elif proto_type in (TYPE_SINT32, TYPE_SINT64): + elif proto_type in {TYPE_SINT32, TYPE_SINT64}: # Handle zig-zag encoding. return encode_varint(value << 1 if value >= 0 else (value << 1) ^ (~0)) elif proto_type in FIXED_TYPES: @@ -917,18 +925,18 @@ def _postprocess_single( ) -> Any: """Adjusts values after parsing.""" if wire_type == WIRE_VARINT: - if meta.proto_type in (TYPE_INT32, TYPE_INT64): + if meta.proto_type in {TYPE_INT32, TYPE_INT64}: bits = int(meta.proto_type[3:]) value = value & ((1 << bits) - 1) signbit = 1 << (bits - 1) value = int((value ^ signbit) - signbit) - elif meta.proto_type in (TYPE_SINT32, TYPE_SINT64): + elif meta.proto_type in {TYPE_SINT32, TYPE_SINT64}: # Undo zig-zag encoding value = (value >> 1) ^ (-(value & 1)) elif meta.proto_type == TYPE_BOOL: # Booleans use a varint encoding, so convert it to true/false. value = value > 0 - elif wire_type in (WIRE_FIXED_32, WIRE_FIXED_64): + elif wire_type in {WIRE_FIXED_32, WIRE_FIXED_64}: fmt = _pack_fmt(meta.proto_type) value = struct.unpack(fmt, value)[0] elif wire_type == WIRE_LEN_DELIM: @@ -992,10 +1000,10 @@ def parse(self: T, data: bytes) -> T: pos = 0 value = [] while pos < len(parsed.value): - if meta.proto_type in (TYPE_FLOAT, TYPE_FIXED32, TYPE_SFIXED32): + if meta.proto_type in {TYPE_FLOAT, TYPE_FIXED32, TYPE_SFIXED32}: decoded, pos = parsed.value[pos : pos + 4], pos + 4 wire_type = WIRE_FIXED_32 - elif meta.proto_type in (TYPE_DOUBLE, TYPE_FIXED64, TYPE_SFIXED64): + elif meta.proto_type in {TYPE_DOUBLE, TYPE_FIXED64, TYPE_SFIXED64}: decoded, pos = parsed.value[pos : pos + 8], pos + 8 wire_type = WIRE_FIXED_64 else: @@ -1169,7 +1177,7 @@ def to_dict( else: enum_class = field_types[field_name] # noqa output[cased_name] = enum_class(value).name - elif meta.proto_type in (TYPE_FLOAT, TYPE_DOUBLE): + elif meta.proto_type in {TYPE_FLOAT, TYPE_DOUBLE}: if field_is_repeated: output[cased_name] = [_dump_float(n) for n in value] else: @@ -1373,7 +1381,7 @@ def to_timedelta(self) -> timedelta: def delta_to_json(delta: timedelta) -> str: parts = str(delta.total_seconds()).split(".") if len(parts) > 1: - while len(parts[1]) not in (3, 6, 9): + while len(parts[1]) not in {3, 6, 9}: parts[1] = f"{parts[1]}0" return f"{'.'.join(parts)}s" From 6e8d5da2f6258c20eb94f7cf465ec31e402ba03e Mon Sep 17 00:00:00 2001 From: James Hilton-Balfe Date: Mon, 11 Apr 2022 21:51:39 +0100 Subject: [PATCH 03/27] Inline functions where possible --- src/betterproto/__init__.py | 29 +++++++++++++---------------- 1 file changed, 13 insertions(+), 16 deletions(-) diff --git a/src/betterproto/__init__.py b/src/betterproto/__init__.py index 378e5db76..61ccd339b 100644 --- a/src/betterproto/__init__.py +++ b/src/betterproto/__init__.py @@ -336,16 +336,15 @@ def from_string(cls, name: str) -> "Enum": raise ValueError(f"Unknown value {name} for enum {cls.__name__}") from e -def _pack_fmt(proto_type: str) -> str: - """Returns a little-endian format string for reading/writing binary.""" - return { - TYPE_DOUBLE: " bytes: @@ -379,7 +378,7 @@ def _preprocess_single(proto_type: str, wraps: str, value: Any) -> bytes: # Handle zig-zag encoding. return encode_varint(value << 1 if value >= 0 else (value << 1) ^ (~0)) elif proto_type in FIXED_TYPES: - return struct.pack(_pack_fmt(proto_type), value) + return _pack_fmt(proto_type).pack(value) elif proto_type == TYPE_STRING: return value.encode("utf-8") elif proto_type == TYPE_MESSAGE: @@ -658,8 +657,7 @@ def __post_init__(self) -> None: self.__dict__["_unknown_fields"] = b"" self.__dict__["_group_current"] = group_current - def __raw_get(self, name: str) -> Any: - return super().__getattribute__(name) + __raw_get = object.__getattribute__ def __eq__(self, other) -> bool: if type(self) is not type(other): @@ -705,7 +703,7 @@ def __getattribute__(self, name: str) -> Any: Lazily initialize default values to avoid infinite recursion for recursive message types """ - value = super().__getattribute__(name) + value = self.__raw_get(name) if value is not PLACEHOLDER: return value @@ -937,8 +935,7 @@ def _postprocess_single( # Booleans use a varint encoding, so convert it to true/false. value = value > 0 elif wire_type in {WIRE_FIXED_32, WIRE_FIXED_64}: - fmt = _pack_fmt(meta.proto_type) - value = struct.unpack(fmt, value)[0] + (value,) = _pack_fmt(meta.proto_type).unpack(value) elif wire_type == WIRE_LEN_DELIM: if meta.proto_type == TYPE_STRING: value = str(value, "utf-8") From 98a91f545cf239eef48894298c4979d4a794e6e6 Mon Sep 17 00:00:00 2001 From: James Hilton-Balfe Date: Mon, 11 Apr 2022 21:53:17 +0100 Subject: [PATCH 04/27] Don't create a bytearray for each call to _serialize_single --- src/betterproto/__init__.py | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/src/betterproto/__init__.py b/src/betterproto/__init__.py index 61ccd339b..ccf96d476 100644 --- a/src/betterproto/__init__.py +++ b/src/betterproto/__init__.py @@ -414,24 +414,25 @@ def _serialize_single( """Serializes a single field and value.""" value = _preprocess_single(proto_type, wraps, value) - output = bytearray() if proto_type in WIRE_VARINT_TYPES: key = encode_varint(field_number << 3) - output += key + value + output = key + value elif proto_type in WIRE_FIXED_32_TYPES: key = encode_varint((field_number << 3) | 5) - output += key + value + output = key + value elif proto_type in WIRE_FIXED_64_TYPES: key = encode_varint((field_number << 3) | 1) - output += key + value + output = key + value elif proto_type in WIRE_LEN_DELIM_TYPES: - if len(value) or serialize_empty or wraps: + if value or serialize_empty or wraps: key = encode_varint((field_number << 3) | 2) - output += key + encode_varint(len(value)) + value + output = key + encode_varint(len(value)) + value + else: + output = b"" else: raise NotImplementedError(proto_type) - return bytes(output) + return output def _parse_float(value: Any) -> float: From 9f92f6c6105a6f700afc6de5ebe340777af986be Mon Sep 17 00:00:00 2001 From: James Hilton-Balfe Date: Mon, 11 Apr 2022 21:54:19 +0100 Subject: [PATCH 05/27] Don't check origin against typing special forms AFAIK __origin__ was never Dict, List etc. --- src/betterproto/__init__.py | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/src/betterproto/__init__.py b/src/betterproto/__init__.py index ccf96d476..d97253f1c 100644 --- a/src/betterproto/__init__.py +++ b/src/betterproto/__init__.py @@ -894,14 +894,15 @@ def _get_field_default(self, field_name: str) -> Any: def _get_field_default_gen(cls, field: dataclasses.Field) -> Any: t = cls._type_hint(field.name) - if hasattr(t, "__origin__"): - if t.__origin__ in (dict, Dict): + origin = getattr(t, "__origin__", None) + if origin is not None: + if origin is dict: # This is some kind of map (dict in Python). - return dict - elif t.__origin__ in (list, List): + return origin + elif origin is list: # This is some kind of list (repeated) field. - return list - elif t.__origin__ is Union and t.__args__[1] is type(None): + return origin + elif origin is Union and t.__args__[1] is type(None): # This is an optional field (either wrapped, or using proto3 # field presence). For setting the default we really don't care # what kind of field it is. From 3e7416e16009d97f37bda102c00575c9da6e3e3e Mon Sep 17 00:00:00 2001 From: James Hilton-Balfe Date: Mon, 11 Apr 2022 21:54:48 +0100 Subject: [PATCH 06/27] Use is for type comparisons --- src/betterproto/__init__.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/betterproto/__init__.py b/src/betterproto/__init__.py index d97253f1c..87295198b 100644 --- a/src/betterproto/__init__.py +++ b/src/betterproto/__init__.py @@ -944,9 +944,9 @@ def _postprocess_single( elif meta.proto_type == TYPE_MESSAGE: cls = self._betterproto.cls_by_field[field_name] - if cls == datetime: + if cls is datetime: value = _Timestamp().parse(value).to_datetime() - elif cls == timedelta: + elif cls is timedelta: value = _Duration().parse(value).to_timedelta() elif meta.wraps: # This is a Google wrapper value message around a single @@ -1105,9 +1105,9 @@ def to_dict( elif field_is_repeated: # Convert each item. cls = self._betterproto.cls_by_field[field_name] - if cls == datetime: + if cls is datetime: value = [_Timestamp.timestamp_to_json(i) for i in value] - elif cls == timedelta: + elif cls is timedelta: value = [_Duration.delta_to_json(i) for i in value] else: value = [ From 2b2debf00141bab9340fe460f01fc93392394b41 Mon Sep 17 00:00:00 2001 From: James Hilton-Balfe Date: Mon, 11 Apr 2022 21:55:28 +0100 Subject: [PATCH 07/27] Optimise for the normal case for dict.__getitem__ --- src/betterproto/__init__.py | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/src/betterproto/__init__.py b/src/betterproto/__init__.py index 87295198b..149f7064c 100644 --- a/src/betterproto/__init__.py +++ b/src/betterproto/__init__.py @@ -986,8 +986,9 @@ def parse(self: T, data: bytes) -> T: self._serialized_on_wire = True proto_meta = self._betterproto for parsed in parse_fields(data): - field_name = proto_meta.field_name_by_number.get(parsed.number) - if not field_name: + try: + field_name = proto_meta.field_name_by_number[parsed.number] + except KeyError: self._unknown_fields += parsed.raw continue @@ -1203,8 +1204,9 @@ def from_dict(self: T, value: Dict[str, Any]) -> T: self._serialized_on_wire = True for key in value: field_name = safe_snake_case(key) - meta = self._betterproto.meta_by_field_name.get(field_name) - if not meta: + try: + meta = self._betterproto.meta_by_field_name[field_name] + except KeyError: continue if value[key] is not None: From fac0ed366a31be14662e1afdb3f9e2b853f76555 Mon Sep 17 00:00:00 2001 From: James Hilton-Balfe Date: Mon, 11 Apr 2022 21:56:01 +0100 Subject: [PATCH 08/27] Simplify from_dict a tad and reduce number of comparisons --- src/betterproto/__init__.py | 114 ++++++++++++++++++------------------ 1 file changed, 57 insertions(+), 57 deletions(-) diff --git a/src/betterproto/__init__.py b/src/betterproto/__init__.py index 149f7064c..8f4967c8e 100644 --- a/src/betterproto/__init__.py +++ b/src/betterproto/__init__.py @@ -1202,72 +1202,72 @@ def from_dict(self: T, value: Dict[str, Any]) -> T: The initialized message. """ self._serialized_on_wire = True - for key in value: + for key, v in value.items(): field_name = safe_snake_case(key) try: meta = self._betterproto.meta_by_field_name[field_name] except KeyError: continue - if value[key] is not None: - if meta.proto_type == TYPE_MESSAGE: - v = getattr(self, field_name) - cls = self._betterproto.cls_by_field[field_name] - if isinstance(v, list): - if cls == datetime: - v = [isoparse(item) for item in value[key]] - elif cls == timedelta: - v = [ - timedelta(seconds=float(item[:-1])) - for item in value[key] - ] - else: - v = [cls().from_dict(item) for item in value[key]] - elif cls == datetime: - v = isoparse(value[key]) - setattr(self, field_name, v) - elif cls == timedelta: - v = timedelta(seconds=float(value[key][:-1])) - setattr(self, field_name, v) - elif meta.wraps: - setattr(self, field_name, value[key]) - elif v is None: - setattr(self, field_name, cls().from_dict(value[key])) + if v is None: + continue + + if meta.proto_type == TYPE_MESSAGE: + v = getattr(self, field_name) + cls = self._betterproto.cls_by_field[field_name] + if isinstance(v, list): + if cls is datetime: + v = [isoparse(item) for item in value[key]] + elif cls is timedelta: + v = [timedelta(seconds=float(item[:-1])) for item in value[key]] else: - # NOTE: `from_dict` mutates the underlying message, so no - # assignment here is necessary. - v.from_dict(value[key]) - elif meta.map_types and meta.map_types[1] == TYPE_MESSAGE: - v = getattr(self, field_name) - cls = self._betterproto.cls_by_field[f"{field_name}.value"] - for k in value[key]: - v[k] = cls().from_dict(value[key][k]) + v = [cls().from_dict(item) for item in value[key]] + elif cls is datetime: + v = isoparse(value[key]) + setattr(self, field_name, v) + elif cls is timedelta: + v = timedelta(seconds=float(value[key][:-1])) + setattr(self, field_name, v) + elif meta.wraps: + setattr(self, field_name, value[key]) + elif v is None: + setattr(self, field_name, cls().from_dict(value[key])) else: - v = value[key] - if meta.proto_type in INT_64_TYPES: - if isinstance(value[key], list): - v = [int(n) for n in value[key]] - else: - v = int(value[key]) - elif meta.proto_type == TYPE_BYTES: - if isinstance(value[key], list): - v = [b64decode(n) for n in value[key]] - else: - v = b64decode(value[key]) - elif meta.proto_type == TYPE_ENUM: - enum_cls = self._betterproto.cls_by_field[field_name] - if isinstance(v, list): - v = [enum_cls.from_string(e) for e in v] - elif isinstance(v, str): - v = enum_cls.from_string(v) - elif meta.proto_type in (TYPE_FLOAT, TYPE_DOUBLE): - if isinstance(value[key], list): - v = [_parse_float(n) for n in value[key]] - else: - v = _parse_float(value[key]) + # NOTE: `from_dict` mutates the underlying message, so no + # assignment here is necessary. + v.from_dict(value[key]) + elif meta.map_types and meta.map_types[1] == TYPE_MESSAGE: + v = getattr(self, field_name) + cls = self._betterproto.cls_by_field[f"{field_name}.value"] + for k in value[key]: + v[k] = cls().from_dict(value[key][k]) + elif meta.proto_type in INT_64_TYPES: + v = ( + [int(n) for n in value[key]] + if isinstance(value[key], list) + else int(value[key]) + ) - if v is not None: - setattr(self, field_name, v) + elif meta.proto_type == TYPE_BYTES: + v = ( + [b64decode(n) for n in value[key]] + if isinstance(value[key], list) + else b64decode(value[key]) + ) + + elif meta.proto_type == TYPE_ENUM: + enum_cls = self._betterproto.cls_by_field[field_name] + if isinstance(v, list): + v = [enum_cls.from_string(e) for e in v] + elif isinstance(v, str): + v = enum_cls.from_string(v) + elif meta.proto_type in {TYPE_FLOAT, TYPE_DOUBLE}: + if isinstance(value[key], list): + v = [_parse_float(n) for n in value[key]] + else: + v = _parse_float(value[key]) + + setattr(self, field_name, v) return self def to_json(self, indent: Union[None, int, str] = None) -> str: From fea05f251c059b6ca5ec599aca7576a623b3ec6f Mon Sep 17 00:00:00 2001 From: James Hilton-Balfe Date: Mon, 11 Apr 2022 22:57:41 +0100 Subject: [PATCH 09/27] Recursive messages are pain --- src/betterproto/__init__.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/betterproto/__init__.py b/src/betterproto/__init__.py index 8f4967c8e..a82b4a945 100644 --- a/src/betterproto/__init__.py +++ b/src/betterproto/__init__.py @@ -349,7 +349,7 @@ def from_string(cls, name: str) -> "Enum": def encode_varint(value: int) -> bytes: """Encodes a single varint value for serialization.""" - b: List[int] = [] + b: "List[int]" = [] if value < 0: value += 1 << 64 @@ -704,7 +704,7 @@ def __getattribute__(self, name: str) -> Any: Lazily initialize default values to avoid infinite recursion for recursive message types """ - value = self.__raw_get(name) + value = super().__getattribute__(name) if value is not PLACEHOLDER: return value From c942fe1fc75acb14802696aa15344487fd972772 Mon Sep 17 00:00:00 2001 From: James Hilton-Balfe Date: Mon, 11 Apr 2022 23:25:06 +0100 Subject: [PATCH 10/27] Get rid of __raw_get --- src/betterproto/__init__.py | 75 ++++++++++++++++++------------------- 1 file changed, 37 insertions(+), 38 deletions(-) diff --git a/src/betterproto/__init__.py b/src/betterproto/__init__.py index a82b4a945..c8495a972 100644 --- a/src/betterproto/__init__.py +++ b/src/betterproto/__init__.py @@ -487,7 +487,7 @@ def decode_varint(buffer: bytes, pos: int) -> Tuple[int, int]: """ result = 0 shift = 0 - while 1: + while True: b = buffer[pos] result |= (b & 0x7F) << shift pos += 1 @@ -629,6 +629,8 @@ class Message: Calls :meth:`__bool__`. """ + __slots__ = ("_serialized_on_wire", "_unknown_fields", "_group_current") + _serialized_on_wire: bool _unknown_fields: bytes _group_current: Dict[str, str] @@ -644,8 +646,8 @@ def __post_init__(self) -> None: if meta.group: group_current.setdefault(meta.group) - value = self.__raw_get(field_name) - if value != PLACEHOLDER and not (meta.optional and value is None): + value = object.__getattribute__(self, field_name) + if value is not PLACEHOLDER and not (meta.optional and value is None): # Found a non-sentinel value all_sentinel = False @@ -654,19 +656,17 @@ def __post_init__(self) -> None: group_current[meta.group] = field_name # Now that all the defaults are set, reset it! - self.__dict__["_serialized_on_wire"] = not all_sentinel - self.__dict__["_unknown_fields"] = b"" - self.__dict__["_group_current"] = group_current - - __raw_get = object.__getattribute__ + super().__setattr__("_serialized_on_wire", not all_sentinel) + super().__setattr__("_unknown_fields", b"") + super().__setattr__("_group_current", group_current) def __eq__(self, other) -> bool: - if type(self) is not type(other): + if not isinstance(other, type(self)): return False for field_name in self._betterproto.meta_by_field_name: - self_val = self.__raw_get(field_name) - other_val = other.__raw_get(field_name) + self_val = object.__getattribute__(self, field_name) + other_val = object.__getattribute__(other, field_name) if self_val is PLACEHOLDER: if other_val is PLACEHOLDER: continue @@ -674,19 +674,16 @@ def __eq__(self, other) -> bool: elif other_val is PLACEHOLDER: other_val = other._get_field_default(field_name) - if self_val != other_val: + if self_val != other_val and ( + not isinstance(self_val, float) + or not isinstance(other_val, float) + or not math.isnan(self_val) + or not math.isnan(other_val) + ): # We consider two nan values to be the same for the # purposes of comparing messages (otherwise a message # is not equal to itself) - if ( - isinstance(self_val, float) - and isinstance(other_val, float) - and math.isnan(self_val) - and math.isnan(other_val) - ): - continue - else: - return False + return False return True @@ -694,7 +691,7 @@ def __repr__(self) -> str: parts = [ f"{field_name}={value!r}" for field_name in self._betterproto.sorted_field_names - for value in (self.__raw_get(field_name),) + for value in (object.__getattribute__(self, field_name),) if value is not PLACEHOLDER ] return f"{self.__class__.__name__}({', '.join(parts)})" @@ -715,23 +712,25 @@ def __getattribute__(self, name: str) -> Any: def __setattr__(self, attr: str, value: Any) -> None: if attr != "_serialized_on_wire": # Track when a field has been set. - self.__dict__["_serialized_on_wire"] = True - - if hasattr(self, "_group_current"): # __post_init__ had already run - if attr in self._betterproto.oneof_group_by_field: - group = self._betterproto.oneof_group_by_field[attr] - for field in self._betterproto.oneof_field_by_group[group]: - if field.name == attr: - self._group_current[group] = field.name - else: - super().__setattr__(field.name, PLACEHOLDER) + super().__setattr__("_serialized_on_wire", True) + + if ( + hasattr(self, "_group_current") + and attr in self._betterproto.oneof_group_by_field + ): # __post_init__ had already run + group = self._betterproto.oneof_group_by_field[attr] + for field in self._betterproto.oneof_field_by_group[group]: + if field.name == attr: + self._group_current[group] = field.name + else: + super().__setattr__(field.name, PLACEHOLDER) super().__setattr__(attr, value) def __bool__(self) -> bool: """True if the Message has any fields with non-default values.""" return any( - self.__raw_get(field_name) + object.__getattribute__(self, field_name) not in (PLACEHOLDER, self._get_field_default(field_name)) for field_name in self._betterproto.meta_by_field_name ) @@ -739,7 +738,7 @@ def __bool__(self) -> bool: def __deepcopy__(self: T, _: Any = {}) -> T: kwargs = {} for name in self._betterproto.sorted_field_names: - value = self.__raw_get(name) + value = object.__getattribute__(self, name) if value is not PLACEHOLDER: kwargs[name] = deepcopy(value) return self.__class__(**kwargs) # type: ignore @@ -879,9 +878,9 @@ def _type_hints(cls) -> Dict[str, Type]: def _cls_for(cls, field: dataclasses.Field, index: int = 0) -> Type: """Get the message class for a field from the type hints.""" field_cls = cls._type_hint(field.name) - if hasattr(field_cls, "__args__") and index >= 0: - if field_cls.__args__ is not None: - field_cls = field_cls.__args__[index] + args = getattr(field_cls, "__args__", None) + if args and index >= 0 and args is not None: + field_cls = field_cls.__args__[index] return field_cls def _get_field_default(self, field_name: str) -> Any: @@ -1325,7 +1324,7 @@ def is_set(self, name: str) -> bool: :class:`bool` `True` if field has been set, otherwise `False`. """ - return self.__raw_get(name) is not PLACEHOLDER + return object.__getattribute__(self, name) is not PLACEHOLDER def serialized_on_wire(message: Message) -> bool: From c6c5d99c97351813bcfb729a579601cd209a9b56 Mon Sep 17 00:00:00 2001 From: James Hilton-Balfe Date: Mon, 11 Apr 2022 23:35:52 +0100 Subject: [PATCH 11/27] Remove redundant conditional --- src/betterproto/__init__.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/betterproto/__init__.py b/src/betterproto/__init__.py index c8495a972..5c8b30f48 100644 --- a/src/betterproto/__init__.py +++ b/src/betterproto/__init__.py @@ -879,7 +879,7 @@ def _cls_for(cls, field: dataclasses.Field, index: int = 0) -> Type: """Get the message class for a field from the type hints.""" field_cls = cls._type_hint(field.name) args = getattr(field_cls, "__args__", None) - if args and index >= 0 and args is not None: + if args and index >= 0: field_cls = field_cls.__args__[index] return field_cls From 3337c8e018a6e76763f7be897307d195935e862a Mon Sep 17 00:00:00 2001 From: James Hilton-Balfe Date: Mon, 11 Apr 2022 23:54:27 +0100 Subject: [PATCH 12/27] Optimise from_dict slightly better --- src/betterproto/__init__.py | 52 ++++++++++++++++--------------------- 1 file changed, 23 insertions(+), 29 deletions(-) diff --git a/src/betterproto/__init__.py b/src/betterproto/__init__.py index 5c8b30f48..69488107b 100644 --- a/src/betterproto/__init__.py +++ b/src/betterproto/__init__.py @@ -1215,56 +1215,50 @@ def from_dict(self: T, value: Dict[str, Any]) -> T: v = getattr(self, field_name) cls = self._betterproto.cls_by_field[field_name] if isinstance(v, list): - if cls is datetime: - v = [isoparse(item) for item in value[key]] - elif cls is timedelta: - v = [timedelta(seconds=float(item[:-1])) for item in value[key]] + if cls == datetime: + v = [isoparse(item) for item in v] + elif cls == timedelta: + v = [timedelta(seconds=float(item[:-1])) for item in v] else: - v = [cls().from_dict(item) for item in value[key]] - elif cls is datetime: - v = isoparse(value[key]) + v = [cls().from_dict(item) for item in v] + elif cls == datetime: + v = isoparse(v) setattr(self, field_name, v) - elif cls is timedelta: - v = timedelta(seconds=float(value[key][:-1])) + elif cls == timedelta: + v = timedelta(seconds=float(v[:-1])) setattr(self, field_name, v) elif meta.wraps: - setattr(self, field_name, value[key]) + setattr(self, field_name, v) elif v is None: - setattr(self, field_name, cls().from_dict(value[key])) + setattr(self, field_name, cls().from_dict(v)) else: # NOTE: `from_dict` mutates the underlying message, so no # assignment here is necessary. - v.from_dict(value[key]) + v.from_dict(v) elif meta.map_types and meta.map_types[1] == TYPE_MESSAGE: v = getattr(self, field_name) cls = self._betterproto.cls_by_field[f"{field_name}.value"] - for k in value[key]: - v[k] = cls().from_dict(value[key][k]) + target = value[key] + for k in target: + v[k] = cls().from_dict(target[k]) elif meta.proto_type in INT_64_TYPES: - v = ( - [int(n) for n in value[key]] - if isinstance(value[key], list) - else int(value[key]) - ) + v = [int(n) for n in v] if isinstance(v, list) else int(v) elif meta.proto_type == TYPE_BYTES: - v = ( - [b64decode(n) for n in value[key]] - if isinstance(value[key], list) - else b64decode(value[key]) - ) + v = [b64decode(n) for n in v] if isinstance(v, list) else b64decode(v) elif meta.proto_type == TYPE_ENUM: - enum_cls = self._betterproto.cls_by_field[field_name] + enum_cls: Enum = self._betterproto.cls_by_field[field_name] if isinstance(v, list): v = [enum_cls.from_string(e) for e in v] elif isinstance(v, str): v = enum_cls.from_string(v) elif meta.proto_type in {TYPE_FLOAT, TYPE_DOUBLE}: - if isinstance(value[key], list): - v = [_parse_float(n) for n in value[key]] - else: - v = _parse_float(value[key]) + v = ( + [_parse_float(n) for n in v] + if isinstance(v, list) + else _parse_float(v) + ) setattr(self, field_name, v) return self From 32fc5690f2f862e96cb38e672408106c80843502 Mon Sep 17 00:00:00 2001 From: James Hilton-Balfe Date: Tue, 12 Apr 2022 00:39:19 +0100 Subject: [PATCH 13/27] I don't know how this would fix the tests --- src/betterproto/__init__.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/betterproto/__init__.py b/src/betterproto/__init__.py index 69488107b..71dc8b066 100644 --- a/src/betterproto/__init__.py +++ b/src/betterproto/__init__.py @@ -1260,7 +1260,8 @@ def from_dict(self: T, value: Dict[str, Any]) -> T: else _parse_float(v) ) - setattr(self, field_name, v) + if v is not None: + setattr(self, field_name, v) return self def to_json(self, indent: Union[None, int, str] = None) -> str: From f17ec62686d9aae9c204e9661f881341b444355e Mon Sep 17 00:00:00 2001 From: James Hilton-Balfe Date: Tue, 12 Apr 2022 11:04:20 +0100 Subject: [PATCH 14/27] Tests should now actually pass --- src/betterproto/__init__.py | 140 +++++++++++++++++++----------------- 1 file changed, 76 insertions(+), 64 deletions(-) diff --git a/src/betterproto/__init__.py b/src/betterproto/__init__.py index 71dc8b066..b074a0cb6 100644 --- a/src/betterproto/__init__.py +++ b/src/betterproto/__init__.py @@ -32,6 +32,7 @@ ) from dateutil.parser import isoparse +from typing_extensions import Final from ._types import T from ._version import __version__ @@ -44,28 +45,28 @@ # Proto 3 data types -TYPE_ENUM = "enum" -TYPE_BOOL = "bool" -TYPE_INT32 = "int32" -TYPE_INT64 = "int64" -TYPE_UINT32 = "uint32" -TYPE_UINT64 = "uint64" -TYPE_SINT32 = "sint32" -TYPE_SINT64 = "sint64" -TYPE_FLOAT = "float" -TYPE_DOUBLE = "double" -TYPE_FIXED32 = "fixed32" -TYPE_SFIXED32 = "sfixed32" -TYPE_FIXED64 = "fixed64" -TYPE_SFIXED64 = "sfixed64" -TYPE_STRING = "string" -TYPE_BYTES = "bytes" -TYPE_MESSAGE = "message" -TYPE_MAP = "map" +TYPE_ENUM: Final = "enum" +TYPE_BOOL: Final = "bool" +TYPE_INT32: Final = "int32" +TYPE_INT64: Final = "int64" +TYPE_UINT32: Final = "uint32" +TYPE_UINT64: Final = "uint64" +TYPE_SINT32: Final = "sint32" +TYPE_SINT64: Final = "sint64" +TYPE_FLOAT: Final = "float" +TYPE_DOUBLE: Final = "double" +TYPE_FIXED32: Final = "fixed32" +TYPE_SFIXED32: Final = "sfixed32" +TYPE_FIXED64: Final = "fixed64" +TYPE_SFIXED64: Final = "sfixed64" +TYPE_STRING: Final = "string" +TYPE_BYTES: Final = "bytes" +TYPE_MESSAGE: Final = "message" +TYPE_MAP: Final = "map" # Fields that use a fixed amount of space (4 or 8 bytes) -FIXED_TYPES = frozenset( +FIXED_TYPES: Final = frozenset( { TYPE_FLOAT, TYPE_DOUBLE, @@ -77,12 +78,12 @@ ) # Fields that are numerical 64-bit types -INT_64_TYPES = frozenset( +INT_64_TYPES: Final = frozenset( {TYPE_INT64, TYPE_UINT64, TYPE_SINT64, TYPE_FIXED64, TYPE_SFIXED64} ) # Fields that are efficiently packed when serialised -PACKED_TYPES = frozenset( +PACKED_TYPES: Final = frozenset( { TYPE_ENUM, TYPE_BOOL, @@ -103,13 +104,13 @@ # Wire types # https://developers.google.com/protocol-buffers/docs/encoding#structure -WIRE_VARINT = 0 -WIRE_FIXED_64 = 1 -WIRE_LEN_DELIM = 2 -WIRE_FIXED_32 = 5 +WIRE_VARINT: Final = 0 +WIRE_FIXED_64: Final = 1 +WIRE_LEN_DELIM: Final = 2 +WIRE_FIXED_32: Final = 5 # Mappings of which Proto 3 types correspond to which wire types. -WIRE_VARINT_TYPES = frozenset( +WIRE_VARINT_TYPES: Final = frozenset( { TYPE_ENUM, TYPE_BOOL, @@ -122,9 +123,11 @@ } ) -WIRE_FIXED_32_TYPES = frozenset({TYPE_FLOAT, TYPE_FIXED32, TYPE_SFIXED32}) -WIRE_FIXED_64_TYPES = frozenset({TYPE_DOUBLE, TYPE_FIXED64, TYPE_SFIXED64}) -WIRE_LEN_DELIM_TYPES = frozenset({TYPE_STRING, TYPE_BYTES, TYPE_MESSAGE, TYPE_MAP}) +WIRE_FIXED_32_TYPES: Final = frozenset({TYPE_FLOAT, TYPE_FIXED32, TYPE_SFIXED32}) +WIRE_FIXED_64_TYPES: Final = frozenset({TYPE_DOUBLE, TYPE_FIXED64, TYPE_SFIXED64}) +WIRE_LEN_DELIM_TYPES: Final = frozenset( + {TYPE_STRING, TYPE_BYTES, TYPE_MESSAGE, TYPE_MAP} +) # Protobuf datetimes start at the Unix Epoch in 1970 in UTC. @@ -136,9 +139,9 @@ def datetime_default_gen() -> datetime: # Special protobuf json doubles -INFINITY = "Infinity" -NEG_INFINITY = "-Infinity" -NAN = "NaN" +INFINITY: Final = "Infinity" +NEG_INFINITY: Final = "-Infinity" +NAN: Final = "NaN" class Casing(enum.Enum): @@ -148,7 +151,7 @@ class Casing(enum.Enum): SNAKE = snake_case #: A snake_case sterilization function. -PLACEHOLDER: Any = object() +PLACEHOLDER: Final[Any] = object() @dataclasses.dataclass(frozen=True) @@ -1201,64 +1204,73 @@ def from_dict(self: T, value: Dict[str, Any]) -> T: The initialized message. """ self._serialized_on_wire = True - for key, v in value.items(): + for key, value_ in value.items(): field_name = safe_snake_case(key) try: meta = self._betterproto.meta_by_field_name[field_name] except KeyError: continue - if v is None: + if value_ is None: continue if meta.proto_type == TYPE_MESSAGE: v = getattr(self, field_name) - cls = self._betterproto.cls_by_field[field_name] + cls: type[Message] = self._betterproto.cls_by_field[field_name] if isinstance(v, list): - if cls == datetime: - v = [isoparse(item) for item in v] - elif cls == timedelta: - v = [timedelta(seconds=float(item[:-1])) for item in v] + if cls is datetime: + v = [isoparse(item) for item in value_] + elif cls is timedelta: + v = [timedelta(seconds=float(item[:-1])) for item in value_] else: - v = [cls().from_dict(item) for item in v] - elif cls == datetime: - v = isoparse(v) + v = [cls().from_dict(item) for item in value_] + elif cls is datetime: + v = isoparse(value_) setattr(self, field_name, v) - elif cls == timedelta: - v = timedelta(seconds=float(v[:-1])) + elif cls is timedelta: + v = timedelta(seconds=float(value_[:-1])) setattr(self, field_name, v) elif meta.wraps: - setattr(self, field_name, v) + setattr(self, field_name, value_) elif v is None: - setattr(self, field_name, cls().from_dict(v)) + setattr(self, field_name, cls().from_dict(value_)) else: # NOTE: `from_dict` mutates the underlying message, so no # assignment here is necessary. - v.from_dict(v) + v.from_dict(value_) elif meta.map_types and meta.map_types[1] == TYPE_MESSAGE: v = getattr(self, field_name) cls = self._betterproto.cls_by_field[f"{field_name}.value"] - target = value[key] - for k in target: - v[k] = cls().from_dict(target[k]) + for k in value_: + v[k] = cls().from_dict(value_[k]) elif meta.proto_type in INT_64_TYPES: - v = [int(n) for n in v] if isinstance(v, list) else int(v) - + v = ( + [int(n) for n in value_] + if isinstance(value_, list) + else int(value_) + ) elif meta.proto_type == TYPE_BYTES: - v = [b64decode(n) for n in v] if isinstance(v, list) else b64decode(v) - + v = ( + [b64decode(n) for n in value_] + if isinstance(value_, list) + else b64decode(value_) + ) elif meta.proto_type == TYPE_ENUM: - enum_cls: Enum = self._betterproto.cls_by_field[field_name] - if isinstance(v, list): - v = [enum_cls.from_string(e) for e in v] - elif isinstance(v, str): - v = enum_cls.from_string(v) - elif meta.proto_type in {TYPE_FLOAT, TYPE_DOUBLE}: + enum_cls: type[Enum] = self._betterproto.cls_by_field[field_name] + if isinstance(value_, list): + v = [enum_cls.from_string(e) for e in value_] + elif isinstance(value_, str): + v = enum_cls.from_string(value_) + else: + v = value_ + elif meta.proto_type in (TYPE_FLOAT, TYPE_DOUBLE): v = ( - [_parse_float(n) for n in v] - if isinstance(v, list) - else _parse_float(v) + [_parse_float(n) for n in value_] + if isinstance(value_, list) + else _parse_float(value_) ) + else: + v = value_ if v is not None: setattr(self, field_name, v) From fa6fb84ea2ff2a4669a8fbc1753cb5e88b4aaae4 Mon Sep 17 00:00:00 2001 From: James Hilton-Balfe Date: Tue, 12 Apr 2022 15:08:48 +0100 Subject: [PATCH 15/27] Update deps --- poetry.lock | 310 +++++++++++++++++++++++++++---------------------- pyproject.toml | 5 +- 2 files changed, 177 insertions(+), 138 deletions(-) diff --git a/poetry.lock b/poetry.lock index 6ccb6b50d..97176d3be 100644 --- a/poetry.lock +++ b/poetry.lock @@ -66,7 +66,7 @@ typing = {version = ">=3.6", markers = "python_version < \"3.7\""} [[package]] name = "black" -version = "22.1.0" +version = "22.3.0" description = "The uncompromising code formatter." category = "main" optional = true @@ -78,7 +78,7 @@ dataclasses = {version = ">=0.6", markers = "python_version < \"3.7\""} mypy-extensions = ">=0.4.3" pathspec = ">=0.9.0" platformdirs = ">=2" -tomli = ">=1.1.0" +tomli = {version = ">=1.1.0", markers = "python_version < \"3.11\""} typed-ast = {version = ">=1.4.2", markers = "python_version < \"3.8\" and implementation_name == \"cpython\""} typing-extensions = {version = ">=3.10.0.0", markers = "python_version < \"3.10\""} @@ -200,11 +200,11 @@ python-versions = ">=3.6" [[package]] name = "dataclasses" -version = "0.7" +version = "0.6" description = "A backport of the dataclasses module for Python 3.6" category = "main" optional = false -python-versions = ">=3.6, <3.7" +python-versions = "*" [[package]] name = "distlib" @@ -247,7 +247,7 @@ docs = ["sphinx"] [[package]] name = "grpcio" -version = "1.44.0" +version = "1.45.0" description = "HTTP/2-based RPC framework" category = "dev" optional = false @@ -257,19 +257,20 @@ python-versions = ">=3.6" six = ">=1.5.2" [package.extras] -protobuf = ["grpcio-tools (>=1.44.0)"] +protobuf = ["grpcio-tools (>=1.45.0)"] [[package]] name = "grpcio-tools" -version = "1.44.0" +version = "1.45.0" description = "Protobuf code generator for gRPC" category = "dev" optional = false python-versions = ">=3.6" [package.dependencies] -grpcio = ">=1.44.0" +grpcio = ">=1.45.0" protobuf = ">=3.5.0.post1,<4.0dev" +setuptools = "*" [[package]] name = "grpclib" @@ -412,7 +413,7 @@ name = "markupsafe" version = "2.0.1" description = "Safely add untrusted strings to HTML/XML markup." category = "main" -optional = false +optional = true python-versions = ">=3.6" [[package]] @@ -658,7 +659,7 @@ six = ">=1.5" [[package]] name = "pytz" -version = "2021.3" +version = "2022.1" description = "World timezone definitions, modern and historical" category = "dev" optional = false @@ -690,6 +691,18 @@ urllib3 = ">=1.21.1,<1.27" socks = ["PySocks (>=1.5.6,!=1.5.7)", "win-inet-pton"] use_chardet_on_py3 = ["chardet (>=3.0.2,<5)"] +[[package]] +name = "setuptools" +version = "59.6.0" +description = "Easily download, build, install, upgrade, and uninstall Python packages" +category = "dev" +optional = false +python-versions = ">=3.6" + +[package.extras] +docs = ["sphinx", "jaraco.packaging (>=8.2)", "rst.linker (>=1.9)", "jaraco.tidelift (>=1.4)", "pygments-github-lexers (==0.0.5)", "sphinx-inline-tabs", "sphinxcontrib-towncrier", "furo"] +testing = ["pytest (>=6)", "pytest-checkdocs (>=2.4)", "pytest-flake8", "pytest-cov", "pytest-enabler (>=1.0.1)", "mock", "flake8-2020", "virtualenv (>=13.0.0)", "pytest-virtualenv (>=1.2.7)", "wheel", "paver", "pip (>=19.1)", "jaraco.envs (>=2.2)", "pytest-xdist", "sphinx", "jaraco.path (>=3.2.0)", "pytest-black (>=0.3.7)", "pytest-mypy"] + [[package]] name = "six" version = "1.16.0" @@ -724,6 +737,7 @@ Jinja2 = ">=2.3" packaging = "*" Pygments = ">=2.0" requests = ">=2.5.0" +setuptools = "*" snowballstemmer = ">=1.1" sphinxcontrib-applehelp = "*" sphinxcontrib-devhelp = "*" @@ -848,7 +862,7 @@ python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*" [[package]] name = "tox" -version = "3.24.5" +version = "3.25.0" description = "tox is a generic virtualenv management and test command line tool" category = "dev" optional = false @@ -895,20 +909,20 @@ python-versions = ">=3.6" [[package]] name = "urllib3" -version = "1.26.8" +version = "1.26.9" description = "HTTP library with thread-safe connection pooling, file post, and more." category = "dev" optional = false python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*, <4" [package.extras] -brotli = ["brotlipy (>=0.6.0)"] +brotli = ["brotlicffi (>=0.8.0)", "brotli (>=1.0.9)", "brotlipy (>=0.6.0)"] secure = ["pyOpenSSL (>=0.14)", "cryptography (>=1.3.4)", "idna (>=2.0.0)", "certifi", "ipaddress"] socks = ["PySocks (>=1.5.6,!=1.5.7,<2.0)"] [[package]] name = "virtualenv" -version = "20.13.2" +version = "20.14.1" description = "Virtual Python Environment builder" category = "dev" optional = false @@ -944,7 +958,7 @@ compiler = ["black", "isort", "jinja2"] [metadata] lock-version = "1.1" python-versions = ">=3.6.2,<4.0" -content-hash = "2891bac64691f1030eb74c847cd5a8d9b43598b108cf03db80a987b168d89a22" +content-hash = "9e32e1ce16b4bd6d929f9646288e038ca8e19627f11ba0c0472a41173e5e52ad" [metadata.files] alabaster = [ @@ -971,29 +985,29 @@ babel = [ {file = "backports.cached_property-1.0.1-py3-none-any.whl", hash = "sha256:687b5fe14be40aadcf547cae91337a1fdb84026046a39370274e54d3fe4fb4f9"}, ] black = [ - {file = "black-22.1.0-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:1297c63b9e1b96a3d0da2d85d11cd9bf8664251fd69ddac068b98dc4f34f73b6"}, - {file = "black-22.1.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:2ff96450d3ad9ea499fc4c60e425a1439c2120cbbc1ab959ff20f7c76ec7e866"}, - {file = "black-22.1.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:0e21e1f1efa65a50e3960edd068b6ae6d64ad6235bd8bfea116a03b21836af71"}, - {file = "black-22.1.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e2f69158a7d120fd641d1fa9a921d898e20d52e44a74a6fbbcc570a62a6bc8ab"}, - {file = "black-22.1.0-cp310-cp310-win_amd64.whl", hash = "sha256:228b5ae2c8e3d6227e4bde5920d2fc66cc3400fde7bcc74f480cb07ef0b570d5"}, - {file = "black-22.1.0-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:b1a5ed73ab4c482208d20434f700d514f66ffe2840f63a6252ecc43a9bc77e8a"}, - {file = "black-22.1.0-cp36-cp36m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:35944b7100af4a985abfcaa860b06af15590deb1f392f06c8683b4381e8eeaf0"}, - {file = "black-22.1.0-cp36-cp36m-win_amd64.whl", hash = "sha256:7835fee5238fc0a0baf6c9268fb816b5f5cd9b8793423a75e8cd663c48d073ba"}, - {file = "black-22.1.0-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:dae63f2dbf82882fa3b2a3c49c32bffe144970a573cd68d247af6560fc493ae1"}, - {file = "black-22.1.0-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:5fa1db02410b1924b6749c245ab38d30621564e658297484952f3d8a39fce7e8"}, - {file = "black-22.1.0-cp37-cp37m-win_amd64.whl", hash = "sha256:c8226f50b8c34a14608b848dc23a46e5d08397d009446353dad45e04af0c8e28"}, - {file = "black-22.1.0-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:2d6f331c02f0f40aa51a22e479c8209d37fcd520c77721c034517d44eecf5912"}, - {file = "black-22.1.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:742ce9af3086e5bd07e58c8feb09dbb2b047b7f566eb5f5bc63fd455814979f3"}, - {file = "black-22.1.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:fdb8754b453fb15fad3f72cd9cad3e16776f0964d67cf30ebcbf10327a3777a3"}, - {file = "black-22.1.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f5660feab44c2e3cb24b2419b998846cbb01c23c7fe645fee45087efa3da2d61"}, - {file = "black-22.1.0-cp38-cp38-win_amd64.whl", hash = "sha256:6f2f01381f91c1efb1451998bd65a129b3ed6f64f79663a55fe0e9b74a5f81fd"}, - {file = "black-22.1.0-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:efbadd9b52c060a8fc3b9658744091cb33c31f830b3f074422ed27bad2b18e8f"}, - {file = "black-22.1.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:8871fcb4b447206904932b54b567923e5be802b9b19b744fdff092bd2f3118d0"}, - {file = "black-22.1.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:ccad888050f5393f0d6029deea2a33e5ae371fd182a697313bdbd835d3edaf9c"}, - {file = "black-22.1.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:07e5c049442d7ca1a2fc273c79d1aecbbf1bc858f62e8184abe1ad175c4f7cc2"}, - {file = "black-22.1.0-cp39-cp39-win_amd64.whl", hash = "sha256:373922fc66676133ddc3e754e4509196a8c392fec3f5ca4486673e685a421321"}, - {file = "black-22.1.0-py3-none-any.whl", hash = "sha256:3524739d76b6b3ed1132422bf9d82123cd1705086723bc3e235ca39fd21c667d"}, - {file = "black-22.1.0.tar.gz", hash = "sha256:a7c0192d35635f6fc1174be575cb7915e92e5dd629ee79fdaf0dcfa41a80afb5"}, + {file = "black-22.3.0-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:2497f9c2386572e28921fa8bec7be3e51de6801f7459dffd6e62492531c47e09"}, + {file = "black-22.3.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:5795a0375eb87bfe902e80e0c8cfaedf8af4d49694d69161e5bd3206c18618bb"}, + {file = "black-22.3.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:e3556168e2e5c49629f7b0f377070240bd5511e45e25a4497bb0073d9dda776a"}, + {file = "black-22.3.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:67c8301ec94e3bcc8906740fe071391bce40a862b7be0b86fb5382beefecd968"}, + {file = "black-22.3.0-cp310-cp310-win_amd64.whl", hash = "sha256:fd57160949179ec517d32ac2ac898b5f20d68ed1a9c977346efbac9c2f1e779d"}, + {file = "black-22.3.0-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:cc1e1de68c8e5444e8f94c3670bb48a2beef0e91dddfd4fcc29595ebd90bb9ce"}, + {file = "black-22.3.0-cp36-cp36m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6d2fc92002d44746d3e7db7cf9313cf4452f43e9ea77a2c939defce3b10b5c82"}, + {file = "black-22.3.0-cp36-cp36m-win_amd64.whl", hash = "sha256:a6342964b43a99dbc72f72812bf88cad8f0217ae9acb47c0d4f141a6416d2d7b"}, + {file = "black-22.3.0-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:328efc0cc70ccb23429d6be184a15ce613f676bdfc85e5fe8ea2a9354b4e9015"}, + {file = "black-22.3.0-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:06f9d8846f2340dfac80ceb20200ea5d1b3f181dd0556b47af4e8e0b24fa0a6b"}, + {file = "black-22.3.0-cp37-cp37m-win_amd64.whl", hash = "sha256:ad4efa5fad66b903b4a5f96d91461d90b9507a812b3c5de657d544215bb7877a"}, + {file = "black-22.3.0-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:e8477ec6bbfe0312c128e74644ac8a02ca06bcdb8982d4ee06f209be28cdf163"}, + {file = "black-22.3.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:637a4014c63fbf42a692d22b55d8ad6968a946b4a6ebc385c5505d9625b6a464"}, + {file = "black-22.3.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:863714200ada56cbc366dc9ae5291ceb936573155f8bf8e9de92aef51f3ad0f0"}, + {file = "black-22.3.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:10dbe6e6d2988049b4655b2b739f98785a884d4d6b85bc35133a8fb9a2233176"}, + {file = "black-22.3.0-cp38-cp38-win_amd64.whl", hash = "sha256:cee3e11161dde1b2a33a904b850b0899e0424cc331b7295f2a9698e79f9a69a0"}, + {file = "black-22.3.0-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:5891ef8abc06576985de8fa88e95ab70641de6c1fca97e2a15820a9b69e51b20"}, + {file = "black-22.3.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:30d78ba6bf080eeaf0b7b875d924b15cd46fec5fd044ddfbad38c8ea9171043a"}, + {file = "black-22.3.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:ee8f1f7228cce7dffc2b464f07ce769f478968bfb3dd1254a4c2eeed84928aad"}, + {file = "black-22.3.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6ee227b696ca60dd1c507be80a6bc849a5a6ab57ac7352aad1ffec9e8b805f21"}, + {file = "black-22.3.0-cp39-cp39-win_amd64.whl", hash = "sha256:9b542ced1ec0ceeff5b37d69838106a6348e60db7b8fdd245294dc1d26136265"}, + {file = "black-22.3.0-py3-none-any.whl", hash = "sha256:bc58025940a896d7e5356952228b68f793cf5fcb342be703c3a2669a1488cb72"}, + {file = "black-22.3.0.tar.gz", hash = "sha256:35020b8886c022ced9282b51b5a875b6d1ab0c387b31a065b84db7c33085ca79"}, ] blessings = [ {file = "blessings-1.7-py2-none-any.whl", hash = "sha256:caad5211e7ba5afe04367cdd4cfc68fa886e2e08f6f35e76b7387d2109ccea6e"}, @@ -1100,8 +1114,8 @@ cwcwidth = [ {file = "cwcwidth-0.1.5.tar.gz", hash = "sha256:2c840e7d85f6de45c45986b416d79312c91882e1121b78d4c347e49c4238c09d"}, ] dataclasses = [ - {file = "dataclasses-0.7-py3-none-any.whl", hash = "sha256:3459118f7ede7c8bea0fe795bff7c6c2ce287d01dd226202f7c9ebc0610a7836"}, - {file = "dataclasses-0.7.tar.gz", hash = "sha256:494a6dcae3b8bcf80848eea2ef64c0cc5cd307ffc263e17cdf42f3e5420808e6"}, + {file = "dataclasses-0.6-py3-none-any.whl", hash = "sha256:454a69d788c7fda44efd71e259be79577822f5e3f53f029a22d08004e951dc9f"}, + {file = "dataclasses-0.6.tar.gz", hash = "sha256:6988bd2b895eef432d562370bb707d540f32f7360ab13da45340101bc2307d84"}, ] distlib = [ {file = "distlib-0.3.4-py2.py3-none-any.whl", hash = "sha256:6564fe0a8f51e734df6333d08b8b94d4ea8ee6b99b5ed50613f731fd4089f34b"}, @@ -1173,96 +1187,116 @@ greenlet = [ {file = "greenlet-1.1.2.tar.gz", hash = "sha256:e30f5ea4ae2346e62cedde8794a56858a67b878dd79f7df76a0767e356b1744a"}, ] grpcio = [ - {file = "grpcio-1.44.0-cp310-cp310-linux_armv7l.whl", hash = "sha256:11f811c0fffd84fca747fbc742464575e5eb130fd4fb4d6012ccc34febd001db"}, - {file = "grpcio-1.44.0-cp310-cp310-macosx_10_10_universal2.whl", hash = "sha256:9a86a91201f8345502ea81dee0a55ae13add5fafadf109b17acd858fe8239651"}, - {file = "grpcio-1.44.0-cp310-cp310-manylinux_2_17_aarch64.whl", hash = "sha256:5f3c54ebb5d9633a557335c01d88d3d4928e9b1b131692283b6184da1edbec0b"}, - {file = "grpcio-1.44.0-cp310-cp310-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:3d47553b8e86ab1e59b0185ba6491a187f94a0239f414c8fc867a22b0405b798"}, - {file = "grpcio-1.44.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d1e22d3a510438b7f3365c0071b810672d09febac6e8ca8a47eab657ae5f347b"}, - {file = "grpcio-1.44.0-cp310-cp310-win32.whl", hash = "sha256:41036a574cab3468f24d41d6ed2b52588fb85ed60f8feaa925d7e424a250740b"}, - {file = "grpcio-1.44.0-cp310-cp310-win_amd64.whl", hash = "sha256:4ee51964edfd0a1293a95bb0d72d134ecf889379d90d2612cbf663623ce832b4"}, - {file = "grpcio-1.44.0-cp36-cp36m-linux_armv7l.whl", hash = "sha256:e2149077d71e060678130644670389ddf1491200bcea16c5560d4ccdc65e3f2e"}, - {file = "grpcio-1.44.0-cp36-cp36m-macosx_10_10_x86_64.whl", hash = "sha256:0ac72d4b953b76924f8fa21436af060d7e6d8581e279863f30ee14f20751ac27"}, - {file = "grpcio-1.44.0-cp36-cp36m-manylinux2010_i686.whl", hash = "sha256:5c30a9a7d3a05920368a60b080cbbeaf06335303be23ac244034c71c03a0fd24"}, - {file = "grpcio-1.44.0-cp36-cp36m-manylinux2010_x86_64.whl", hash = "sha256:05467acd391e3fffb05991c76cb2ed2fa1309d0e3815ac379764bc5670b4b5d4"}, - {file = "grpcio-1.44.0-cp36-cp36m-manylinux_2_17_aarch64.whl", hash = "sha256:b81dc7894062ed2d25b74a2725aaa0a6895ce97ce854f432fe4e87cad5a07316"}, - {file = "grpcio-1.44.0-cp36-cp36m-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:46d4843192e7d36278884282e100b8f305cf37d1b3d8c6b4f736d4454640a069"}, - {file = "grpcio-1.44.0-cp36-cp36m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:898c159148f27e23c08a337fb80d31ece6b76bb24f359d83929460d813665b74"}, - {file = "grpcio-1.44.0-cp36-cp36m-win32.whl", hash = "sha256:b8d852329336c584c636caa9c2db990f3a332b19bc86a80f4646b58d27c142db"}, - {file = "grpcio-1.44.0-cp36-cp36m-win_amd64.whl", hash = "sha256:790d7493337558ae168477d1be3178f4c9b8f91d8cd9b8b719d06fd9b2d48836"}, - {file = "grpcio-1.44.0-cp37-cp37m-linux_armv7l.whl", hash = "sha256:cd61b52d9cf8fcf8d9628c0b640b9e44fdc5e93d989cc268086a858540ed370c"}, - {file = "grpcio-1.44.0-cp37-cp37m-macosx_10_10_x86_64.whl", hash = "sha256:14eefcf623890f3f7dd7831decd2a2116652b5ce1e0f1d4b464b8f52110743b0"}, - {file = "grpcio-1.44.0-cp37-cp37m-manylinux2010_i686.whl", hash = "sha256:bebe90b8020b4248e5a2076b56154cc6ff45691bbbe980579fc9db26717ac968"}, - {file = "grpcio-1.44.0-cp37-cp37m-manylinux2010_x86_64.whl", hash = "sha256:89b390b1c0de909965280d175c53128ce2f0f4f5c0f011382243dd7f2f894060"}, - {file = "grpcio-1.44.0-cp37-cp37m-manylinux_2_17_aarch64.whl", hash = "sha256:c122dac5cb299b8ad7308d61bd9fe0413de13b0347cce465398436b3fdf1f609"}, - {file = "grpcio-1.44.0-cp37-cp37m-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:6641a28cc826a92ef717201cca9a035c34a0185e38b0c93f3ce5f01a01a1570a"}, - {file = "grpcio-1.44.0-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:fdb0a3e0e64843441793923d9532a3a23907b07b2a1e0a7a31f186dc185bb772"}, - {file = "grpcio-1.44.0-cp37-cp37m-win32.whl", hash = "sha256:be857b7ec2ac43455156e6ba89262f7d7ae60227049427d01a3fecd218a3f88d"}, - {file = "grpcio-1.44.0-cp37-cp37m-win_amd64.whl", hash = "sha256:f6a9cf0e77f72f2ac30c9c6e086bc7446c984c51bebc6c7f50fbcd718037edba"}, - {file = "grpcio-1.44.0-cp38-cp38-linux_armv7l.whl", hash = "sha256:19e54f0c7083c8332b5a75a9081fc5127f1dbb67b6c1a32bd7fe896ef0934918"}, - {file = "grpcio-1.44.0-cp38-cp38-macosx_10_10_x86_64.whl", hash = "sha256:bfd36b959c3c4e945119387baed1414ea46f7116886aa23de0172302b49d7ff1"}, - {file = "grpcio-1.44.0-cp38-cp38-manylinux2010_i686.whl", hash = "sha256:ccd388b8f37b19d06e4152189726ce309e36dc03b53f2216a4ea49f09a7438e6"}, - {file = "grpcio-1.44.0-cp38-cp38-manylinux2010_x86_64.whl", hash = "sha256:9075c0c003c1ff14ebce8f0ba55cc692158cb55c68da09cf8b0f9fc5b749e343"}, - {file = "grpcio-1.44.0-cp38-cp38-manylinux_2_17_aarch64.whl", hash = "sha256:e898194f76212facbaeb6d7545debff29351afa23b53ff8f0834d66611af5139"}, - {file = "grpcio-1.44.0-cp38-cp38-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:8fa6584046a7cf281649975a363673fa5d9c6faf9dc923f261cc0e56713b5892"}, - {file = "grpcio-1.44.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:36a7bdd6ef9bca050c7ade8cba5f0e743343ea0756d5d3d520e915098a9dc503"}, - {file = "grpcio-1.44.0-cp38-cp38-win32.whl", hash = "sha256:dc3290d0411ddd2bd49adba5793223de8de8b01588d45e9376f1a9f7d25414f4"}, - {file = "grpcio-1.44.0-cp38-cp38-win_amd64.whl", hash = "sha256:13343e7b840c20f43b44f0e6d3bbdc037c964f0aec9735d7cb685c407731c9ff"}, - {file = "grpcio-1.44.0-cp39-cp39-linux_armv7l.whl", hash = "sha256:c5c2f8417d13386e18ccc8c61467cb6a6f9667a1ff7000a2d7d378e5d7df693f"}, - {file = "grpcio-1.44.0-cp39-cp39-macosx_10_10_x86_64.whl", hash = "sha256:cf220199b7b4992729ad4d55d5d3f652f4ccfe1a35b5eacdbecf189c245e1859"}, - {file = "grpcio-1.44.0-cp39-cp39-manylinux2010_i686.whl", hash = "sha256:4201c597e5057a9bfef9ea5777a6d83f6252cb78044db7d57d941ec2300734a5"}, - {file = "grpcio-1.44.0-cp39-cp39-manylinux2010_x86_64.whl", hash = "sha256:e2de61005118ae59d48d5d749283ebfd1ba4ca68cc1000f8a395cd2bdcff7ceb"}, - {file = "grpcio-1.44.0-cp39-cp39-manylinux_2_17_aarch64.whl", hash = "sha256:871078218fa9117e2a378678f327e32fda04e363ed6bc0477275444273255d4d"}, - {file = "grpcio-1.44.0-cp39-cp39-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:a8d610b7b557a7609fecee80b6dd793ecb7a9a3c3497fbdce63ce7d151cdd705"}, - {file = "grpcio-1.44.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4fcb53e4eb8c271032c91b8981df5fc1bb974bc73e306ec2c27da41bd95c44b5"}, - {file = "grpcio-1.44.0-cp39-cp39-win32.whl", hash = "sha256:e50ddea6de76c09b656df4b5a55ae222e2a56e625c44250e501ff3c904113ec1"}, - {file = "grpcio-1.44.0-cp39-cp39-win_amd64.whl", hash = "sha256:d2ec124a986093e26420a5fb10fa3f02b2c232f924cdd7b844ddf7e846c020cd"}, - {file = "grpcio-1.44.0.tar.gz", hash = "sha256:4bae1c99896045d3062ab95478411c8d5a52cb84b91a1517312629fa6cfeb50e"}, + {file = "grpcio-1.45.0-cp310-cp310-linux_armv7l.whl", hash = "sha256:0d74a159df9401747e57960f0772f4371486e3281919004efa9df8a82985abee"}, + {file = "grpcio-1.45.0-cp310-cp310-macosx_10_10_universal2.whl", hash = "sha256:4e6d15bfdfa28e5f6d524dd3b29c7dc129cfc578505b067aa97574490c5b70fe"}, + {file = "grpcio-1.45.0-cp310-cp310-manylinux_2_17_aarch64.whl", hash = "sha256:44615be86e5540a18f5e4ca5a0f428d4b1efb800d255cfd9f902a11daca8fd74"}, + {file = "grpcio-1.45.0-cp310-cp310-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:8b452f715e2cae9e75cb309f59a37f82e5b25f51f0bfc3cd1462de86265cef05"}, + {file = "grpcio-1.45.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:db1c45daa35c64f17498af1ba6eb1d0a8d88a8a0b6b322f960ab461e7ef0419e"}, + {file = "grpcio-1.45.0-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:678a673fe811dad3ed5bd2e2352b79851236e4d718aeaeffc10f372a55954d8d"}, + {file = "grpcio-1.45.0-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:a5c8a08aff0af770c977dcede62fbed53ae7b99adbc184d5299d148bb04652f1"}, + {file = "grpcio-1.45.0-cp310-cp310-win32.whl", hash = "sha256:1d764c8a190719301ec6f3b6ddeb48a234604e337d0fbb3184a4ddcda2aca9da"}, + {file = "grpcio-1.45.0-cp310-cp310-win_amd64.whl", hash = "sha256:797f5b750be6ff2905b9d0529a00c1f873d8035a5d01a9801910ace5f0d52a18"}, + {file = "grpcio-1.45.0-cp36-cp36m-linux_armv7l.whl", hash = "sha256:b46772b7eb58c6cb0b468b56d59618694d2c2f2cee2e5b4e83ae9729a46b8af0"}, + {file = "grpcio-1.45.0-cp36-cp36m-macosx_10_10_x86_64.whl", hash = "sha256:2f135e5c8e9acd14f3090fd86dccb9d7c26aea7bfbd4528e8a86ff621d39e610"}, + {file = "grpcio-1.45.0-cp36-cp36m-manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:16603b9544a4af135ce4d594a7396602fbe62d1ccaa484b05cb1814c17a3e559"}, + {file = "grpcio-1.45.0-cp36-cp36m-manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:ccba925045c00acc9ce2cc645b6fa9d19767dbb16c9c49921013da412b1d3415"}, + {file = "grpcio-1.45.0-cp36-cp36m-manylinux_2_17_aarch64.whl", hash = "sha256:7262b9d96db79e29049c7eb2b75b03f2b9485fd838209b5ff8e3cca73b2a706c"}, + {file = "grpcio-1.45.0-cp36-cp36m-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:a1c1098f35c33b985c312cacea39e2aa66f7ac1462579eed1d3aed2e51fff00d"}, + {file = "grpcio-1.45.0-cp36-cp36m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0b18c86a9cfbedd0c4e083690fecc82027b3f938100ed0af8db77d52a171eb1e"}, + {file = "grpcio-1.45.0-cp36-cp36m-musllinux_1_1_i686.whl", hash = "sha256:638364d3603df9e4a1dbc2151b5fe1b491ceecda4e1672be86724e1dfa79c44d"}, + {file = "grpcio-1.45.0-cp36-cp36m-musllinux_1_1_x86_64.whl", hash = "sha256:8de79eac582431cb6d05ff5652e68089c40aa0e604ec1630fa52ac926bc44f1b"}, + {file = "grpcio-1.45.0-cp36-cp36m-win32.whl", hash = "sha256:6cf5f1827c182ef9b503d7d01e503c1067f4499d45af792d95ccd1d8b0bea30d"}, + {file = "grpcio-1.45.0-cp36-cp36m-win_amd64.whl", hash = "sha256:4f1a22744f93b38d393b7a83cb607029ac5e2de680cab39957ffdd116590a178"}, + {file = "grpcio-1.45.0-cp37-cp37m-linux_armv7l.whl", hash = "sha256:321f84dbc788481f7a3cd12636a133ba5f4d17e57f1c906de5a22fd709c971b5"}, + {file = "grpcio-1.45.0-cp37-cp37m-macosx_10_10_x86_64.whl", hash = "sha256:a33ed7d3e52ddc839e2f020592a4371d805c2ae820fb63b12525058e1810fe46"}, + {file = "grpcio-1.45.0-cp37-cp37m-manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:f9f28d8c5343602e1510d4839e38568bcd0ca6353bd98ad9941787584a371a1d"}, + {file = "grpcio-1.45.0-cp37-cp37m-manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:3a40dbb8aac60cf6a86583e2ba74fc2c286f1abc7a3404b25dcd12a49b9f7d8b"}, + {file = "grpcio-1.45.0-cp37-cp37m-manylinux_2_17_aarch64.whl", hash = "sha256:b00ce58323dde47d2ea240d10ee745471b9966429c97d9e6567c8d56e02b0372"}, + {file = "grpcio-1.45.0-cp37-cp37m-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:bd4944f35f1e5ab54804c3e37d24921ecc01908ef871cdce6bd52995ea4f985c"}, + {file = "grpcio-1.45.0-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:cc135b77f384a84bac67a37947886986be136356446338d64160a30c85f20c6d"}, + {file = "grpcio-1.45.0-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:35ae55460514ed404ceaa95533b9a79989691b562faf012fc8fb143d8fd16e47"}, + {file = "grpcio-1.45.0-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:779db3d00c8da1d3efa942387cb0fea9ac6d50124d656024f82f9faefdd016e3"}, + {file = "grpcio-1.45.0-cp37-cp37m-win32.whl", hash = "sha256:aea67bd3cbf93db552c725bc0b4db0acdc6a284d036d1cc32d638305e0f01fd9"}, + {file = "grpcio-1.45.0-cp37-cp37m-win_amd64.whl", hash = "sha256:7fe3ac700cc5ecba9dc9072c0e6cfd2f964ea9f273ce1111eaa27d13aa20ec32"}, + {file = "grpcio-1.45.0-cp38-cp38-linux_armv7l.whl", hash = "sha256:259c126821fefcda298c020a0d83c4a4edac3cf10b1af12a62d250f8192ea1d1"}, + {file = "grpcio-1.45.0-cp38-cp38-macosx_10_10_x86_64.whl", hash = "sha256:5d05cd1b2b0975bb000ba97ca465565158dc211616c9bbbef5d1b77871974687"}, + {file = "grpcio-1.45.0-cp38-cp38-manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:6f2e044a715507fd13c70c928cd90daf8d0295c936a81fd9065a24e58ba7cc7d"}, + {file = "grpcio-1.45.0-cp38-cp38-manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:4d37c526b86c46d229f6117df5dca2510de597ab73c5956bc379ca41f8a1db84"}, + {file = "grpcio-1.45.0-cp38-cp38-manylinux_2_17_aarch64.whl", hash = "sha256:6df338b8d2c328ba91a25e28786d10059dea3bc9115fa1ddad30ba5d459e714a"}, + {file = "grpcio-1.45.0-cp38-cp38-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:042921a824e90bf2974dbef7d89937096181298294799fb53e5576d9958884c7"}, + {file = "grpcio-1.45.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:fb23ed6ed84ae312df03e96c7a7cd3aa5f7e3a1ad7066fdb6cd47f1bd334196c"}, + {file = "grpcio-1.45.0-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:79582ec821ef10162348170a6e912d93ea257c749320a162dfc3a132ef25ac1b"}, + {file = "grpcio-1.45.0-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:d14d372ea5a51d5ab991aa6d499a26e5a1e3b3f3af93f41826ea610f8a276c9e"}, + {file = "grpcio-1.45.0-cp38-cp38-win32.whl", hash = "sha256:b54444cf4212935a7b98cd26a30ad3a036389e4fd2ff3e461b176af876c7e20b"}, + {file = "grpcio-1.45.0-cp38-cp38-win_amd64.whl", hash = "sha256:da395720d6e9599c754f862f3f75bc0e8ff29fa55259e082e442a9cc916ffbc3"}, + {file = "grpcio-1.45.0-cp39-cp39-linux_armv7l.whl", hash = "sha256:add03308fa2d434628aeaa445e0c75cdb9535f39128eb949b1483ae83fafade6"}, + {file = "grpcio-1.45.0-cp39-cp39-macosx_10_10_x86_64.whl", hash = "sha256:250d8f18332f3dbd4db00efa91d33d336e58362e9c80e6946d45ecf5e82d95ec"}, + {file = "grpcio-1.45.0-cp39-cp39-manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:dfca4dfd307b449d0a1e92bc7fbb5224ccf16db384aab412ba6766fc56bdffb6"}, + {file = "grpcio-1.45.0-cp39-cp39-manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:b7f2dc8831045eb0c892bb947e1cba2b1ed639e79a54abff7c4ad90bdd329f78"}, + {file = "grpcio-1.45.0-cp39-cp39-manylinux_2_17_aarch64.whl", hash = "sha256:2355493a9e71f15d9004b2ab87892cb532e9e98db6882fced2912115eb5631af"}, + {file = "grpcio-1.45.0-cp39-cp39-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:2798e42d62a0296982276d0bab96fc7d6772cd148357154348355304d6216763"}, + {file = "grpcio-1.45.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0fe6acb1439127e0bee773f8a9a3ece290cb4cac4fe8d46b10bc8dda250a990c"}, + {file = "grpcio-1.45.0-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:6774272a59b9ee16fb0d4f53e23716953a22bbb3efe12fdf9a4ee3eec2c4f81f"}, + {file = "grpcio-1.45.0-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:52f61fcb17d92b87ba47d54b3c9deae09d4f0216a3ea277b7df4b6c1794e6556"}, + {file = "grpcio-1.45.0-cp39-cp39-win32.whl", hash = "sha256:3992c690228126e5652c7a1f61863c1ebfd71369cf2adb0fce86fee1d82d2d27"}, + {file = "grpcio-1.45.0-cp39-cp39-win_amd64.whl", hash = "sha256:220867a53e53b2e201e98c55061e3053e31c0ce613625087242be684d3e8612a"}, + {file = "grpcio-1.45.0.tar.gz", hash = "sha256:ff2c8b965b0fc25cf281961aa46619c10900543effe3f806ef818231c40aaff3"}, ] grpcio-tools = [ - {file = "grpcio-tools-1.44.0.tar.gz", hash = "sha256:be37f458ea510c9a8f1caabbc2b258d12e55d189a567f5edcace90f27dc0efbf"}, - {file = "grpcio_tools-1.44.0-cp310-cp310-linux_armv7l.whl", hash = "sha256:9f58529e24f613019a85c258a274d441d89e0cad8cf7fca21ef3807ba5840c5d"}, - {file = "grpcio_tools-1.44.0-cp310-cp310-macosx_10_10_universal2.whl", hash = "sha256:1d120082236f8d2877f8a19366476b82c3562423b877b7c471a142432e31c2c4"}, - {file = "grpcio_tools-1.44.0-cp310-cp310-manylinux_2_17_aarch64.whl", hash = "sha256:65c2fe3cdc5425180f01dd303e28d4f363d38f4c2e3a7e1a87caedd5417e23bb"}, - {file = "grpcio_tools-1.44.0-cp310-cp310-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:5caef118deb8cdee1978fd3d8e388a9b256cd8d34e4a8895731ac0e86fa5e47c"}, - {file = "grpcio_tools-1.44.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:121c9765cee8636201cf0d4e80bc7b509813194919bccdb66e9671c4ece6dac3"}, - {file = "grpcio_tools-1.44.0-cp310-cp310-win32.whl", hash = "sha256:90d1fac188bac838c4169eb3b67197887fa0572ea8a90519a20cddb080800549"}, - {file = "grpcio_tools-1.44.0-cp310-cp310-win_amd64.whl", hash = "sha256:3e16260dfe6e997330473863e01466b0992369ae2337a0249b390b4651cff424"}, - {file = "grpcio_tools-1.44.0-cp36-cp36m-linux_armv7l.whl", hash = "sha256:608414cc1093e1e9e5980c97a6ee78e51dffff359e7a3f123d1fb9d95b8763a5"}, - {file = "grpcio_tools-1.44.0-cp36-cp36m-macosx_10_10_x86_64.whl", hash = "sha256:395609c06f69fbc79518b30a01931127088a3f9ef2cc2a35269c5f187eefd38c"}, - {file = "grpcio_tools-1.44.0-cp36-cp36m-manylinux2010_i686.whl", hash = "sha256:f7ce16766b24b88ec0e4355f5dd66c2eee6af210e889fcb7961c9c4634c687de"}, - {file = "grpcio_tools-1.44.0-cp36-cp36m-manylinux2010_x86_64.whl", hash = "sha256:3c9abc4a40c62f46d5e43e49c7afc567dedf12eeef95933ac9ea2986baa2420b"}, - {file = "grpcio_tools-1.44.0-cp36-cp36m-manylinux_2_17_aarch64.whl", hash = "sha256:b73fd87a44ba1b91866b0254193c37cdb001737759b77b637cebe0c816d38342"}, - {file = "grpcio_tools-1.44.0-cp36-cp36m-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:2b211f12e4cbc0fde8e0f982b0f581cce38874666a02ebfed93c23dcaeb8a4e0"}, - {file = "grpcio_tools-1.44.0-cp36-cp36m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9b421dc9b27bcaff4c73644cd3801e4893b11ba3eb39729246fd3de98d9f685b"}, - {file = "grpcio_tools-1.44.0-cp36-cp36m-win32.whl", hash = "sha256:33d93027840a873c7b59402fe6db8263b88c56e2f84aa0b6281c05cc8bd314a1"}, - {file = "grpcio_tools-1.44.0-cp36-cp36m-win_amd64.whl", hash = "sha256:71fb6e7e66b918803b1bebd0231560981ab86c2546a3318a45822ce94de5e83d"}, - {file = "grpcio_tools-1.44.0-cp37-cp37m-linux_armv7l.whl", hash = "sha256:614c427ff235d92f103e9189f0230197c8f2f817d0dd9fd078f5d2ea4d920d02"}, - {file = "grpcio_tools-1.44.0-cp37-cp37m-macosx_10_10_x86_64.whl", hash = "sha256:c13e0cb486cfa15320ddcd70452a4d736e6ce319c03d6b3c0c2513ec8d2748fb"}, - {file = "grpcio_tools-1.44.0-cp37-cp37m-manylinux2010_i686.whl", hash = "sha256:5ade6b13dc4e148f400c8f55a6ef0b14216a3371d7a9e559571d5981b6cec36b"}, - {file = "grpcio_tools-1.44.0-cp37-cp37m-manylinux2010_x86_64.whl", hash = "sha256:6138d2c7eec7ed57585bc58e2dbcb65635a2d574ac632abd29949d3e68936bab"}, - {file = "grpcio_tools-1.44.0-cp37-cp37m-manylinux_2_17_aarch64.whl", hash = "sha256:3d6c8548b199591757dbfe89ed14e23782d6079d6d201c6c314c72f4086883aa"}, - {file = "grpcio_tools-1.44.0-cp37-cp37m-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:b41c419829f01734d65958ba9b01b759061d8f7e0698f9612ba6b8837269f7a9"}, - {file = "grpcio_tools-1.44.0-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f9f0c5b4567631fec993826e694e83d86a972b3e2e9b05cb0c56839b0316d26c"}, - {file = "grpcio_tools-1.44.0-cp37-cp37m-win32.whl", hash = "sha256:3f0e1d1f3f5a6f0c9f8b5441819dbec831ce7e9ffe04768e4b0d965a95fbbe5e"}, - {file = "grpcio_tools-1.44.0-cp37-cp37m-win_amd64.whl", hash = "sha256:1f87fc86d0b4181b6b4da6ec6a29511dca000e6b5694fdd6bbf87d125128bc41"}, - {file = "grpcio_tools-1.44.0-cp38-cp38-linux_armv7l.whl", hash = "sha256:cb8baa1d4cea35ca662c24098377bdd9514c56f227da0e38b43cd9b8223bfcc6"}, - {file = "grpcio_tools-1.44.0-cp38-cp38-macosx_10_10_x86_64.whl", hash = "sha256:ea36a294f7c70fd2f2bfb5dcf08602006304aa65b055ebd4f7c709e2a89deba7"}, - {file = "grpcio_tools-1.44.0-cp38-cp38-manylinux2010_i686.whl", hash = "sha256:1972caf8f695b91edc6444134445798692fe71276f0cde7604d55e65179adf93"}, - {file = "grpcio_tools-1.44.0-cp38-cp38-manylinux2010_x86_64.whl", hash = "sha256:674fb8d9c0e2d75166c4385753962485b757897223fc92a19c9e513ab80b96f7"}, - {file = "grpcio_tools-1.44.0-cp38-cp38-manylinux_2_17_aarch64.whl", hash = "sha256:37045ba850d423cdacede77b266b127025818a5a36d80f1fd7a5a1614a6a0de5"}, - {file = "grpcio_tools-1.44.0-cp38-cp38-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:6cdf72947c6b0b03aa6dac06117a095947d02d43a5c6343051f4ce161fd0abcb"}, - {file = "grpcio_tools-1.44.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:69bfa6fc1515c202fe428ba9f99e2b2f947b01bafc15d868798235b2e2d36baa"}, - {file = "grpcio_tools-1.44.0-cp38-cp38-win32.whl", hash = "sha256:2c516124356476d9afa126acce10ce568733120afbd9ae17ee01d44b9da20a67"}, - {file = "grpcio_tools-1.44.0-cp38-cp38-win_amd64.whl", hash = "sha256:ceb6441c24176705c5ab056e65a8b330e107107c5a492ba094d1b862a136d15d"}, - {file = "grpcio_tools-1.44.0-cp39-cp39-linux_armv7l.whl", hash = "sha256:398eda759194d355eb09f7beabae6e4fb45b3877cf7efe505b49095fa4889cef"}, - {file = "grpcio_tools-1.44.0-cp39-cp39-macosx_10_10_x86_64.whl", hash = "sha256:a169bfd7a1fe8cc11472eeeeab3088b3c5d56caac12b2192a920b73adcbc974c"}, - {file = "grpcio_tools-1.44.0-cp39-cp39-manylinux2010_i686.whl", hash = "sha256:a58aaaec0d846d142edd8e794ebb80aa429abfd581f4493a60a603aac0c50ac8"}, - {file = "grpcio_tools-1.44.0-cp39-cp39-manylinux2010_x86_64.whl", hash = "sha256:c3253bee8b68fe422754faf0f286aa068861c926a7b11e4daeb44b9af767c7f1"}, - {file = "grpcio_tools-1.44.0-cp39-cp39-manylinux_2_17_aarch64.whl", hash = "sha256:3c0be60721ae1ba09c4f29572a145f412e561b9201e19428758893709827f472"}, - {file = "grpcio_tools-1.44.0-cp39-cp39-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:e44b9572c2226b85976e0d6054e22d7c59ebd6c9425ee71e5bc8910434aee3e1"}, - {file = "grpcio_tools-1.44.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7c04ec47905c4f6d6dad34d29f6ace652cc1ddc986f55aaa5559b72104c3f5cf"}, - {file = "grpcio_tools-1.44.0-cp39-cp39-win32.whl", hash = "sha256:fb8c7b9d24e2c4dc77e7800e83b68081729ac6094b781b2afdabf08af18c3b28"}, - {file = "grpcio_tools-1.44.0-cp39-cp39-win_amd64.whl", hash = "sha256:4eb93619c8cb3773fb899504e3e30a0dc79d3904fd7a84091d15552178e1e920"}, + {file = "grpcio-tools-1.45.0.tar.gz", hash = "sha256:a016cfc21e0d91b3b036d3d4f968d1fdea865dfa03524cb1fbeca84719fd45a2"}, + {file = "grpcio_tools-1.45.0-cp310-cp310-linux_armv7l.whl", hash = "sha256:0431410ba4463bdb03051a6279c040a1bae1d1b12d7dd533ecfba2462725cf11"}, + {file = "grpcio_tools-1.45.0-cp310-cp310-macosx_10_10_universal2.whl", hash = "sha256:52a801063894a85f719108b438b8e71f86ca8059c25824944867879a4e8f6d2c"}, + {file = "grpcio_tools-1.45.0-cp310-cp310-manylinux_2_17_aarch64.whl", hash = "sha256:451e54b490c5d0efcb0ad7a8f7e45ec3cf452de67ee017ccb2bd1e5e45571938"}, + {file = "grpcio_tools-1.45.0-cp310-cp310-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:047233beb9773f7da454711b3ec029233b494375db03f3fd2e759702b231c09f"}, + {file = "grpcio_tools-1.45.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:210ea758250b5bb4f986713c01dc200f63b122a181a228114906bb99e5822479"}, + {file = "grpcio_tools-1.45.0-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:e021b911fde2f86c3528f67f7937a41ef56195f637a7556409a4e88c81ab8f2d"}, + {file = "grpcio_tools-1.45.0-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:ad8a74b0626b3762eeddfef2a18944f7cb9ddd80db13997fb4587185c821b10e"}, + {file = "grpcio_tools-1.45.0-cp310-cp310-win32.whl", hash = "sha256:baceb0da2ada3ec4959beef208c3685d3274b0ecc59ac531658e0d35d8f67846"}, + {file = "grpcio_tools-1.45.0-cp310-cp310-win_amd64.whl", hash = "sha256:ee423b5ebd1a6a6fa8d2cd4861a5ee758036e4d08f6a9a5eebc4ec2380bd94ef"}, + {file = "grpcio_tools-1.45.0-cp36-cp36m-linux_armv7l.whl", hash = "sha256:e286083bcf32e7bc26b67c8fb8d59a385047cd1213e205a3f0eafee50c171cc4"}, + {file = "grpcio_tools-1.45.0-cp36-cp36m-macosx_10_10_x86_64.whl", hash = "sha256:f535902209809acf5d1de59e287dd43c81e76906d4e2e51f8068a544ecc84301"}, + {file = "grpcio_tools-1.45.0-cp36-cp36m-manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:40842f52243c0ada1d6262a625bca31dd217e12ef7e7b3dbccaabe289d8b24e5"}, + {file = "grpcio_tools-1.45.0-cp36-cp36m-manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:64ec376631be21e39a631b940dd833273fc709a19ad08d993089a7bb2a958dc0"}, + {file = "grpcio_tools-1.45.0-cp36-cp36m-manylinux_2_17_aarch64.whl", hash = "sha256:b7de099ae16938aeb7c9e0f5178b9ad2be500731847e3a168be7dbad25d70dee"}, + {file = "grpcio_tools-1.45.0-cp36-cp36m-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:bbee84e4fcaca03fbfb1b1defa7b226999d6fa468c72578ff900e46caf01a55b"}, + {file = "grpcio_tools-1.45.0-cp36-cp36m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:71a3beee3526b2aacbf19ad83a7737a1c9e4f8a1fad3768b644f9d8bf45f29df"}, + {file = "grpcio_tools-1.45.0-cp36-cp36m-musllinux_1_1_i686.whl", hash = "sha256:57e79e34ba8ff1d7594dd5556fbeb1ff7bb985a9f34b54da65ea6c617c02969b"}, + {file = "grpcio_tools-1.45.0-cp36-cp36m-musllinux_1_1_x86_64.whl", hash = "sha256:d8656dca6e4f729a77a156cea16141dd7206657bf303b67c157530c7e7741216"}, + {file = "grpcio_tools-1.45.0-cp36-cp36m-win32.whl", hash = "sha256:527aa1105cf2ef8e979ccbb08b0e80330cbec736b67da54d966fc9f3860d7145"}, + {file = "grpcio_tools-1.45.0-cp36-cp36m-win_amd64.whl", hash = "sha256:31bd8e8e5b383943e72b5fb8e157ee730aa6b52e8a15bb13035166e1b5b9c897"}, + {file = "grpcio_tools-1.45.0-cp37-cp37m-linux_armv7l.whl", hash = "sha256:8f64dd3098edcdc99a0ee9e680ae674a86f40f65c125a88a11610c28503844ec"}, + {file = "grpcio_tools-1.45.0-cp37-cp37m-macosx_10_10_x86_64.whl", hash = "sha256:e8808de2aac8c7b2938602cd121b37b3c44e1e80cadb4b48dc695f205ff71e2c"}, + {file = "grpcio_tools-1.45.0-cp37-cp37m-manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:ebb17cb82cd921b8950ddc080ba5ed9a3fc06e45942050f6127872bd6fc46325"}, + {file = "grpcio_tools-1.45.0-cp37-cp37m-manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:0c1a1f1a794046823aac6ae207746b503b26db992837e7b06cb4bed2dc8520ae"}, + {file = "grpcio_tools-1.45.0-cp37-cp37m-manylinux_2_17_aarch64.whl", hash = "sha256:8d9be3e3bf85820ce43ff00d800b6ad61448ab8c458c12c36696f76b81808aaa"}, + {file = "grpcio_tools-1.45.0-cp37-cp37m-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:319f4905e398558c9c0d508b685976b2728ff5c6629613debb6c153e49e5ad18"}, + {file = "grpcio_tools-1.45.0-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7db11a65e07410db1c31cbeb9afe344a6bd88a63dcd819557707ca7318478727"}, + {file = "grpcio_tools-1.45.0-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:477230d6d5054fc949928cbc1d50db54a5cece5d233b8ef3e0aebbf60939bdd8"}, + {file = "grpcio_tools-1.45.0-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:a33edaa319bafd7542105d25abc6d9a8a331d4684fb5886863d1c9a6cd47fa67"}, + {file = "grpcio_tools-1.45.0-cp37-cp37m-win32.whl", hash = "sha256:690b520660008687af9eb956981f6da2134f8ce299434a22314c00e9dac29fcb"}, + {file = "grpcio_tools-1.45.0-cp37-cp37m-win_amd64.whl", hash = "sha256:47c6f5c7d9ed33726ed6ed1630767a8e08e8d10497cba07ba9001b54a599d486"}, + {file = "grpcio_tools-1.45.0-cp38-cp38-linux_armv7l.whl", hash = "sha256:bfea11559bec0935b84174a2bb10ec67ca97367d71d11facbbf9bbf8f5693067"}, + {file = "grpcio_tools-1.45.0-cp38-cp38-macosx_10_10_x86_64.whl", hash = "sha256:36516f6f9957f6295d81766b1855be858055fc17cebcd4076471d697597cb2c6"}, + {file = "grpcio_tools-1.45.0-cp38-cp38-manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:1b4b1727cdfda8854089f03df2d2b2b0171243c54048ac1359dd89ab5c211180"}, + {file = "grpcio_tools-1.45.0-cp38-cp38-manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:b2425c9cbc1c400a4fd7adcefde7c524c46e7f42f3f2cb52a15399bc559d4fe0"}, + {file = "grpcio_tools-1.45.0-cp38-cp38-manylinux_2_17_aarch64.whl", hash = "sha256:1b4a5dcd433377cedb18cff3c79050c638ce7d6223de9ad9119157994558e37b"}, + {file = "grpcio_tools-1.45.0-cp38-cp38-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ed8306de5f8076d2fa0ba2a787c7fd1aecc4b901b2af1113acec21cea8178caf"}, + {file = "grpcio_tools-1.45.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:19ce25a2d573b2057af7d57aa7c80819db90cb92d20eafc8e8ae1448fe9941b1"}, + {file = "grpcio_tools-1.45.0-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:e3729ecd8bc42e783faba7243d315b1beb44021bc146afec0537791b47980878"}, + {file = "grpcio_tools-1.45.0-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:b7cf16c448e19b10f9fb13327d930925ef053bb21dcd858a20184d2a8f55ce18"}, + {file = "grpcio_tools-1.45.0-cp38-cp38-win32.whl", hash = "sha256:367dfa639abc4538843043ab2dd6bf5b0232ddc519418f1e1287e855e7cf27c4"}, + {file = "grpcio_tools-1.45.0-cp38-cp38-win_amd64.whl", hash = "sha256:115ae6a8df239987b662b228771ab9c1d4db3cc4db3da6d184a1b95bc9759d91"}, + {file = "grpcio_tools-1.45.0-cp39-cp39-linux_armv7l.whl", hash = "sha256:6e7b53a8a605f91e0f9584481b74b008f321ea22461f075eeaebaf98b2de372f"}, + {file = "grpcio_tools-1.45.0-cp39-cp39-macosx_10_10_x86_64.whl", hash = "sha256:ad49ad7f6f5ea305d92ce33f773f7d9a667742010d1ec02a1a0626b735cf57dd"}, + {file = "grpcio_tools-1.45.0-cp39-cp39-manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:713ffedf8c01dc34c1d69121c0b3421f557674681ffc0e004205d9bb0fc994b9"}, + {file = "grpcio_tools-1.45.0-cp39-cp39-manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:bf423863263933a98706e8a8b775c81d62e911222dbeb2b62ba60da815394ae2"}, + {file = "grpcio_tools-1.45.0-cp39-cp39-manylinux_2_17_aarch64.whl", hash = "sha256:5cfd3e7c082a3a01f65fdf3a3ab9168dea36102bf7326edfe03a1f592fe244e4"}, + {file = "grpcio_tools-1.45.0-cp39-cp39-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:b6437665cd46e4dd39343c69da4c18f761868c632793ce6c436942d1b33fd930"}, + {file = "grpcio_tools-1.45.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:79d951338e18c90f9e412cbe3e747530c94bd7c71963574e70cf7cdb7c113c01"}, + {file = "grpcio_tools-1.45.0-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:737d1c0e359b83f45b5d7170ea9bb08e5f90dd36126097b7a8e7ad62ade867be"}, + {file = "grpcio_tools-1.45.0-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:4b6e5c48eb28a215f9d6e76d646406d2505c1a5ae8864273960a73e5c09fe982"}, + {file = "grpcio_tools-1.45.0-cp39-cp39-win32.whl", hash = "sha256:63d66c90f816601385a085726eb678c6c872aed7911df4232d906fc240159c83"}, + {file = "grpcio_tools-1.45.0-cp39-cp39-win_amd64.whl", hash = "sha256:54dfd7d777664973b794b2fe585748f87f1066a4d6bb0af4f918b353b91bd434"}, ] grpclib = [ {file = "grpclib-0.4.2.tar.gz", hash = "sha256:ead080cb7d56d6a5e835aaf5255d1ef1dce475a7722566ea225f0188fce33b68"}, @@ -1574,8 +1608,8 @@ python-dateutil = [ {file = "python_dateutil-2.8.2-py2.py3-none-any.whl", hash = "sha256:961d03dc3453ebbc59dbdea9e4e11c5651520a876d0f4db161e8674aae935da9"}, ] pytz = [ - {file = "pytz-2021.3-py2.py3-none-any.whl", hash = "sha256:3672058bc3453457b622aab7a1c3bfd5ab0bdae451512f6cf25f64ed37f5b87c"}, - {file = "pytz-2021.3.tar.gz", hash = "sha256:acad2d8b20a1af07d4e4c9d2e9285c5ed9104354062f275f3fcd88dcef4f1326"}, + {file = "pytz-2022.1-py2.py3-none-any.whl", hash = "sha256:e68985985296d9a66a881eb3193b0906246245294a881e7c8afe623866ac6a5c"}, + {file = "pytz-2022.1.tar.gz", hash = "sha256:1e760e2fe6a8163bc0b3d9a19c4f84342afa0a2affebfaa84b01b978a02ecaa7"}, ] pyyaml = [ {file = "PyYAML-6.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:d4db7c7aef085872ef65a8fd7d6d09a14ae91f691dec3e87ee5ee0539d516f53"}, @@ -1616,6 +1650,10 @@ requests = [ {file = "requests-2.27.1-py2.py3-none-any.whl", hash = "sha256:f22fa1e554c9ddfd16e6e41ac79759e17be9e492b3587efa038054674760e72d"}, {file = "requests-2.27.1.tar.gz", hash = "sha256:68d7c56fd5a8999887728ef304a6d12edc7be74f1cfa47714fc8b414525c9a61"}, ] +setuptools = [ + {file = "setuptools-59.6.0-py3-none-any.whl", hash = "sha256:4ce92f1e1f8f01233ee9952c04f6b81d1e02939d6e1b488428154974a4d0783e"}, + {file = "setuptools-59.6.0.tar.gz", hash = "sha256:22c7348c6d2976a52632c67f7ab0cdf40147db7789f9aed18734643fe9cf3373"}, +] six = [ {file = "six-1.16.0-py2.py3-none-any.whl", hash = "sha256:8abb2f1d86890a2dfb989f9a77cfcfd3e47c2a354b01111771326f8aa26e0254"}, {file = "six-1.16.0.tar.gz", hash = "sha256:1e61c37477a1626458e36f7b1d82aa5c9b094fa4802892072e49de9c60c4c926"}, @@ -1669,8 +1707,8 @@ tomlkit = [ {file = "tomlkit-0.7.2.tar.gz", hash = "sha256:d7a454f319a7e9bd2e249f239168729327e4dd2d27b17dc68be264ad1ce36754"}, ] tox = [ - {file = "tox-3.24.5-py2.py3-none-any.whl", hash = "sha256:be3362472a33094bce26727f5f771ca0facf6dafa217f65875314e9a6600c95c"}, - {file = "tox-3.24.5.tar.gz", hash = "sha256:67e0e32c90e278251fea45b696d0fef3879089ccbe979b0c556d35d5a70e2993"}, + {file = "tox-3.25.0-py2.py3-none-any.whl", hash = "sha256:0805727eb4d6b049de304977dfc9ce315a1938e6619c3ab9f38682bb04662a5a"}, + {file = "tox-3.25.0.tar.gz", hash = "sha256:37888f3092aa4e9f835fc8cc6dadbaaa0782651c41ef359e3a5743fcb0308160"}, ] typed-ast = [ {file = "typed_ast-1.5.2-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:183b183b7771a508395d2cbffd6db67d6ad52958a5fdc99f450d954003900266"}, @@ -1707,12 +1745,12 @@ typing-extensions = [ {file = "typing_extensions-4.1.1.tar.gz", hash = "sha256:1a9462dcc3347a79b1f1c0271fbe79e844580bb598bafa1ed208b94da3cdcd42"}, ] urllib3 = [ - {file = "urllib3-1.26.8-py2.py3-none-any.whl", hash = "sha256:000ca7f471a233c2251c6c7023ee85305721bfdf18621ebff4fd17a8653427ed"}, - {file = "urllib3-1.26.8.tar.gz", hash = "sha256:0e7c33d9a63e7ddfcb86780aac87befc2fbddf46c58dbb487e0855f7ceec283c"}, + {file = "urllib3-1.26.9-py2.py3-none-any.whl", hash = "sha256:44ece4d53fb1706f667c9bd1c648f5469a2ec925fcf3a776667042d645472c14"}, + {file = "urllib3-1.26.9.tar.gz", hash = "sha256:aabaf16477806a5e1dd19aa41f8c2b7950dd3c746362d7e3223dbe6de6ac448e"}, ] virtualenv = [ - {file = "virtualenv-20.13.2-py2.py3-none-any.whl", hash = "sha256:e7b34c9474e6476ee208c43a4d9ac1510b041c68347eabfe9a9ea0c86aa0a46b"}, - {file = "virtualenv-20.13.2.tar.gz", hash = "sha256:01f5f80744d24a3743ce61858123488e91cb2dd1d3bdf92adaf1bba39ffdedf0"}, + {file = "virtualenv-20.14.1-py2.py3-none-any.whl", hash = "sha256:e617f16e25b42eb4f6e74096b9c9e37713cf10bf30168fb4a739f3fa8f898a3a"}, + {file = "virtualenv-20.14.1.tar.gz", hash = "sha256:ef589a79795589aada0c1c5b319486797c03b67ac3984c48c669c0e4f50df3a5"}, ] zipp = [ {file = "zipp-3.6.0-py3-none-any.whl", hash = "sha256:9fe5ea21568a0a70e50f273397638d39b03353731e6cbbb3fd8502a33fec40bc"}, diff --git a/pyproject.toml b/pyproject.toml index 093ad4ddf..4d226f346 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -13,12 +13,13 @@ packages = [ [tool.poetry.dependencies] python = ">=3.6.2,<4.0" -black = { version = ">=19.3b0", optional = true } -dataclasses = { version = "^0.7", python = ">=3.6, <3.7" } +black = { version = "^22.3.0", optional = true } +dataclasses = { version = "^0.6", python = ">=3.6, <3.7" } grpclib = "^0.4.1" jinja2 = { version = ">=2.11.2", optional = true } python-dateutil = "^2.8" isort = {version = "^5.10.1", optional = true} +typing-extensions = "^4.1.1" [tool.poetry.dev-dependencies] asv = "^0.4.2" From f168031df1899262be451207a0ef5e6922b5d30a Mon Sep 17 00:00:00 2001 From: James Hilton-Balfe Date: Fri, 15 Apr 2022 18:19:06 +0100 Subject: [PATCH 16/27] Add in something I forgot to include --- src/betterproto/__init__.py | 25 ++++++++++++------------- 1 file changed, 12 insertions(+), 13 deletions(-) diff --git a/src/betterproto/__init__.py b/src/betterproto/__init__.py index b074a0cb6..034595b27 100644 --- a/src/betterproto/__init__.py +++ b/src/betterproto/__init__.py @@ -853,20 +853,19 @@ def __bytes__(self) -> bytes: return bytes(output) # For compatibility with other libraries - def SerializeToString(self: T) -> bytes: - """ - Get the binary encoded Protobuf representation of this message instance. + SerializeToString = __bytes__ + """ + Get the binary encoded Protobuf representation of this message instance. - .. note:: - This is a method for compatibility with other libraries, - you should really use ``bytes(x)``. + .. note:: + This is a method for compatibility with other libraries, + you should really use ``bytes(x)``. - Returns - -------- - :class:`bytes` - The binary encoded Protobuf representation of this message instance - """ - return bytes(self) + Returns + -------- + :class:`bytes` + The binary encoded Protobuf representation of this message instance + """ @classmethod def _type_hint(cls, field_name: str) -> Type: @@ -883,7 +882,7 @@ def _cls_for(cls, field: dataclasses.Field, index: int = 0) -> Type: field_cls = cls._type_hint(field.name) args = getattr(field_cls, "__args__", None) if args and index >= 0: - field_cls = field_cls.__args__[index] + field_cls = args[index] return field_cls def _get_field_default(self, field_name: str) -> Any: From bfcf43e49fefd053bd5fa207c044e891bad69090 Mon Sep 17 00:00:00 2001 From: James Hilton-Balfe Date: Fri, 15 Apr 2022 18:37:50 +0100 Subject: [PATCH 17/27] Fix 3.6 --- src/betterproto/__init__.py | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/src/betterproto/__init__.py b/src/betterproto/__init__.py index 034595b27..c84129e64 100644 --- a/src/betterproto/__init__.py +++ b/src/betterproto/__init__.py @@ -659,9 +659,9 @@ def __post_init__(self) -> None: group_current[meta.group] = field_name # Now that all the defaults are set, reset it! - super().__setattr__("_serialized_on_wire", not all_sentinel) - super().__setattr__("_unknown_fields", b"") - super().__setattr__("_group_current", group_current) + object.__setattr__(self, "_serialized_on_wire", not all_sentinel) + object.__setattr__(self, "_unknown_fields", b"") + object.__setattr__(self, "_group_current", group_current) def __eq__(self, other) -> bool: if not isinstance(other, type(self)): @@ -897,12 +897,12 @@ def _get_field_default_gen(cls, field: dataclasses.Field) -> Any: origin = getattr(t, "__origin__", None) if origin is not None: - if origin is dict: + if origin in {dict, Dict}: # This is some kind of map (dict in Python). - return origin - elif origin is list: + return dict + elif origin is {list, List}: # This is some kind of list (repeated) field. - return origin + return list elif origin is Union and t.__args__[1] is type(None): # This is an optional field (either wrapped, or using proto3 # field presence). For setting the default we really don't care From 018ae7466177e79e39513c0458dc7ef34682e731 Mon Sep 17 00:00:00 2001 From: James Hilton-Balfe Date: Fri, 15 Apr 2022 18:39:54 +0100 Subject: [PATCH 18/27] Fix 3.6 properly --- src/betterproto/__init__.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/betterproto/__init__.py b/src/betterproto/__init__.py index c84129e64..f0b5e3594 100644 --- a/src/betterproto/__init__.py +++ b/src/betterproto/__init__.py @@ -881,7 +881,7 @@ def _cls_for(cls, field: dataclasses.Field, index: int = 0) -> Type: """Get the message class for a field from the type hints.""" field_cls = cls._type_hint(field.name) args = getattr(field_cls, "__args__", None) - if args and index >= 0: + if args: field_cls = args[index] return field_cls @@ -900,7 +900,7 @@ def _get_field_default_gen(cls, field: dataclasses.Field) -> Any: if origin in {dict, Dict}: # This is some kind of map (dict in Python). return dict - elif origin is {list, List}: + elif origin in {list, List}: # This is some kind of list (repeated) field. return list elif origin is Union and t.__args__[1] is type(None): From 0fa972ccbf9d5f3d6dfd5cf2c12482f5cf80c60a Mon Sep 17 00:00:00 2001 From: James Hilton-Balfe Date: Fri, 22 Apr 2022 18:01:50 +0100 Subject: [PATCH 19/27] Use hasattr(x, "__iter__") rather than isinstance(x, Iterable) and float(-inf) works --- src/betterproto/__init__.py | 41 +++++++++++++++++-------------------- 1 file changed, 19 insertions(+), 22 deletions(-) diff --git a/src/betterproto/__init__.py b/src/betterproto/__init__.py index f0b5e3594..28175c6bf 100644 --- a/src/betterproto/__init__.py +++ b/src/betterproto/__init__.py @@ -43,6 +43,22 @@ ) from .grpc.grpclib_client import ServiceStub +# Circular import workaround: google.protobuf depends on base classes defined above. +from .lib.google.protobuf import DoubleValue # noqa +from .lib.google.protobuf import ( + BoolValue, + BytesValue, + Duration, + EnumValue, + FloatValue, + Int32Value, + Int64Value, + StringValue, + Timestamp, + UInt32Value, + UInt64Value, +) + # Proto 3 data types TYPE_ENUM: Final = "enum" @@ -454,7 +470,7 @@ def _parse_float(value: Any) -> float: if value == INFINITY: return float("inf") if value == NEG_INFINITY: - return -float("inf") + return float("-inf") if value == NAN: return float("nan") return float(value) @@ -476,7 +492,7 @@ def _dump_float(value: float) -> Union[float, str]: """ if value == float("inf"): return INFINITY - if value == -float("inf"): + if value == float("-inf"): return NEG_INFINITY if value == float("nan"): return NAN @@ -1162,9 +1178,7 @@ def to_dict( elif meta.proto_type == TYPE_ENUM: if field_is_repeated: enum_class = field_types[field_name].__args__[0] - if isinstance(value, typing.Iterable) and not isinstance( - value, str - ): + if hasattr(value, "__iter__") and not isinstance(value, str): output[cased_name] = [enum_class(el).name for el in value] else: # transparently upgrade single value to repeated @@ -1362,23 +1376,6 @@ def which_one_of(message: Message, group_name: str) -> Tuple[str, Optional[Any]] return field_name, getattr(message, field_name) -# Circular import workaround: google.protobuf depends on base classes defined above. -from .lib.google.protobuf import ( # noqa - BoolValue, - BytesValue, - DoubleValue, - Duration, - EnumValue, - FloatValue, - Int32Value, - Int64Value, - StringValue, - Timestamp, - UInt32Value, - UInt64Value, -) - - class _Duration(Duration): def to_timedelta(self) -> timedelta: return timedelta(seconds=self.seconds, microseconds=self.nanos / 1e3) From eb2cbccac6b3b15aced2865fda19d3c5bfe5506c Mon Sep 17 00:00:00 2001 From: James Hilton-Balfe Date: Sat, 23 Apr 2022 11:27:19 +0100 Subject: [PATCH 20/27] remove typing import --- src/betterproto/__init__.py | 1 - 1 file changed, 1 deletion(-) diff --git a/src/betterproto/__init__.py b/src/betterproto/__init__.py index 28175c6bf..583de6043 100644 --- a/src/betterproto/__init__.py +++ b/src/betterproto/__init__.py @@ -4,7 +4,6 @@ import math import struct import sys -import typing import warnings from base64 import ( b64decode, From b313172d988fd6dd421df71d993386bab6917157 Mon Sep 17 00:00:00 2001 From: James Hilton-Balfe Date: Sat, 23 Apr 2022 11:29:23 +0100 Subject: [PATCH 21/27] Remove circular import --- src/betterproto/__init__.py | 33 +++++++++++++++++---------------- 1 file changed, 17 insertions(+), 16 deletions(-) diff --git a/src/betterproto/__init__.py b/src/betterproto/__init__.py index 583de6043..775116686 100644 --- a/src/betterproto/__init__.py +++ b/src/betterproto/__init__.py @@ -42,22 +42,6 @@ ) from .grpc.grpclib_client import ServiceStub -# Circular import workaround: google.protobuf depends on base classes defined above. -from .lib.google.protobuf import DoubleValue # noqa -from .lib.google.protobuf import ( - BoolValue, - BytesValue, - Duration, - EnumValue, - FloatValue, - Int32Value, - Int64Value, - StringValue, - Timestamp, - UInt32Value, - UInt64Value, -) - # Proto 3 data types TYPE_ENUM: Final = "enum" @@ -1375,6 +1359,23 @@ def which_one_of(message: Message, group_name: str) -> Tuple[str, Optional[Any]] return field_name, getattr(message, field_name) +# Circular import workaround: google.protobuf depends on base classes defined above. +from .lib.google.protobuf import ( + BoolValue, + BytesValue, + DoubleValue, + Duration, + EnumValue, + FloatValue, + Int32Value, + Int64Value, + StringValue, + Timestamp, + UInt32Value, + UInt64Value, +) + + class _Duration(Duration): def to_timedelta(self) -> timedelta: return timedelta(seconds=self.seconds, microseconds=self.nanos / 1e3) From 993904b2140c8630e350d79823d7060389828100 Mon Sep 17 00:00:00 2001 From: James Hilton-Balfe Date: Sat, 23 Apr 2022 11:33:21 +0100 Subject: [PATCH 22/27] poetry.lock again --- poetry.lock | 80 +++++++++++++++++++++-------------------------------- 1 file changed, 31 insertions(+), 49 deletions(-) diff --git a/poetry.lock b/poetry.lock index 97176d3be..61d0e4201 100644 --- a/poetry.lock +++ b/poetry.lock @@ -44,11 +44,11 @@ tests_no_zope = ["coverage[toml] (>=5.0.2)", "hypothesis", "pympler", "pytest (> [[package]] name = "babel" -version = "2.9.1" +version = "2.10.1" description = "Internationalization utilities" category = "dev" optional = false -python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" +python-versions = ">=3.6" [package.dependencies] pytz = ">=2015.7" @@ -270,7 +270,6 @@ python-versions = ">=3.6" [package.dependencies] grpcio = ">=1.45.0" protobuf = ">=3.5.0.post1,<4.0dev" -setuptools = "*" [[package]] name = "grpclib" @@ -413,7 +412,7 @@ name = "markupsafe" version = "2.0.1" description = "Safely add untrusted strings to HTML/XML markup." category = "main" -optional = true +optional = false python-versions = ">=3.6" [[package]] @@ -691,18 +690,6 @@ urllib3 = ">=1.21.1,<1.27" socks = ["PySocks (>=1.5.6,!=1.5.7)", "win-inet-pton"] use_chardet_on_py3 = ["chardet (>=3.0.2,<5)"] -[[package]] -name = "setuptools" -version = "59.6.0" -description = "Easily download, build, install, upgrade, and uninstall Python packages" -category = "dev" -optional = false -python-versions = ">=3.6" - -[package.extras] -docs = ["sphinx", "jaraco.packaging (>=8.2)", "rst.linker (>=1.9)", "jaraco.tidelift (>=1.4)", "pygments-github-lexers (==0.0.5)", "sphinx-inline-tabs", "sphinxcontrib-towncrier", "furo"] -testing = ["pytest (>=6)", "pytest-checkdocs (>=2.4)", "pytest-flake8", "pytest-cov", "pytest-enabler (>=1.0.1)", "mock", "flake8-2020", "virtualenv (>=13.0.0)", "pytest-virtualenv (>=1.2.7)", "wheel", "paver", "pip (>=19.1)", "jaraco.envs (>=2.2)", "pytest-xdist", "sphinx", "jaraco.path (>=3.2.0)", "pytest-black (>=0.3.7)", "pytest-mypy"] - [[package]] name = "six" version = "1.16.0" @@ -737,7 +724,6 @@ Jinja2 = ">=2.3" packaging = "*" Pygments = ">=2.0" requests = ">=2.5.0" -setuptools = "*" snowballstemmer = ">=1.1" sphinxcontrib-applehelp = "*" sphinxcontrib-devhelp = "*" @@ -885,7 +871,7 @@ testing = ["flaky (>=3.4.0)", "freezegun (>=0.3.11)", "pytest (>=4.0.0)", "pytes [[package]] name = "typed-ast" -version = "1.5.2" +version = "1.5.3" description = "a fork of Python 2 and 3 ast modules with type comment support" category = "main" optional = false @@ -958,7 +944,7 @@ compiler = ["black", "isort", "jinja2"] [metadata] lock-version = "1.1" python-versions = ">=3.6.2,<4.0" -content-hash = "9e32e1ce16b4bd6d929f9646288e038ca8e19627f11ba0c0472a41173e5e52ad" +content-hash = "55103cf74b0244e87d6aa3cca4b427d429ecd5dd023b96d31865df1f9d574c09" [metadata.files] alabaster = [ @@ -977,8 +963,8 @@ attrs = [ {file = "attrs-21.4.0.tar.gz", hash = "sha256:626ba8234211db98e869df76230a137c4c40a12d72445c45d5f5b716f076e2fd"}, ] babel = [ - {file = "Babel-2.9.1-py2.py3-none-any.whl", hash = "sha256:ab49e12b91d937cd11f0b67cb259a57ab4ad2b59ac7a3b41d6c06c0ac5b0def9"}, - {file = "Babel-2.9.1.tar.gz", hash = "sha256:bc0c176f9f6a994582230df350aa6e05ba2ebe4b3ac317eab29d9be5d2768da0"}, + {file = "Babel-2.10.1-py3-none-any.whl", hash = "sha256:3f349e85ad3154559ac4930c3918247d319f21910d5ce4b25d439ed8693b98d2"}, + {file = "Babel-2.10.1.tar.gz", hash = "sha256:98aeaca086133efb3e1e2aad0396987490c8425929ddbcfe0550184fdc54cd13"}, ] "backports.cached-property" = [ {file = "backports.cached-property-1.0.1.tar.gz", hash = "sha256:1a5ef1e750f8bc7d0204c807aae8e0f450c655be0cf4b30407a35fd4bb27186c"}, @@ -1650,10 +1636,6 @@ requests = [ {file = "requests-2.27.1-py2.py3-none-any.whl", hash = "sha256:f22fa1e554c9ddfd16e6e41ac79759e17be9e492b3587efa038054674760e72d"}, {file = "requests-2.27.1.tar.gz", hash = "sha256:68d7c56fd5a8999887728ef304a6d12edc7be74f1cfa47714fc8b414525c9a61"}, ] -setuptools = [ - {file = "setuptools-59.6.0-py3-none-any.whl", hash = "sha256:4ce92f1e1f8f01233ee9952c04f6b81d1e02939d6e1b488428154974a4d0783e"}, - {file = "setuptools-59.6.0.tar.gz", hash = "sha256:22c7348c6d2976a52632c67f7ab0cdf40147db7789f9aed18734643fe9cf3373"}, -] six = [ {file = "six-1.16.0-py2.py3-none-any.whl", hash = "sha256:8abb2f1d86890a2dfb989f9a77cfcfd3e47c2a354b01111771326f8aa26e0254"}, {file = "six-1.16.0.tar.gz", hash = "sha256:1e61c37477a1626458e36f7b1d82aa5c9b094fa4802892072e49de9c60c4c926"}, @@ -1711,30 +1693,30 @@ tox = [ {file = "tox-3.25.0.tar.gz", hash = "sha256:37888f3092aa4e9f835fc8cc6dadbaaa0782651c41ef359e3a5743fcb0308160"}, ] typed-ast = [ - {file = "typed_ast-1.5.2-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:183b183b7771a508395d2cbffd6db67d6ad52958a5fdc99f450d954003900266"}, - {file = "typed_ast-1.5.2-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:676d051b1da67a852c0447621fdd11c4e104827417bf216092ec3e286f7da596"}, - {file = "typed_ast-1.5.2-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:bc2542e83ac8399752bc16e0b35e038bdb659ba237f4222616b4e83fb9654985"}, - {file = "typed_ast-1.5.2-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:74cac86cc586db8dfda0ce65d8bcd2bf17b58668dfcc3652762f3ef0e6677e76"}, - {file = "typed_ast-1.5.2-cp310-cp310-win_amd64.whl", hash = "sha256:18fe320f354d6f9ad3147859b6e16649a0781425268c4dde596093177660e71a"}, - {file = "typed_ast-1.5.2-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:31d8c6b2df19a777bc8826770b872a45a1f30cfefcfd729491baa5237faae837"}, - {file = "typed_ast-1.5.2-cp36-cp36m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:963a0ccc9a4188524e6e6d39b12c9ca24cc2d45a71cfdd04a26d883c922b4b78"}, - {file = "typed_ast-1.5.2-cp36-cp36m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:0eb77764ea470f14fcbb89d51bc6bbf5e7623446ac4ed06cbd9ca9495b62e36e"}, - {file = "typed_ast-1.5.2-cp36-cp36m-win_amd64.whl", hash = "sha256:294a6903a4d087db805a7656989f613371915fc45c8cc0ddc5c5a0a8ad9bea4d"}, - {file = "typed_ast-1.5.2-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:26a432dc219c6b6f38be20a958cbe1abffcc5492821d7e27f08606ef99e0dffd"}, - {file = "typed_ast-1.5.2-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c7407cfcad702f0b6c0e0f3e7ab876cd1d2c13b14ce770e412c0c4b9728a0f88"}, - {file = "typed_ast-1.5.2-cp37-cp37m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:f30ddd110634c2d7534b2d4e0e22967e88366b0d356b24de87419cc4410c41b7"}, - {file = "typed_ast-1.5.2-cp37-cp37m-win_amd64.whl", hash = "sha256:8c08d6625bb258179b6e512f55ad20f9dfef019bbfbe3095247401e053a3ea30"}, - {file = "typed_ast-1.5.2-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:90904d889ab8e81a956f2c0935a523cc4e077c7847a836abee832f868d5c26a4"}, - {file = "typed_ast-1.5.2-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:bbebc31bf11762b63bf61aaae232becb41c5bf6b3461b80a4df7e791fabb3aca"}, - {file = "typed_ast-1.5.2-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c29dd9a3a9d259c9fa19d19738d021632d673f6ed9b35a739f48e5f807f264fb"}, - {file = "typed_ast-1.5.2-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:58ae097a325e9bb7a684572d20eb3e1809802c5c9ec7108e85da1eb6c1a3331b"}, - {file = "typed_ast-1.5.2-cp38-cp38-win_amd64.whl", hash = "sha256:da0a98d458010bf4fe535f2d1e367a2e2060e105978873c04c04212fb20543f7"}, - {file = "typed_ast-1.5.2-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:33b4a19ddc9fc551ebabca9765d54d04600c4a50eda13893dadf67ed81d9a098"}, - {file = "typed_ast-1.5.2-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:1098df9a0592dd4c8c0ccfc2e98931278a6c6c53cb3a3e2cf7e9ee3b06153344"}, - {file = "typed_ast-1.5.2-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:42c47c3b43fe3a39ddf8de1d40dbbfca60ac8530a36c9b198ea5b9efac75c09e"}, - {file = "typed_ast-1.5.2-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:f290617f74a610849bd8f5514e34ae3d09eafd521dceaa6cf68b3f4414266d4e"}, - {file = "typed_ast-1.5.2-cp39-cp39-win_amd64.whl", hash = "sha256:df05aa5b241e2e8045f5f4367a9f6187b09c4cdf8578bb219861c4e27c443db5"}, - {file = "typed_ast-1.5.2.tar.gz", hash = "sha256:525a2d4088e70a9f75b08b3f87a51acc9cde640e19cc523c7e41aa355564ae27"}, + {file = "typed_ast-1.5.3-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:9ad3b48cf2b487be140072fb86feff36801487d4abb7382bb1929aaac80638ea"}, + {file = "typed_ast-1.5.3-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:542cd732351ba8235f20faa0fc7398946fe1a57f2cdb289e5497e1e7f48cfedb"}, + {file = "typed_ast-1.5.3-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5dc2c11ae59003d4a26dda637222d9ae924387f96acae9492df663843aefad55"}, + {file = "typed_ast-1.5.3-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:fd5df1313915dbd70eaaa88c19030b441742e8b05e6103c631c83b75e0435ccc"}, + {file = "typed_ast-1.5.3-cp310-cp310-win_amd64.whl", hash = "sha256:e34f9b9e61333ecb0f7d79c21c28aa5cd63bec15cb7e1310d7d3da6ce886bc9b"}, + {file = "typed_ast-1.5.3-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:f818c5b81966d4728fec14caa338e30a70dfc3da577984d38f97816c4b3071ec"}, + {file = "typed_ast-1.5.3-cp36-cp36m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3042bfc9ca118712c9809201f55355479cfcdc17449f9f8db5e744e9625c6805"}, + {file = "typed_ast-1.5.3-cp36-cp36m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:4fff9fdcce59dc61ec1b317bdb319f8f4e6b69ebbe61193ae0a60c5f9333dc49"}, + {file = "typed_ast-1.5.3-cp36-cp36m-win_amd64.whl", hash = "sha256:8e0b8528838ffd426fea8d18bde4c73bcb4167218998cc8b9ee0a0f2bfe678a6"}, + {file = "typed_ast-1.5.3-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:8ef1d96ad05a291f5c36895d86d1375c0ee70595b90f6bb5f5fdbee749b146db"}, + {file = "typed_ast-1.5.3-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ed44e81517364cb5ba367e4f68fca01fba42a7a4690d40c07886586ac267d9b9"}, + {file = "typed_ast-1.5.3-cp37-cp37m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:f60d9de0d087454c91b3999a296d0c4558c1666771e3460621875021bf899af9"}, + {file = "typed_ast-1.5.3-cp37-cp37m-win_amd64.whl", hash = "sha256:9e237e74fd321a55c90eee9bc5d44be976979ad38a29bbd734148295c1ce7617"}, + {file = "typed_ast-1.5.3-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:ee852185964744987609b40aee1d2eb81502ae63ee8eef614558f96a56c1902d"}, + {file = "typed_ast-1.5.3-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:27e46cdd01d6c3a0dd8f728b6a938a6751f7bd324817501c15fb056307f918c6"}, + {file = "typed_ast-1.5.3-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d64dabc6336ddc10373922a146fa2256043b3b43e61f28961caec2a5207c56d5"}, + {file = "typed_ast-1.5.3-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:8cdf91b0c466a6c43f36c1964772918a2c04cfa83df8001ff32a89e357f8eb06"}, + {file = "typed_ast-1.5.3-cp38-cp38-win_amd64.whl", hash = "sha256:9cc9e1457e1feb06b075c8ef8aeb046a28ec351b1958b42c7c31c989c841403a"}, + {file = "typed_ast-1.5.3-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:e20d196815eeffb3d76b75223e8ffed124e65ee62097e4e73afb5fec6b993e7a"}, + {file = "typed_ast-1.5.3-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:37e5349d1d5de2f4763d534ccb26809d1c24b180a477659a12c4bde9dd677d74"}, + {file = "typed_ast-1.5.3-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c9f1a27592fac87daa4e3f16538713d705599b0a27dfe25518b80b6b017f0a6d"}, + {file = "typed_ast-1.5.3-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:8831479695eadc8b5ffed06fdfb3e424adc37962a75925668deeb503f446c0a3"}, + {file = "typed_ast-1.5.3-cp39-cp39-win_amd64.whl", hash = "sha256:20d5118e494478ef2d3a2702d964dae830aedd7b4d3b626d003eea526be18718"}, + {file = "typed_ast-1.5.3.tar.gz", hash = "sha256:27f25232e2dd0edfe1f019d6bfaaf11e86e657d9bdb7b0956db95f560cceb2b3"}, ] typing = [ {file = "typing-3.7.4.3-py2-none-any.whl", hash = "sha256:283d868f5071ab9ad873e5e52268d611e851c870a2ba354193026f2dfb29d8b5"}, From 9f51d158fd9f660c12d26207f4917751ebfb4361 Mon Sep 17 00:00:00 2001 From: James Hilton-Balfe Date: Sat, 23 Apr 2022 12:29:20 +0100 Subject: [PATCH 23/27] Don't change dataclasses version --- poetry.lock | 10 +++++----- pyproject.toml | 2 +- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/poetry.lock b/poetry.lock index 61d0e4201..73cb3a219 100644 --- a/poetry.lock +++ b/poetry.lock @@ -200,11 +200,11 @@ python-versions = ">=3.6" [[package]] name = "dataclasses" -version = "0.6" +version = "0.7" description = "A backport of the dataclasses module for Python 3.6" category = "main" optional = false -python-versions = "*" +python-versions = ">=3.6, <3.7" [[package]] name = "distlib" @@ -944,7 +944,7 @@ compiler = ["black", "isort", "jinja2"] [metadata] lock-version = "1.1" python-versions = ">=3.6.2,<4.0" -content-hash = "55103cf74b0244e87d6aa3cca4b427d429ecd5dd023b96d31865df1f9d574c09" +content-hash = "a0f218c6f1282445d0a68e2e308e98beb4667d087bce2bdf986a1cb8ce46a93f" [metadata.files] alabaster = [ @@ -1100,8 +1100,8 @@ cwcwidth = [ {file = "cwcwidth-0.1.5.tar.gz", hash = "sha256:2c840e7d85f6de45c45986b416d79312c91882e1121b78d4c347e49c4238c09d"}, ] dataclasses = [ - {file = "dataclasses-0.6-py3-none-any.whl", hash = "sha256:454a69d788c7fda44efd71e259be79577822f5e3f53f029a22d08004e951dc9f"}, - {file = "dataclasses-0.6.tar.gz", hash = "sha256:6988bd2b895eef432d562370bb707d540f32f7360ab13da45340101bc2307d84"}, + {file = "dataclasses-0.7-py3-none-any.whl", hash = "sha256:3459118f7ede7c8bea0fe795bff7c6c2ce287d01dd226202f7c9ebc0610a7836"}, + {file = "dataclasses-0.7.tar.gz", hash = "sha256:494a6dcae3b8bcf80848eea2ef64c0cc5cd307ffc263e17cdf42f3e5420808e6"}, ] distlib = [ {file = "distlib-0.3.4-py2.py3-none-any.whl", hash = "sha256:6564fe0a8f51e734df6333d08b8b94d4ea8ee6b99b5ed50613f731fd4089f34b"}, diff --git a/pyproject.toml b/pyproject.toml index 4d226f346..5db881238 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -14,7 +14,7 @@ packages = [ [tool.poetry.dependencies] python = ">=3.6.2,<4.0" black = { version = "^22.3.0", optional = true } -dataclasses = { version = "^0.6", python = ">=3.6, <3.7" } +dataclasses = { version = "^0.7", python = ">=3.6, <3.7" } grpclib = "^0.4.1" jinja2 = { version = ">=2.11.2", optional = true } python-dateutil = "^2.8" From 0b15d46529d19abff5695962af13b8fae1c535de Mon Sep 17 00:00:00 2001 From: James Hilton-Balfe Date: Sat, 23 Apr 2022 12:39:35 +0100 Subject: [PATCH 24/27] Fix some annotations --- src/betterproto/__init__.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/betterproto/__init__.py b/src/betterproto/__init__.py index 775116686..be191bef8 100644 --- a/src/betterproto/__init__.py +++ b/src/betterproto/__init__.py @@ -351,7 +351,7 @@ def from_string(cls, name: str) -> "Enum": def encode_varint(value: int) -> bytes: """Encodes a single varint value for serialization.""" - b: "List[int]" = [] + b: List[int] = [] if value < 0: value += 1 << 64 @@ -1212,7 +1212,7 @@ def from_dict(self: T, value: Dict[str, Any]) -> T: if meta.proto_type == TYPE_MESSAGE: v = getattr(self, field_name) - cls: type[Message] = self._betterproto.cls_by_field[field_name] + cls: Type[Message] = self._betterproto.cls_by_field[field_name] if isinstance(v, list): if cls is datetime: v = [isoparse(item) for item in value_] @@ -1252,7 +1252,7 @@ def from_dict(self: T, value: Dict[str, Any]) -> T: else b64decode(value_) ) elif meta.proto_type == TYPE_ENUM: - enum_cls: type[Enum] = self._betterproto.cls_by_field[field_name] + enum_cls: Type[Enum] = self._betterproto.cls_by_field[field_name] if isinstance(value_, list): v = [enum_cls.from_string(e) for e in value_] elif isinstance(value_, str): From f0447183fb3d9ab0d62f1ae575dafd1f5c74dbb3 Mon Sep 17 00:00:00 2001 From: James Hilton-Balfe Date: Thu, 16 Jun 2022 14:50:24 +0100 Subject: [PATCH 25/27] Make betterproto.Casing no longer an Enum. I remember initially being confused as to how this ever worked as enum members to my knowledge were never callable, however, as it turns out Casing.CAMEL and SNAKE never actually were enum members --- src/betterproto/__init__.py | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/src/betterproto/__init__.py b/src/betterproto/__init__.py index 65a02a9f7..6c364b185 100644 --- a/src/betterproto/__init__.py +++ b/src/betterproto/__init__.py @@ -32,7 +32,10 @@ ) from dateutil.parser import isoparse -from typing_extensions import Final +from typing_extensions import ( + Final, + final, +) from ._types import T from ._version import __version__ @@ -144,11 +147,14 @@ def datetime_default_gen() -> datetime: NAN: Final = "NaN" -class Casing(enum.Enum): +@final +class Casing: """Casing constants for serialization.""" - CAMEL = camel_case #: A camelCase sterilization function. - SNAKE = snake_case #: A snake_case sterilization function. + __slots__ = () + + CAMEL: Final = camel_case #: A camelCase sterilization function. + SNAKE: Final = snake_case #: A snake_case sterilization function. PLACEHOLDER: Final[Any] = object() From 64dbc67389bb71e747543c8861b740ddad58ab1c Mon Sep 17 00:00:00 2001 From: James Hilton-Balfe Date: Thu, 16 Jun 2022 14:52:33 +0100 Subject: [PATCH 26/27] Perform similar optimisations to from_pydict to from_dict --- src/betterproto/__init__.py | 57 ++++++++++++++++++------------------- 1 file changed, 27 insertions(+), 30 deletions(-) diff --git a/src/betterproto/__init__.py b/src/betterproto/__init__.py index 6c364b185..7dfe6e711 100644 --- a/src/betterproto/__init__.py +++ b/src/betterproto/__init__.py @@ -1215,7 +1215,6 @@ def from_dict(self: T, value: Dict[str, Any]) -> T: meta = self._betterproto.meta_by_field_name[field_name] except KeyError: continue - if value_ is None: continue @@ -1268,7 +1267,7 @@ def from_dict(self: T, value: Dict[str, Any]) -> T: v = enum_cls.from_string(value_) else: v = value_ - elif meta.proto_type in (TYPE_FLOAT, TYPE_DOUBLE): + elif meta.proto_type in {TYPE_FLOAT, TYPE_DOUBLE}: v = ( [_parse_float(n) for n in value_] if isinstance(value_, list) @@ -1417,39 +1416,37 @@ def from_pydict(self: T, value: Dict[str, Any]) -> T: The initialized message. """ self._serialized_on_wire = True - for key in value: + for key, value_ in value.items(): field_name = safe_snake_case(key) - meta = self._betterproto.meta_by_field_name.get(field_name) - if not meta: + try: + meta = self._betterproto.meta_by_field_name.get(field_name) + except KeyError: + continue + if value_ is None: continue - if value[key] is not None: - if meta.proto_type == TYPE_MESSAGE: - v = getattr(self, field_name) - if isinstance(v, list): - cls = self._betterproto.cls_by_field[field_name] - for item in value[key]: - v.append(cls().from_pydict(item)) - elif isinstance(v, datetime): - v = value[key] - elif isinstance(v, timedelta): - v = value[key] - elif meta.wraps: - v = value[key] - else: - # NOTE: `from_pydict` mutates the underlying message, so no - # assignment here is necessary. - v.from_pydict(value[key]) - elif meta.map_types and meta.map_types[1] == TYPE_MESSAGE: - v = getattr(self, field_name) - cls = self._betterproto.cls_by_field[f"{field_name}.value"] - for k in value[key]: - v[k] = cls().from_pydict(value[key][k]) + if meta.proto_type == TYPE_MESSAGE: + v = getattr(self, field_name) + if isinstance(v, list): + cls = self._betterproto.cls_by_field[field_name] + for item in value_: + v.append(cls().from_pydict(item)) + elif isinstance(v, datetime) or isinstance(v, timedelta) or meta.wraps: + v = value_ else: - v = value[key] + # NOTE: `from_pydict` mutates the underlying message, so no + # assignment here is necessary. + v.from_pydict(value_) + elif meta.map_types and meta.map_types[1] == TYPE_MESSAGE: + v = getattr(self, field_name) + cls = self._betterproto.cls_by_field[f"{field_name}.value"] + for k in value_: + v[k] = cls().from_pydict(value_[k]) + else: + v = value_ - if v is not None: - setattr(self, field_name, v) + if v is not None: + setattr(self, field_name, v) return self def is_set(self, name: str) -> bool: From bc67c5cb033a59c3d057741611743f6f6b7f0eae Mon Sep 17 00:00:00 2001 From: James Hilton-Balfe Date: Tue, 2 Aug 2022 18:41:37 +0100 Subject: [PATCH 27/27] Replace accidental .get call --- src/betterproto/__init__.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/betterproto/__init__.py b/src/betterproto/__init__.py index 7dfe6e711..24cd4ba78 100644 --- a/src/betterproto/__init__.py +++ b/src/betterproto/__init__.py @@ -1419,7 +1419,7 @@ def from_pydict(self: T, value: Dict[str, Any]) -> T: for key, value_ in value.items(): field_name = safe_snake_case(key) try: - meta = self._betterproto.meta_by_field_name.get(field_name) + meta = self._betterproto.meta_by_field_name[field_name] except KeyError: continue if value_ is None: