Python 如何使用mypy键入检查PyQt5应用程序?

Python 如何使用mypy键入检查PyQt5应用程序?,python,pyqt,mypy,Python,Pyqt,Mypy,我试图用mypy键入PyQt5应用程序的代码。但是我发现它不会检查我定义的widget类中的代码。我编写了一个小的示例应用程序,以找出哪些被检查,哪些没有被检查 from PyQt5.QtWidgets import QApplication, QWidget, QPushButton, QGridLayout, \ QSpinBox, QLabel def add_numbers(a: str, b: str) -> str: return a + b def a

我试图用mypy键入PyQt5应用程序的代码。但是我发现它不会检查我定义的widget类中的代码。我编写了一个小的示例应用程序,以找出哪些被检查,哪些没有被检查

from PyQt5.QtWidgets import QApplication, QWidget, QPushButton, QGridLayout, \
    QSpinBox, QLabel


def add_numbers(a: str, b: str) -> str:
    return a + b


def add_numbers2(a: str, b: int) -> int:
    return a + b  # found: unsupported operand int + str


class MyWidget(QWidget):

    def __init__(self, parent=None):
        super().__init__(parent)

        add_numbers(1, 2)  # not found: should result in incompatible type error

        self.a_label = QLabel('a:')
        self.a_spinbox = QSpinBox()
        self.b_label = QLabel('b:')
        self.b_spinbox = QSpinBox()
        self.c_label = QLabel('c:')
        self.c_spinbox = QSpinBox()
        self.button = QPushButton('a + b')

        layout = QGridLayout()
        layout.addWidget(self.a_label, 0, 0)
        layout.addWidget(self.a_spinbox, 0, 1)
        layout.addWidget(self.b_label, 1, 0)
        layout.addWidget(self.b_spinbox, 1, 1)
        layout.addWidget(self.button, 2, 1)
        layout.addWidget(self.c_label, 3, 0)
        layout.addWidget(self.c_spinbox, 3, 1)
        self.setLayout(layout)

        self.button.clicked.connect(self.add_numbers)

    def add_numbers(self):
        a = self.a_spinbox.value()
        b = self.b_spinbox.value()
        c = add_numbers(a, b)  # not found: should result in incompatible type error
        self.c_spinbox.setValue(c)


if __name__ == '__main__':
    add_numbers(1, 2)  # found: incompatible type found by mypy
    app = QApplication([])
    w = MyWidget()
    w.show()
    app.exec_()
如果我运行mypy,我会得到以下输出:

$ mypy --ignore-missing-imports --follow-imports=skip test.py
test.py:10: error: Unsupported operand types for + ("str" and "int")
test.py:48: error: Argument 1 to "add_numbers" has incompatible type "int"; 
expected "str"
test.py:48: error: Argument 2 to "add_numbers" has incompatible type "int"; 
expected "str"

Mypy在
add_numbers2()
中发现了类型错误,在主要部分,我试图将两个整数传递给只接受字符串作为参数的函数
add_numbers()
。但是由于某些原因,
MyWidget.add_number()
\uuu init\uuuu()
函数中的错误已被跳过。mypy会忽略
MyWidget()
类中的所有内容。有人知道如何使mypy能够完全检查代码吗?

默认情况下,mypy不会检查未注释的方法。可以向它们添加类型注释,也可以使用
--check untyped defs

调用它。默认情况下,mypy不会检查未注释的方法。要么给它们添加类型注释,要么用
调用它——检查非类型化的defs

——检查非类型化的defs
确实做得很好。谢谢你。现在找到了
\uuuu init\uuuu()
函数中的调用。但是,
MyWidget.add_numbers()
中的一个仍然被跳过。但原因是,
QSpinBox.value()
的类型未知。我想我需要省去
--忽略缺少的导入
--跟随导入=跳过
选项。但是接下来会有一个新的抱怨:
test.py:1:错误:模块'PyQt5.qtwidts'没有库存根文件。
。PyQt5没有存根文件吗?它们随PyQt5的最新版本一起提供。我认为它们包含在从源代码构建时分别生成的源文件中。我通常通过
pip安装PyQt5
安装PyQt5,它将使用控制盘。因为我在Windows上,从源代码构建很困难。有没有更简单的方法来获取存根文件?与此同时,我从我的linux虚拟机中检索存根文件,在那里我从源代码构建了PyQt5,并将*.pyi文件复制到我的Windows项目中。但是使用它们会产生大量的错误,就像上面描述的那样。那封邮件恰好是我的:D也许最好不要对那些模块进行打字检查,但我不知道你会如何让mypy做到这一点。我仍然计划开始使用mypy并编辑存根文件以更好地使用它,但到目前为止我还没有做到这一点。
——检查非类型的defs
确实做得很好。谢谢你。现在找到了
\uuuu init\uuuu()
函数中的调用。但是,
MyWidget.add_numbers()
中的一个仍然被跳过。但原因是,
QSpinBox.value()
的类型未知。我想我需要省去
--忽略缺少的导入
--跟随导入=跳过
选项。但是接下来会有一个新的抱怨:
test.py:1:错误:模块'PyQt5.qtwidts'没有库存根文件。
。PyQt5没有存根文件吗?它们随PyQt5的最新版本一起提供。我认为它们包含在从源代码构建时分别生成的源文件中。我通常通过
pip安装PyQt5
安装PyQt5,它将使用控制盘。因为我在Windows上,从源代码构建很困难。有没有更简单的方法来获取存根文件?与此同时,我从我的linux虚拟机中检索存根文件,在那里我从源代码构建了PyQt5,并将*.pyi文件复制到我的Windows项目中。但是使用它们会产生大量的错误,就像上面描述的那样。那封邮件恰好是我的:D也许最好不要对那些模块进行打字检查,但我不知道你会如何让mypy做到这一点。我仍然计划开始使用mypy并编辑存根文件以更好地使用它,但到目前为止我还没有做到。为什么要进行下一票?pyqt5似乎带有类型存根,但缺少mypy选择它们的
typed.py
文件。我试着创建了那个文件,然后一切都对我有效。为什么要否决?pyqt5似乎有类型存根,但缺少mypy选择的
typed.py
文件。我试着创建那个文件,然后一切都对我有用。