I have the following python snippet that is generating MyPy "problems" (in vscode).
my_struct = MyStruct()
#! set mutable flag to true to place data in our object.
fcntl.ioctl( dev_hand.fileno(), my_ioctl_id, my_struct, True )
The error is:
Argument 3 to "ioctl" has incompatible type "my_struct"; expected "Union[int, str]"
MyStruct is a ctypes structure. All the examples for using ioctl() with ctypes structures show passing the instance to ioctl(). Indeed this does work, except now MyPy is complaining.
I'd prefer not to convert to bytes and manually pack/unpack with the struct module (which I presume is one solution).
I'm using Python 3.7.3 on Linux (Debian Buster), with mypy 0.782
Thanks, Brendan.
NOTE: I forgot to mention that my code is targeting Python 2.7, as it is legacy from a Debian Jessie target system. I am using the --py2 switch for mypy (which must run on Python 3).
The ioctl() function has the following signature, which seems to come from the vscode server (remote ssh) ms-python .... typeshed/stdlib/3/fcntl.pyi`
def ioctl(fd: _AnyFile,
request: int,
arg: Union[int, bytes] = ...,
mutate_flag: bool = ...) -> Any: ...
Here is a more complete code example.
from typing import ( BinaryIO, )
import ioctl
import fcntl
from ctypes import ( c_uint32, Structure, addressof )
class Point ( Structure ) :
_fields_ = [ ( 'x', c_uint32 ), ( 'y', c_uint32 ) ]
def ioctl_get_point (
dev_hand,
) :
point = Point()
fcntl.ioctl( dev_hand, 0x12345678, point, True ) #! ** MyPy does NOT complain at all **
def ioctl_get_point_2 (
dev_hand, # type: BinaryIO
) :
point = Point()
fcntl.ioctl( dev_hand, 0x12345678, point, True ) #! ** MyPy complains about arg 3 **
return point
def ioctl_get_point_3 (
dev_hand,
) : # type: (...) -> Point
point = Point()
fcntl.ioctl( dev_hand, 0x12345678, point, True ) #! ** MyPy complains about arg 3 **
return point
def ioctl_get_point_4 (
dev_hand, # type: BinaryIO
) : # type: (...) -> Point
point = Point()
fcntl.ioctl( dev_hand, 0x12345678, point, True ) #! ** MyPy complains about arg 3 **
return point
def ioctl_get_point_5 (
dev_hand, # type: BinaryIO
) : # type: (...) -> Point
point = Point()
fcntl.ioctl( dev_hand, 0x12345678, addressof( point ), True ) #! ** MyPy does NOT complain at all **
return point
To me, it seems like using the ctypes.addressof() function, that @CristiFati suggested, is the simplest solution.
Unfortunately that doesn't work. The ioctl() function needs to know the size of the object.
Thanks, Brendan.
ctypes.addressof(my_struct)? - CristiFati--py2). I've updated the question with more info. I think CristiFati's answer of usingctypes.addressof()is the simplest solution. - BrendanSimon