Type System¶
PDC Struct provides fixed-width integer types that ensure precise control over binary serialization. These types guarantee specific byte sizes regardless of platform, making them essential for C interoperability and cross-platform protocols.
Overview¶
While Python's built-in int type has arbitrary precision, binary protocols and C structs require fixed-width integers. PDC Struct provides these types with built-in validation:
| Type | Size | Range | Struct Format |
|---|---|---|---|
Int8 |
1 byte | -128 to 127 | b |
UInt8 |
1 byte | 0 to 255 | B |
Int16 |
2 bytes | -32,768 to 32,767 | h |
UInt16 |
2 bytes | 0 to 65,535 | H |
Usage¶
In StructModel Fields¶
from pdc_struct import StructModel, StructConfig, StructMode
from pdc_struct.c_types import Int8, UInt8, Int16, UInt16
class SensorReading(StructModel):
sensor_id: UInt8 # 0-255
temperature: Int16 # -32768 to 32767 (e.g., hundredths of degrees)
humidity: UInt8 # 0-255 (percentage)
status_code: Int8 # -128 to 127
struct_config = StructConfig(mode=StructMode.C_COMPATIBLE)
# Values are validated on creation
reading = SensorReading(
sensor_id=42,
temperature=-1050, # -10.50 degrees
humidity=65,
status_code=-1
)
Direct Instantiation¶
These types can be used directly and behave like regular integers:
from pdc_struct.c_types import UInt8, Int16
# Create instances
value = UInt8(255)
temp = Int16(-1000)
# Standard integer operations work
result = value + 1 # Returns regular int (256)
doubled = Int16(temp * 2) # Wrap back in Int16 for validation
# Validation on creation
try:
bad_value = UInt8(256) # Raises ValueError
except ValueError as e:
print(e) # "UInt8 value must be between 0 and 255"
Comparison with Plain int¶
When you use plain int in a StructModel, it serializes as a platform-dependent long integer (typically 8 bytes on 64-bit systems). Fixed-width types give you explicit control:
class WithPlainInt(StructModel):
value: int # 8 bytes (platform-dependent)
class WithFixedWidth(StructModel):
value: UInt16 # Always exactly 2 bytes
Validation Behavior¶
All fixed-width types validate their values at construction time:
from pdc_struct.c_types import Int8, UInt8
# Range validation
UInt8(-1) # ValueError: UInt8 value must be between 0 and 255
Int8(128) # ValueError: Int8 value must be between -128 and 127
# Type validation
UInt8("10") # TypeError: UInt8 requires an integer value
Int16(3.14) # TypeError: Int16 requires an integer value
Pydantic will also validate these types when used as model fields, providing detailed error messages.
C Equivalent Types¶
These types correspond to standard C integer types:
| PDC Struct | C Type | stdint.h |
|---|---|---|
Int8 |
signed char |
int8_t |
UInt8 |
unsigned char |
uint8_t |
Int16 |
short |
int16_t |
UInt16 |
unsigned short |
uint16_t |
Other Supported Types¶
Beyond fixed-width integers, StructModel supports these Python types automatically:
| Python Type | Serialization | Notes |
|---|---|---|
int |
8-byte signed | Platform long |
float |
8-byte double | IEEE 754 |
bool |
1 byte | 0 or 1 |
str |
Null-terminated | Requires max_length |
bytes |
Fixed-length | Requires max_length |
Enum / IntEnum |
Varies | Based on value type |
IPv4Address |
4 bytes | Network byte order |
UUID |
16 bytes | Binary format |
StructModel |
Nested | Recursive packing |
BitFieldModel |
1/2/4 bytes | Based on bit_width |
Class Reference¶
Int8
¶
Bases: int
8-bit signed integer (-128 to 127).
Equivalent to C's int8_t or signed char. Serializes to exactly 1 byte.
Use for small signed values where memory efficiency matters.
Example
from pdc_struct import StructModel, StructConfig, StructMode from pdc_struct.c_types import Int8
class Temperature(StructModel): ... celsius: Int8 # -128 to 127 degrees ... struct_config = StructConfig(mode=StructMode.C_COMPATIBLE)
reading = Temperature(celsius=-10) len(reading.to_bytes()) 1
Source code in pdc_struct/c_types.py
__get_pydantic_core_schema__(_source_type, _handler)
classmethod
¶
UInt8
¶
Bases: int
8-bit unsigned integer (0 to 255).
Equivalent to C's uint8_t or unsigned char. Serializes to exactly 1 byte.
Commonly used for byte values, flags, and small counters.
Example
from pdc_struct import StructModel, StructConfig, StructMode from pdc_struct.c_types import UInt8
class Pixel(StructModel): ... r: UInt8 ... g: UInt8 ... b: UInt8 ... struct_config = StructConfig(mode=StructMode.C_COMPATIBLE)
pixel = Pixel(r=255, g=128, b=0) pixel.to_bytes() b'\xff\x80\x00'
Source code in pdc_struct/c_types.py
__get_pydantic_core_schema__(_source_type, _handler)
classmethod
¶
Int16
¶
Bases: int
16-bit signed integer (-32,768 to 32,767).
Equivalent to C's int16_t or short. Serializes to exactly 2 bytes.
Use for medium-range signed values like audio samples or relative coordinates.
Example
from pdc_struct import StructModel, StructConfig, StructMode, ByteOrder from pdc_struct.c_types import Int16
class AudioSample(StructModel): ... left: Int16 ... right: Int16 ... struct_config = StructConfig( ... mode=StructMode.C_COMPATIBLE, ... byte_order=ByteOrder.LITTLE_ENDIAN ... )
sample = AudioSample(left=-16384, right=16383) len(sample.to_bytes()) 4
Source code in pdc_struct/c_types.py
__get_pydantic_core_schema__(_source_type, _handler)
classmethod
¶
Pydantic validation schema.
UInt16
¶
Bases: int
16-bit unsigned integer (0 to 65,535).
Equivalent to C's uint16_t or unsigned short. Serializes to exactly 2 bytes.
Commonly used for port numbers, lengths, and medium-range counters.
Example
from pdc_struct import StructModel, StructConfig, StructMode, ByteOrder from pdc_struct.c_types import UInt16
class NetworkHeader(StructModel): ... source_port: UInt16 ... dest_port: UInt16 ... length: UInt16 ... struct_config = StructConfig( ... mode=StructMode.C_COMPATIBLE, ... byte_order=ByteOrder.BIG_ENDIAN # Network byte order ... )
header = NetworkHeader(source_port=8080, dest_port=443, length=100) header.to_bytes() b'\x1f\x90\x01\xbb\x00d'
Source code in pdc_struct/c_types.py
__get_pydantic_core_schema__(_source_type, _handler)
classmethod
¶
Pydantic validation schema.
See Also¶
StructModel- Using types in struct definitions- Type System Guide - Detailed type usage patterns
- C Interoperability - Working with C code