Consider I have the following struct:
import ctypes
class MyStruct(ctypes.BigEndianStructure):
# ! These typehints are added so that the IDE recognizes the fields of the Structure
field_size1: ctypes.c_uint8
field_size7: ctypes.c_uint8
field_size8: ctypes.c_uint8
_pack_ = 1
_fields_ = [
("field_size1", ctypes.c_uint8, 1),
("field_size7", ctypes.c_uint8, 7),
("field_size8", ctypes.c_uint8, 8),
]
I am able to assign the bits in this struct from Python types and get the bytes I expect.
s = MyStruct()
s.field_size1 = 1
s.field_size7 = 2
s.field_size8 = 3
I get the mypy linting error:
Incompatible types in assignment (expression has type "int", variable has type "c_uint8") Mypy(assignment)
However, if I try to use the ctype, the program crashes (ie the message below isn't printed):
s = MyStruct()
s.field_size1 = ctypes.c_uint8(1)
print("completed")
Which is what I believe I would expect. Trying to shove the 8bits into a 1bit length wouldn't make sense.
Is there a correct way to use the ctypes types when assigning bitfields to keep both Python and mypy happy without 'type ignores'
Thanks to @Mark Tolonen
I was able to better understand my problem and come up with this answer.
These
ctypes.Structureobjects automatically handle the conversion to native Python types.With the original example
My confusion stemmed from my actual use case that involved Arrays, as these do not natively get converted. Hence when I was working with my original application I had naively also applied the sample logic to arrays to the other fields.
Now
Now how best to type hint an array is the question I would need to answer.
This also is as straightforward as direct assignment with a tuple, and tuples can have a specific length in the type hint: