Skip to content

Type annotations #417

@TilmanK

Description

@TilmanK
Contributor

I stumbled upon this when setting a new project where I haven't configured mypy yet to just ignore pytest-qt: There are no type annotations.

Is there a reason from this apart from “It's not there because no one did it yet”? It would be a nice-to-have thing, since the earliest mayor Python version supported is 3.6 and pytest itself has them (as far as I remember)…

Activity

nicoddemus

nicoddemus commented on Apr 20, 2022

@nicoddemus
Member

Hi @TilmanK!

“It's not there because no one did it yet”?

Mainly that only. I'm a big fan of having type annotations (even aiming for full type annotations), but nobody has stopped to bring them to pytest-qt yet.

TilmanK

TilmanK commented on Apr 20, 2022

@TilmanK
ContributorAuthor

Hmm, any idea how to address the dynamic use of the Qt library? Maybe using TypeVars in some way?

nicoddemus

nicoddemus commented on Apr 20, 2022

@nicoddemus
Member

the dynamic use of the Qt library?

Hmm sorry can you be more specific?

TilmanK

TilmanK commented on Apr 22, 2022

@TilmanK
ContributorAuthor

Sure. Let's take QtBot.addWidget() as an example:

def addWidget(self, widget, *, before_close_func=None):

How do I annotate that? I can use widget: qt_api.QtWidgets.QWidget. Doing so results in an error: Name "qt_api.QtWidgets.QWidget" is not defined

nicoddemus

nicoddemus commented on Apr 22, 2022

@nicoddemus
Member

Oh I see thanks.

Hmm that's tricky, not sure how to overcome that: qt_api by design only defines the symbols at runtime (during pytest_configure), so there's no way to do that at static time.

TilmanK

TilmanK commented on Apr 22, 2022

@TilmanK
ContributorAuthor

We could do something like.

if TYPE_CHECKING:
    qt_api = PyQt6

Maybe...

nicoddemus

nicoddemus commented on Apr 22, 2022

@nicoddemus
Member

I thought of that, the problem is that the choice of using PyQt or PySide is defined at realtime too, so that snippet won't work for PySide users... :/

TilmanK

TilmanK commented on Apr 23, 2022

@TilmanK
ContributorAuthor

I thought of that, the problem is that the choice of using PyQt or PySide is defined at realtime too, so that snippet won't work for PySide users... :/

Yes, I know. Sorry, the code snippet isn't clear. Of course, I don't want to hard-wire the API to PyQt6, I was just thinking about a first approach to tell mypy which package to use...

nicoddemus

nicoddemus commented on Apr 23, 2022

@nicoddemus
Member

I was just thinking about a first approach to tell mypy which package to use...

Indeed. However that selection is done at runtime by design (checking an environment variable, or the configuration in pytest.ini file), which are ultimately runtime decisions, so mypy can't know about them at static time. 🤔

nicoddemus

nicoddemus commented on Apr 25, 2022

@nicoddemus
Member

Just thinking about this: we might decide to type any qt-related class as Any for now, and properly type everything else. Having a widget: Any parameter is not so bad for now if we type the other parameters. If we find a solution down the road, we can then improve the typing coverage accordingly.

TilmanK

TilmanK commented on Apr 25, 2022

@TilmanK
ContributorAuthor

I already started to work on a PR doing exactly this 😊

nicoddemus

nicoddemus commented on Apr 25, 2022

@nicoddemus
Member

Great! 😁

The-Compiler

The-Compiler commented on Apr 30, 2022

@The-Compiler
Member

FWIW, the way other Qt wrappers seem to approach this (qtpy, qts) is that they have a CLI supplying --always-true and --always-false options to mypy.

adam-grant-hendry

adam-grant-hendry commented on Jun 15, 2022

@adam-grant-hendry

Thanks for linking me to the discussion here @nicoddemus ! I'll throw my hat in the ring and put up a PR.

From our discussion, we agreed adding type hints inline to the source was preferred over using stubs(*.pyi files), which I 100% support. I think this is the best approach.

I have one file hinted as of yet. Per PEP 561, you can add a line "partial\n" to the "py.typed" marker to indicate the package is partially stubbed. I'll add this so we can add type hints one-by-one to each module as we create them and have PRs for individual modules as opposed to a giant PR that type hints the whole code base at one go.

TilmanK

TilmanK commented on Jun 18, 2022

@TilmanK
ContributorAuthor

Go for it, I currently can find the time to do this anyway...

herobank110

herobank110 commented on May 22, 2025

@herobank110
Contributor

Is there any status update on adding the type annotations?

The-Compiler

The-Compiler commented on May 22, 2025

@The-Compiler
Member

No, otherwise it would be in this issue, that's kind of the whole point of a public issue tracker 😉

herobank110

herobank110 commented on May 22, 2025

@herobank110
Contributor

mind if I take a stab at it?

The-Compiler

The-Compiler commented on May 22, 2025

@The-Compiler
Member

Please go ahead! I think even just getting the infrastructure into place (e.g. mypy running on CI) and annotating the easier cases would be a big win and get the ball rolling.

herobank110

herobank110 commented on May 22, 2025

@herobank110
Contributor

I have a proposed proof of concept: #605.
The main idea is using TYPE_CHECKING to import the relevant qt code from qtpy, as I'm not sure the qt_compat/qt_api in this repo will be able to provide much type annotation capabilities. Technically qtpy wouldn't need to be added to this project's dependencies - users of the library can have it in their own project to get the typing. However for mypy to actually type check in this project's CI properly, perhaps qtpy could be added as a dev dependency?

Also I'm not aware of a way to properly type *args and **kwargs for forwarding, as needed in the mouseClick, etc. functions. One solution may be to duplicate the parameters from the Qt API.

I have added mypy to the precommit config and it seems to be running on CI

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

      Participants

      @The-Compiler@nicoddemus@TilmanK@herobank110@adam-grant-hendry

      Issue actions

        Type annotations · Issue #417 · pytest-dev/pytest-qt