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