У меня есть следующий фрагмент кода Python, который создает проблемы MyPy (в 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 )
Ошибка:
Аргумент 3 для ioctl имеет несовместимый тип my_struct; ожидаемый союз [int, str]
MyStruct - это структура ctypes. Все примеры использования ioctl()
со структурами ctypes показывают передачу экземпляра в ioctl()
. Действительно, это работает, но теперь MyPy жалуется.
Я бы предпочел не преобразовывать в байты и вручную упаковывать / распаковывать с помощью модуля struct
(который, как я полагаю, является одним из решений).
Я использую Python 3.7.3
в Linux (Debian Buster) с mypy 0.782
Спасибо, Брендан.
ПРИМЕЧАНИЕ. Я забыл упомянуть, что мой код нацелен на Python 2.7, поскольку он унаследован от целевой системы Debian Jessie. Я использую переключатель --py2
для mypy
(который должен работать на Python 3).
Функция ioctl()
имеет следующую сигнатуру, которая, похоже, исходит от сервера vscode (удаленный ssh) ms-python .... typeshed / stdlib / 3 / fcntl.pyi`
def ioctl(fd: _AnyFile,
request: int,
arg: Union[int, bytes] = ...,
mutate_flag: bool = ...) -> Any: ...
Вот более полный пример кода.
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
Мне кажется, что использование функции ctypes.addressof()
, предложенной @CristiFati, является самым простым решением.
К сожалению, это не работает. Функция ioctl()
должна знать размер объекта.
Спасибо, Брендан.
--py2
). Я обновил вопрос, добавив дополнительную информацию. Я думаю, что ответ CristiFati об использованииctypes.addressof()
- самое простое решение. - person BrendanSimon   schedule 03.08.2020