typing: Making pyqtSlot typed
Phil Thompson
phil at riverbankcomputing.com
Wed Jul 5 17:20:03 BST 2023
On 29/06/2023 23:20, Florian Bruhin wrote:
> Whoops. Resent without line-wrapping... switched to a new mail-client
> which is based on PyQt btw: https://github.com/akissinger/dodo
>
> Sorry for the noise!
>
> -----------
>
> Hey,
>
> last one for today :)
>
> pyqtSlot is currently typed as returning Any:
>
> def pyqtSlot(
> *types,
> name: typing.Optional[str] = ...,
> result: typing.Optional[str] = ...,
> ) -> typing.Any: ...
>
> which means that incorrect code such as:
>
> from PyQt6.QtCore import pyqtSlot
>
> @pyqtSlot(int)
> def func(a: int) -> None:
> print(a)
>
> func("not-an-int")
>
> can't be typechecked because the pyqtSlot decorator loses the type
> information:
>
> slot.py:3: error: Untyped decorator makes function "func" untyped
> [misc]
>
> A minimal improvement wound be:
>
> FuncT = typing.TypeVar("FuncT", bound=typing.Callable)
> def pyqtSlot(*types, name: typing.Optional[str] = ..., result:
> typing.Optional[str] = ...) -> typing.Callable[[FuncT], FuncT]: ...
>
> read as:
>
> - FuncT is a type variable, representing any callable
> - Calling pyqtSlot as e.g. pyqtSlot(int) returns a callable
> (the decorator)
> - That decorator takes a FuncT as argument, and returns a FuncT
>
> Thus, we can teach the type system that @pyqtSlot does not touch the
> decorated function's signature, which then results in mypy catching
> this
> properly:
>
> slot.py:7: error: Argument 1 to "func" has incompatible type
> "str"; expected "int" [arg-type]
> func("not-an-int")
>
> Interestingly, the PyQt6-stubs project has far more complex typing for
> pyqtSlot:
>
> https://github.com/python-qt-tools/PyQt6-stubs/blob/f623a641cd5cdff53342177e4fbbf9cae8172336/PyQt6-stubs/QtCore.pyi#L7537-L7563
>
> It's unclear to me how that works in detail and if it's really needed.
> The minimal fix above fixes all related errors for my project (but I
> don't e.g. use QML).
>
> Florian
Fixed.
Thanks,
Phil
More information about the PyQt
mailing list