python-qt-tools / PyQt5-stubs

Stubs for PyQt5
GNU General Public License v3.0
68 stars 31 forks source link

Problem with Qt methods that return pointers #151

Closed TilmanK closed 2 years ago

TilmanK commented 3 years ago

I just stumbled over an issue, that I was well aware of, but that wasn't reported by MyPy since it's incorrectly annotated in the stubs. Nevertheless, I think this is more of a stub-wide problem. Here's a minimal example:


from PyQt5.QtWidgets import QTableWidget, QApplication

app = QApplication(sys.argv)

# create a QTableWidget with one row and one column
table_widget = QTableWidget()
table_widget.setRowCount(1)
table_widget.setColumnCount(1)

# Get the item in Cell(0,0)
item = table_widget.item(0, 0)

# will print: None
print(str(item))

sys.exit(app.exec())

QTableWidget.item() returns a QTableWidgetItem per annotation. Nevertheless, the C++ method returns a pointer which can (and is in the shown example) a null pointer or None in Python.

How can we take care of this? In QTableWidget alone there are about ten methods that return a pointer. Shouldn't every single one of them have an Optional around their return type? My C++ days are long gone, so I'm not sure: can all of those methods return a null pointer?

The-Compiler commented 3 years ago

so I'm not sure: can all of those methods return a null pointer?

In theory, anything can return a null pointer - with raw pointers like used by Qt, there's no distinction between SomeType and Optional[SomeType]. However, since Qt uses pointers everywhere, annotating everything as Optional would be cumbersome. Many of those things probably are never None in practice.

Thus, this is something which needs to be fixed on a case-by-case basis based on Qt's documentation - for QTableWidget::item that indeed says (emphasis mine):

Returns the item for the given row and column if one has been set; otherwise returns nullptr.

Similarly, horizontalHeaderItem, itemAt, and mimeData (only if passing an empty list?) are documented that way. I suspect verticalHeaderItem and the take... variants do so as well, but to be certain, one would've to check the code.

TilmanK commented 3 years ago

@The-Compiler thanks for the explanation, yeah, that question was kind of stupid. Of course those functions return what was intended when developing them.

Ok. Maybe I'll find some time to fix that stuff at least for common models, views and the widget classes combining them since I tend to use them quite often.

bluebird75 commented 2 years ago

@TilmanK any news on this ?