Как набрать проверку приложения PyQt5 с помощью mypy?

Я попытался проверить код приложения PyQt5 с помощью mypy. Но я обнаружил, что он не будет проверять код внутри моего определенного класса виджетов. Я написал небольшой пример приложения, чтобы узнать, что проверяется, а что нет.

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() и в __init__() функции почему-то пропущены. Mypy игнорирует все, что находится внутри класса MyWidget(). Кто-нибудь знает, что сделать, чтобы mypy полностью проверил код?


person MrLeeh    schedule 11.04.2017    source источник
comment
Почему голос против?   -  person MrLeeh    schedule 28.04.2018
comment
Кажется, что pyqt5 поставляется с заглушками типов, но отсутствует файл typed.py, который mypy мог бы их выбрать. Я попытался создать этот файл, и у меня все сработало.   -  person LtWorf    schedule 29.12.2020


Ответы (1)


mypy по умолчанию не проверяет неаннотированные методы. Либо добавьте к ним аннотации типов, либо вызовите с помощью --check-untyped-defs.

person The Compiler    schedule 12.04.2017
comment
--check-untyped-defs определенно делает хорошую работу. Спасибо тебе за это. Теперь вызов в функции __init__() найден. Однако тот, что указан в MyWidget.add_numbers(), по-прежнему пропускается. Но причина этого в том, что тип QSpinBox.value() неизвестен. Думаю, мне нужно исключить параметры --ignore-missing-imports и --follow-imports=skip. Но потом будет новая жалоба: test.py:1: error: No library stub file for module 'PyQt5.QtWidgets'. Нет ли файлов-заглушек для PyQt5? - person MrLeeh; 12.04.2017
comment
Они поставляются с последними выпусками PyQt5. - person The Compiler; 12.04.2017
comment
Я так понимаю, что они включены в исходные файлы, соответственно, создаются при сборке из исходников. Обычно я устанавливаю PyQt5 через pip install PyQt5, который будет использовать колеса. Поскольку я использую Windows, сборка из исходников затруднена. Есть ли более простой способ получить файлы-заглушки? - person MrLeeh; 12.04.2017
comment
Тем временем я получил файлы-заглушки со своей виртуальной машины Linux, на которой я собрал PyQt5 из исходных текстов, и скопировал файлы * .pyi в свой проект Windows. Но их использование приводит к множеству ошибок, подобных описанным здесь. - person MrLeeh; 12.04.2017
comment
Это письмо оказалось моим: D Может быть, было бы лучше просто не проверять типы этих модулей, но я не знаю, как вы могли бы заставить mypy это сделать. Я все еще планирую начать использовать mypy и редактировать файлы-заглушки, чтобы работать с ним лучше, но пока я до этого не дошел. - person The Compiler; 12.04.2017
comment
О, это забавно: D Я не знал, что это был ваш пост, но теперь вижу, отлично. Я согласен с тем, что файлы-заглушки необходимо будет скорректировать и, возможно, добавить в машинный код. Но я спрашиваю себя, почему они вообще созданы неправильным образом. - person MrLeeh; 12.04.2017
comment
Я ожидал, что по крайней мере ошибки (из-за отсутствия импорта) исчезнут. Для остальных это более непонятные ограничения (или разногласия?), И файлы, вероятно, по-прежнему полезны в других контекстах (например, автозаполнение в IDE). - person The Compiler; 12.04.2017