typing: Making QObject.findChildren type-aware
Phil Thompson
phil at riverbankcomputing.com
Wed Jul 12 12:50:11 BST 2023
On 09/07/2023 00:37, Florian Bruhin wrote:
> Hey,
>
> Another relatively simple one, hopefully!
>
> The current type hints for QObject.findChildren are:
>
> @typing.overload
> def findChildren(self, type: type, name: str = ..., options:
> Qt.FindChildOption = ...) -> typing.List['QObject']: ...
> @typing.overload
> def findChildren(self, types: typing.Tuple, name: str = ...,
> options: Qt.FindChildOption = ...) -> typing.List['QObject']: ...
> @typing.overload
> def findChildren(self, type: type, re: 'QRegularExpression',
> options: Qt.FindChildOption = ...) -> typing.List['QObject']: ...
> @typing.overload
> def findChildren(self, types: typing.Tuple, re:
> 'QRegularExpression', options: Qt.FindChildOption = ...) ->
> typing.List['QObject']: ...
> @typing.overload
> def findChild(self, type: type, name: str = ..., options:
> Qt.FindChildOption = ...) -> 'QObject': ...
> @typing.overload
> def findChild(self, types: typing.Tuple, name: str = ..., options:
> Qt.FindChildOption = ...) -> 'QObject': ...
>
> which means that one needs to use typing.cast to make the type system
> aware
> that it's in fact not a QObject - for (a somewhat contrived) example:
>
> from PyQt6.QtCore import QThread, QObject
> obj = QObject()
> thread = QThread(obj)
> thread2 = obj.findChild(QThread)
> print(thread2.isRunning())
>
> results in:
>
> error: "QObject" has no attribute "isRunning" [attr-defined]
>
> PyQt6-stubs has this improved here:
> https://github.com/python-qt-tools/PyQt6-stubs/blob/main/PyQt6-stubs/QtCore.pyi#L1393-L1404
>
> and does this instead:
>
> @typing.overload
> def findChildren(self, type: typing.Type[QObjectT], name: str =
> ..., options: Qt.FindChildOption = ...) -> typing.List["QObjectT"]:
> ...
> @typing.overload
> def findChildren(self, types: typing.Tuple[typing.Type[QObjectT],
> ...], name: str = ..., options: Qt.FindChildOption = ...) ->
> typing.List["QObjectT"]: ...
> @typing.overload
> def findChildren(self, type: typing.Type[QObjectT], re:
> "QRegularExpression", options: Qt.FindChildOption = ...) ->
> typing.List["QObjectT"]: ...
> @typing.overload
> def findChildren(self, types: typing.Tuple[typing.Type[QObjectT],
> ...], re: "QRegularExpression", options: Qt.FindChildOption = ...) ->
> typing.List["QObjectT"]: ...
> @typing.overload
> def findChild(self, type: typing.Type[QObjectT], name: str = ...,
> options: Qt.FindChildOption = ...) -> "QObjectT": ...
> @typing.overload
> def findChild(self, types: typing.Tuple[typing.Type[QObjectT],
> ...], name: str = ..., options: Qt.FindChildOption = ...) ->
> "QObjectT": ...
>
> with:
>
> QObjectT = typing.TypeVar("QObjectT", bound=QObject)
>
> which makes the respective "type" / "types" argument based a type
> variable, and
> teaches the type system that the return value will be of the type
> passed in as
> an argument.
>
> (Probably could drop the quotes in the return types too, since they are
> now not
> referring to the QObject class this was defined in anymore)
>
> Florian
Fixed in the next PyQt snapshots.
Phil
More information about the PyQt
mailing list