Skip to content

Commit ca16b6e

Browse files
authored
Various micro-optimizations (#139)
1 parent 16d554d commit ca16b6e

File tree

1 file changed

+14
-20
lines changed

1 file changed

+14
-20
lines changed

src/betterproto/__init__.py

Lines changed: 14 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
import json
55
import struct
66
import sys
7-
import warnings
7+
import typing
88
from abc import ABC
99
from base64 import b64decode, b64encode
1010
from datetime import datetime, timedelta, timezone
@@ -22,8 +22,6 @@
2222
get_type_hints,
2323
)
2424

25-
import typing
26-
2725
from ._types import T
2826
from .casing import camel_case, safe_snake_case, snake_case
2927
from .grpc.grpclib_client import ServiceStub
@@ -126,11 +124,7 @@ class Casing(enum.Enum):
126124
SNAKE = snake_case
127125

128126

129-
class _PLACEHOLDER:
130-
pass
131-
132-
133-
PLACEHOLDER: Any = _PLACEHOLDER()
127+
PLACEHOLDER: Any = object()
134128

135129

136130
@dataclasses.dataclass(frozen=True)
@@ -261,7 +255,7 @@ class Enum(enum.IntEnum):
261255
def from_string(cls, name: str) -> int:
262256
"""Return the value which corresponds to the string name."""
263257
try:
264-
return cls.__members__[name]
258+
return cls._member_map_[name]
265259
except KeyError as e:
266260
raise ValueError(f"Unknown value {name} for enum {cls.__name__}") from e
267261

@@ -349,7 +343,7 @@ def _serialize_single(
349343
"""Serializes a single field and value."""
350344
value = _preprocess_single(proto_type, wraps, value)
351345

352-
output = b""
346+
output = bytearray()
353347
if proto_type in WIRE_VARINT_TYPES:
354348
key = encode_varint(field_number << 3)
355349
output += key + value
@@ -366,10 +360,10 @@ def _serialize_single(
366360
else:
367361
raise NotImplementedError(proto_type)
368362

369-
return output
363+
return bytes(output)
370364

371365

372-
def decode_varint(buffer: bytes, pos: int, signed: bool = False) -> Tuple[int, int]:
366+
def decode_varint(buffer: bytes, pos: int) -> Tuple[int, int]:
373367
"""
374368
Decode a single varint value from a byte buffer. Returns the value and the
375369
new position in the buffer.
@@ -513,7 +507,7 @@ def __post_init__(self) -> None:
513507
all_sentinel = True
514508

515509
# Set current field of each group after `__init__` has already been run.
516-
group_current: Dict[str, str] = {}
510+
group_current: Dict[str, Optional[str]] = {}
517511
for field_name, meta in self._betterproto.meta_by_field_name.items():
518512

519513
if meta.group:
@@ -571,7 +565,7 @@ def __bytes__(self) -> bytes:
571565
"""
572566
Get the binary encoded Protobuf representation of this instance.
573567
"""
574-
output = b""
568+
output = bytearray()
575569
for field_name, meta in self._betterproto.meta_by_field_name.items():
576570
value = getattr(self, field_name)
577571

@@ -609,7 +603,7 @@ def __bytes__(self) -> bytes:
609603
# Packed lists look like a length-delimited field. First,
610604
# preprocess/encode each value into a buffer and then
611605
# treat it like a field of raw bytes.
612-
buf = b""
606+
buf = bytearray()
613607
for item in value:
614608
buf += _preprocess_single(meta.proto_type, "", item)
615609
output += _serialize_single(meta.number, TYPE_BYTES, buf)
@@ -644,7 +638,8 @@ def __bytes__(self) -> bytes:
644638
wraps=meta.wraps or "",
645639
)
646640

647-
return output + self._unknown_fields
641+
output += self._unknown_fields
642+
return bytes(output)
648643

649644
# For compatibility with other libraries
650645
SerializeToString = __bytes__
@@ -754,14 +749,14 @@ def parse(self: T, data: bytes) -> T:
754749
"""
755750
# Got some data over the wire
756751
self._serialized_on_wire = True
757-
752+
proto_meta = self._betterproto
758753
for parsed in parse_fields(data):
759-
field_name = self._betterproto.field_name_by_number.get(parsed.number)
754+
field_name = proto_meta.field_name_by_number.get(parsed.number)
760755
if not field_name:
761756
self._unknown_fields += parsed.raw
762757
continue
763758

764-
meta = self._betterproto.meta_by_field_name[field_name]
759+
meta = proto_meta.meta_by_field_name[field_name]
765760

766761
value: Any
767762
if parsed.wire_type == WIRE_LEN_DELIM and meta.proto_type in PACKED_TYPES:
@@ -907,7 +902,6 @@ def from_dict(self: T, value: dict) -> T:
907902
returns the instance itself and is therefore assignable and chainable.
908903
"""
909904
self._serialized_on_wire = True
910-
fields_by_name = {f.name: f for f in dataclasses.fields(self)}
911905
for key in value:
912906
field_name = safe_snake_case(key)
913907
meta = self._betterproto.meta_by_field_name.get(field_name)

0 commit comments

Comments
 (0)