protobuf API¶
protobuf
¶
Zero-dependency proto3 encoder/decoder using Python dataclass schemas.
Part of zerodep: https://github.com/Oaklight/zerodep Copyright (c) 2026 Peng Ding. MIT License.
Encode and decode Protocol Buffers (proto3) wire format using plain Python
dataclasses as message schemas. No protoc compiler, no .proto files,
no C extensions — just stdlib + type annotations.
Basic usage::
from protobuf import message, field, int32, repeated
@message
class Person:
name: str = field(1)
id: int32 = field(2)
emails: repeated[str] = field(3)
data = Person(name="Alice", id=123, emails=["a@b.com"]).serialize()
person = Person.parse(data)
print(person.to_dict())
Scalar type aliases::
int32, int64, uint32, uint64 # varint
sint32, sint64 # varint + ZigZag
fixed32, sfixed32, float32 # 32-bit fixed
fixed64, sfixed64, double # 64-bit fixed
bool_ # varint (0/1)
Composite fields::
repeated[int32] # packed repeated scalars
map_field[str, int32] # map<string, int32>
Proto3 semantics: - All fields are optional with zero-value defaults. - Fields at their default value are NOT serialized. - Unknown fields are preserved across parse → serialize round-trips.
WireType
¶
ScalarType
¶
Bases: IntEnum
Identifies the proto3 scalar encoding strategy.
Source code in protobuf/protobuf.py
ProtoScalar
dataclass
¶
Annotated marker carrying proto wire-type metadata for a scalar field.
Placed inside Annotated[base_type, ProtoScalar(...)] to tell the
encoder/decoder how to serialize the value on the wire.
Source code in protobuf/protobuf.py
Repeated
dataclass
¶
Annotated marker for repeated fields.
repeated[int32] expands to
Annotated[list[int], Repeated(...), ProtoScalar(...)].
Source code in protobuf/protobuf.py
MapField
dataclass
¶
Annotated marker for map<K, V> fields.
map_field[str, int32] expands to Annotated[dict[str, int], MapField(...)].
Source code in protobuf/protobuf.py
OneofGroup
dataclass
¶
repeated
¶
Subscriptable type alias for repeated proto fields.
Usage: emails: repeated[str] = field(3)
map_field
¶
Subscriptable type alias for map proto fields.
Usage: attrs: map_field[str, int32] = field(5)
FieldKind
¶
Bases: IntEnum
Categories for how a field is encoded on the wire.
Source code in protobuf/protobuf.py
FieldInfo
dataclass
¶
Resolved metadata for a single proto field.
Source code in protobuf/protobuf.py
encode_varint(value)
¶
Encode an unsigned integer as a varint.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
value
|
int
|
Non-negative integer to encode. |
required |
Returns:
| Type | Description |
|---|---|
bytes
|
Varint-encoded bytes. |
Source code in protobuf/protobuf.py
decode_varint(data, pos)
¶
Decode a varint from data starting at pos.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
data
|
bytes | bytearray | memoryview
|
Buffer to read from. |
required |
pos
|
int
|
Start offset. |
required |
Returns:
| Type | Description |
|---|---|
tuple[int, int]
|
Tuple of (decoded value, new position after varint). |
Raises:
| Type | Description |
|---|---|
ValueError
|
If the varint is malformed or exceeds 10 bytes. |
Source code in protobuf/protobuf.py
zigzag_encode(value)
¶
ZigZag-encode a signed integer.
Maps signed integers to unsigned: 0→0, -1→1, 1→2, -2→3, …
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
value
|
int
|
Signed integer. |
required |
Returns:
| Type | Description |
|---|---|
int
|
ZigZag-encoded unsigned integer. |
Source code in protobuf/protobuf.py
zigzag_decode(value)
¶
ZigZag-decode an unsigned integer back to signed.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
value
|
int
|
ZigZag-encoded unsigned integer. |
required |
Returns:
| Type | Description |
|---|---|
int
|
Original signed integer. |
make_tag(field_number, wire_type)
¶
Pack a field number and wire type into a tag varint.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
field_number
|
int
|
Proto field number (1–536870911). |
required |
wire_type
|
int
|
Wire type (0–5). |
required |
Returns:
| Type | Description |
|---|---|
bytes
|
Varint-encoded tag bytes. |
Source code in protobuf/protobuf.py
decode_tag(data, pos)
¶
Decode a tag varint into field number and wire type.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
data
|
bytes | bytearray | memoryview
|
Buffer. |
required |
pos
|
int
|
Start offset. |
required |
Returns:
| Type | Description |
|---|---|
tuple[int, int, int]
|
Tuple of (field_number, wire_type, new position). |
Source code in protobuf/protobuf.py
encode_fixed32(value)
¶
decode_fixed32(data, pos)
¶
Decode a 32-bit little-endian unsigned integer.
Source code in protobuf/protobuf.py
encode_sfixed32(value)
¶
decode_sfixed32(data, pos)
¶
Decode a signed 32-bit little-endian integer.
Source code in protobuf/protobuf.py
encode_fixed64(value)
¶
decode_fixed64(data, pos)
¶
Decode a 64-bit little-endian unsigned integer.
Source code in protobuf/protobuf.py
encode_sfixed64(value)
¶
decode_sfixed64(data, pos)
¶
Decode a signed 64-bit little-endian integer.
Source code in protobuf/protobuf.py
encode_float(value)
¶
decode_float(data, pos)
¶
Decode a 32-bit float.
Source code in protobuf/protobuf.py
encode_double(value)
¶
decode_double(data, pos)
¶
Decode a 64-bit double.
Source code in protobuf/protobuf.py
oneof(group_name)
¶
Create a oneof group marker for use in field metadata.
Usage::
@message
class Msg:
text: str = field(1, oneof="body")
image: bytes = field(2, oneof="body")
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
group_name
|
str
|
Name of the oneof group. |
required |
Returns:
| Type | Description |
|---|---|
OneofGroup
|
OneofGroup marker. |
Source code in protobuf/protobuf.py
field(number, *, default=dataclasses.MISSING, default_factory=dataclasses.MISSING, oneof=None)
¶
Define a proto field with its field number.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
number
|
int
|
Proto field number (must be >= 1). |
required |
default
|
Any
|
Default value for the field. |
MISSING
|
default_factory
|
Any
|
Factory for mutable default values. |
MISSING
|
oneof
|
str | None
|
Optional oneof group name. |
None
|
Returns:
| Type | Description |
|---|---|
Any
|
A |
Source code in protobuf/protobuf.py
message(cls)
¶
Decorator that turns a class into a proto3 message.
Applies @dataclass (if not already applied) and injects proto3
serialize(), parse(), to_dict(), from_dict() methods.
Usage::
@message
class Person:
name: str = field(1)
id: int32 = field(2)
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
cls
|
type
|
The class to decorate. |
required |
Returns:
| Type | Description |
|---|---|
type
|
The decorated class with proto3 capabilities. |