[prev in list] [next in list] [prev in thread] [next in thread] 

List:       pykde
Subject:    Re: typing: Making QObject.findChildren type-aware
From:       Phil Thompson <phil () riverbankcomputing ! com>
Date:       2023-07-12 11:50:11
Message-ID: 5c3e90213a7fca8dc25f877752f31f66 () riverbankcomputing ! com
[Download RAW message or body]

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
[prev in list] [next in list] [prev in thread] [next in thread] 

Configure | About | News | Add a list | Sponsored by KoreLogic