2017-04-11 50 views
0

我試圖用mypy鍵入PyQt5應用程序的代碼。但是我發現它不會檢查我定義的小部件類中的代碼。我寫了一個小示例應用程序,以瞭解什麼被檢查,哪些不被檢查。如何使用mypy檢查PyQt5應用程序?

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完全檢查代碼嗎?

回答

1

默認情況下,mypy不檢查未註釋的方法。可以爲它們添加類型註釋,或者用--check-untyped-defs來調用它。

+0

'--check-untyped-defs' definetely做得很好。這次真是萬分感謝。現在可以找到'__init __()'函數中的調用。但是'MyWidget.add_numbers()'中的那個仍然被跳過。但其原因是'QSpinBox.value()'的類型未知。我想我需要省略'--ignore-missing-imports'和'--follow-imports = skip'選項。但是接下來會有一個新的投訴:'test.py:1:error:模塊'PyQt5.QtWidgets'沒有庫存根文件。 PyQt5沒有可用的存根文件嗎? – MrLeeh

+1

它們與最近的PyQt5版本一起發貨。 –

+0

我把它們包含在源文件中,分別從源代碼構建時生成。我通常通過'pip install PyQt5'安裝PyQt5,它將使用輪子。由於我在Windows平臺上構建源代碼很困難。有沒有更簡單的方法來獲取存根文件? – MrLeeh

相關問題