import ctypes C_UINT8 = ctypes.c_uint8 C_UINT32 = ctypes.c_uint32 class BitFieldStruct(ctypes.LittleEndianStructure): _fields_ = [ ("long_field", C_UINT32, 29), ("short_field_0", C_UINT8, 1), ("short_field_1", C_UINT8, 1), ("short_field_2", C_UINT8, 1), ] class BitField(ctypes.Union): _anonymous_ = ("fields",) _fields_ = [ ("fields", BitFieldStruct), ("as32bit", C_UINT32) ] def test_bit_field_union(): f = BitField() f.as32bit = int.from_bytes([255, 255, 255, 255], byteorder='little') assert f.long_field == int.from_bytes([255, 255, 255, 31], byteorder='little') assert f.short_field_0 == 1 assert f.short_field_1 == 1 assert f.short_field_2 == 1 test_bit_field_union() # Equivalent C -> https://rextester.com/FWV78514 # #include # #include # # # # union BitFieldUnion { # struct { # uint32_t long_field : 29; # uint8_t short_field_0 : 1; # uint8_t short_field_1 : 1; # uint8_t short_field_2 : 1; # }; # uint32_t as32bit; # }; # # int main(void) { # # union BitFieldUnion bf; # bf.as32bit = 4294967295; # printf("long_field is %d\n", bf.long_field); # printf("short_field_0 is %d\n", bf.short_field_0); # printf("short_field_1 is %d\n", bf.short_field_1); # printf("short_field_2 is %d\n", bf.short_field_2); # # }