我有下面的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
模块手动打包/解包(我认为这是一种解决方案)。
我正在使用python3.7。3
在Linux(Debian Buster)上,使用mypy 0.782
谢谢,布兰登。
注意:我忘了提到我的代码是针对Python2.7的,因为它是Debian Jessie目标系统遗留下来的。我正在使用--py2
开关来切换mypy
(它必须在Python 3上运行)。
ioctl()
函数具有以下签名,似乎来自vscode服务器(远程ssh)ms-python...
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
对我来说,使用@CristiFati建议的ctypes.addressof()
函数似乎是最简单的解决方案。
不幸的是,这不起作用。ioctl()
函数需要知道对象的大小。
谢谢,布兰登。
首先,该错误消息看起来像Python 2 mypy错误消息,而不是Python 3 mypy错误消息。Python 3的存根有一个fcntl.ioctl
的声明,与该错误消息不匹配。使用Python 3 mypy,您仍然会收到错误消息,但这将是不同的消息。)
第二,fcntl。ioctl
接受任何支持缓冲区接口的对象(包括您的结构),但mypy甚至不知道缓冲区接口是什么。没有支持缓冲区接口的对象的注释,也没有静态识别支持缓冲区接口的对象的方法。目前无法正确注释函数,如fcntl。ioctl
。关于这一点,还有一些悬而未决的问题,但目前还看不到解决方案。
你最好的办法可能是在那一行打一个#type:ignore
注释。
mypy
遵循fnctl的规范。ioctl
功能如下:
参数arg可以是整数、支持只读缓冲区接口的对象(如bytes
)或支持读写缓冲区接口的对象(如byteray
)中的一个。
因此,申诉是合法的。
我宁愿不转换为字节和手动打包/解包与结构模块
借助TYPE_CHECKING
常量,您可以为fnctl引入一个带有类型提示的本地存根。ioctl
将覆盖stdlib的类型提示:
import ctypes
from typing import TYPE_CHECKING
class MyStruct(ctypes.Structure):
_fields_ = [...]
if TYPE_CHECKING: # this is only processed by mypy
from typing import Protocol, Union, TypeVar
class HasFileno(Protocol):
def fileno(self) -> int: ...
FileDescriptorLike = Union[int, HasFileno]
_S = TypeVar('_S', bound=ctypes.Structure)
def ioctl(__fd: FileDescriptorLike, __request: int, __arg: Union[int, bytes, _S] = ..., __mutate_flag: bool = ...) -> int: ...
else: # this will be executed at runtime and ignored by mypy
from fcntl import ioctl
my_struct = MyStruct(...)
my_ioctl_id = ...
dev_hand = ...
ioctl(dev_hand.fileno(), my_ioctl_id, my_struct, True) # mypy won't complain here anymore
这是我试图解决的一个问题的代码 主要的活动是 我得到以下错误, java:36:错误:不兼容类型:int[]无法转换为>integer[]输出=totalchocolates(ip1);
我一直试图编译这个简单的警报对话框,以便在用户单击提交按钮时显示。编译代码时会弹出一条错误消息: 错误:(33,74)错误:不兼容的类型: 这个类叫做Login_Activity,它扩展了BaseActivity,它扩展了Activity。
我试着在这个网站上搜索类似的问题,但没有发现任何地方他们试图使用一个int数字来填充使用方法。
我试着在这个网站上搜索类似的问题,但没有找到任何地方他们试图使用一个int数来填充的方法的使用。
而当运行时,我收到的是: 错误:不兼容类型:int无法转换为客户端ClientDAO.Delete(clientId);
我在抽象课上有以下内容... 还有另一个类,它继承了这个类... 当我从主类执行以下调用时,我收到一个错误... 我的问题是..为什么会发生这种情况?我的getEntityById不是返回T型的东西,在这种情况下应该是产品吗? 我在 Netbeans 中工作,编译时未显示任何错误。 感谢您的帮助=)