[Python] How to correctly type-hint a function with `pyqtSlot()` decorator inside `QRunnable`...

Discussão em 'Python' iniciado por Stack, Julho 10, 2025.

  1. Stack

    Stack Membro Participativo

    Status:

    1. I'm learning how to use concurrency/threads within PyQt library from here www.pythonguis.com. Below is the simplified/part of code from this tutorial.
    2. I want strict type hinting in my code. And I'm getting error messages on this code from mypy. (Shown on the 2-nd source-code block).

    Question:

    • How to correctly type-hint the function while using pyqtSlot() decorator?
    • What is Superclass (that return None), and what is Subclass (that returns str|None) in this case?

    What I tried to solve:

    • My autistic ass doesn't sit well with error is showing on my text-editor. And I wasted too much time to solve single line. I couldn't find anything useful on the internet.
    • The definition (or should I say stub file) says pyqtSlot() is: def pyqtSlot(*types, name: typing.Optional[str] = ..., result: typing.Optional[str] = ...) -> typing.Callable[..., typing.Optional[str]]: ..., I'm unable to interpret this due to no-experience on decorators.
    • stub file: QtCore.pyi says that Class QRunnable's run is: def run(self) -> None: ....

    from typing import Callable
    from PyQt5.QtCore import QObject, QRunnable, pyqtSignal, pyqtSlot

    import traceback
    import sys


    class WorkerSignal(QObject):
    finished = pyqtSignal()
    error = pyqtSignal(tuple)
    result = pyqtSignal(object)
    progress = pyqtSignal(int)


    class Worker(QRunnable):
    def __init__(self, fn: Callable[[], str]) -> None:
    super(Worker, self).__init__()
    self.fn:Callable[[], str] = fn
    self.signals: WorkerSignal = WorkerSignal()

    @pyqtSlot()
    def run(self) -> None: # <====================== this line
    try:
    result: str = self.fn()
    except Exception:
    traceback.print_exc()
    exctype, value = sys.exc_info()[:2]
    self.signals.error.emit((exctype, value, traceback.format_exc()))
    else:
    self.signals.result.emit(result)
    finally:
    self.signals.finished.emit()


    $ mypy /tmp/tmp.py
    /tmp/tmp.py:22: error: Signature of "run" incompatible with supertype "QRunnable" [override]
    /tmp/tmp.py:22: note: Superclass:
    /tmp/tmp.py:22: note: def run(self) -> None
    /tmp/tmp.py:22: note: Subclass:
    /tmp/tmp.py:22: note: str | None
    Found 1 error in 1 file (checked 1 source file)


    EDIT:

    • Is the following guess correct?
      • pyqtSlot() takes function that returns typing.Optional[str] (i.e. str | None). Perhaps its the subclass?
      • QRunnable's method run() only return None, Perhaps it's the superclass?
      • In this case, correct question would be: How to use decorator, if decorator's return and function's return are different? Would this be the correct question?

    Continue reading...

Compartilhe esta Página