Skip to the content.

uctypes — typed memory access

import uctypes

Define C-like struct layouts on top of bytes / bytearray / memoryview. Useful for parsing on-disk DOS structures (FAT boot sectors, MZ EXE headers, etc.) without writing pack/unpack formats by hand.

Concepts

A struct definition is a Python dict describing field names → offset-and-type pairs. Pass it + a byte buffer + an endian to uctypes.struct() and you get back an object whose attributes read/write through to the buffer.

Field type encodings

The type encoding combines the size class with the offset.

Encoding Width
uctypes.UINT8 1 byte
uctypes.INT8 1 byte (signed)
uctypes.UINT16 2 bytes
uctypes.INT16 2 bytes (signed)
uctypes.UINT32 4 bytes
uctypes.INT32 4 bytes (signed)
uctypes.UINT64 8 bytes
uctypes.INT64 8 bytes (signed)
uctypes.FLOAT32 4 bytes
uctypes.FLOAT64 8 bytes
uctypes.ARRAY + n array of n elems
uctypes.PTR pointer

Endian: uctypes.LITTLE_ENDIAN, uctypes.BIG_ENDIAN, uctypes.NATIVE.

Example: MZ EXE header

import uctypes

MZ_DESC = {
    'magic':           0  | uctypes.ARRAY | (2 << uctypes.ARRAY_SIZE_BITS) | uctypes.UINT8,
    'bytes_in_last':   2  | uctypes.UINT16,
    'pages':           4  | uctypes.UINT16,
    'reloc_count':     6  | uctypes.UINT16,
    'header_paras':    8  | uctypes.UINT16,
    'min_alloc':      10  | uctypes.UINT16,
    'max_alloc':      12  | uctypes.UINT16,
    'init_ss':        14  | uctypes.UINT16,
    'init_sp':        16  | uctypes.UINT16,
    'checksum':       18  | uctypes.UINT16,
    'init_ip':        20  | uctypes.UINT16,
    'init_cs':        22  | uctypes.UINT16,
    'reloc_offset':   24  | uctypes.UINT16,
    'overlay':        26  | uctypes.UINT16,
}

with open('MP.EXE', 'rb') as f:
    buf = f.read(28)

hdr = uctypes.struct(uctypes.addressof(buf), MZ_DESC, uctypes.LITTLE_ENDIAN)
print('magic:', bytes(hdr.magic))     # b'MZ'
print('pages:', hdr.pages)
print('CS:IP at start:', hex(hdr.init_cs), hex(hdr.init_ip))

The struct shape uses MicroPython’s compact representation — each field is offset | type. For nested structures and arrays, the upstream uctypes guide has the full layout grammar.

Use cases on DOS

For one-off parsing the struct module is usually simpler; uctypes shines when the same struct definition is reused many times against in-place memory.


Credit: MicroPython uctypes docs (MIT).