Skip to content

tkinter.Event is not generic at runtime #4431

@Akuli

Description

@Akuli

In #4347 I made tkinter.Event generic, so that you could write

def event_handler(event: tkinter.Event[tkinter.Label]) -> None:
    label_stuff(event.widget)

instead of

def event_handler(event: tkinter.Event) -> None:
    assert isinstance(event.widget, tkinter.Label)
    label_stuff(event.widget)

This doesn't actually work because tkinter.Event is not generic at runtime, so you need to use a string instead (or on 3.8+, from __future__ import annotations):

def event_handler(event: "tkinter.Event[tkinter.Label]") -> None:
    label_stuff(event.widget)

The assert code still works though because plain tkinter.Event is equivalent to tkinter.Event[Any]. So the stubs currently allow writing event: tkinter.Event or event: "tkinter.Event[Foo]", but I didn't realize the need for using a string when I made the pull request.

What we can do about this:

  • Do nothing and recommend using tkinter.Event or "tkinter.Event[Foo]".
  • Create a pull request to cpython that makes tkinter.Event generic at runtime. This won't actually help because 3.8+ has from __future__ import annotations and tkinter.Event wouldn't become generic in older pythons.
  • Revert make tkinter.Event generic and add missing type hints to bind methods #4347 and just require assert isinstance(event.widget, Foo).

Also, what else can go wrong with making something generic in stubs but not at runtime?

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions