make tkinter.Event generic and add missing type hints to bind methods (#4347)

This commit is contained in:
Akuli
2020-07-25 15:23:26 +03:00
committed by GitHub
parent 51fd8b2a06
commit 2c37551fd1
2 changed files with 107 additions and 16 deletions

View File

@@ -2,7 +2,8 @@ import sys
from enum import Enum
from tkinter.constants import * # noqa: F403
from types import TracebackType
from typing import Any, Callable, Dict, Optional, Tuple, Type, Union
from typing import Any, Callable, Dict, Generic, Optional, Tuple, Type, TypeVar, Union, overload
from typing_extensions import Literal
TclError: Any
wantobjects: Any
@@ -52,7 +53,10 @@ if sys.version_info >= (3, 6):
VirtualEvent: str = ...
Visibility: str = ...
class Event:
# Events considered covariant because you should never assign to event.widget.
_W = TypeVar("_W", covariant=True, bound="Misc")
class Event(Generic[_W]):
serial: int
num: int
focus: bool
@@ -73,7 +77,7 @@ class Event:
type: EventType
else:
type: str
widget: Misc
widget: _W
delta: int
def NoDefaultRoot(): ...
@@ -119,6 +123,8 @@ getdouble: Any
def getboolean(s): ...
# This class is the base class of all widgets. Don't use BaseWidget or Widget
# for that because Tk doesn't inherit from Widget or BaseWidget.
class Misc:
def destroy(self): ...
def deletecommand(self, name): ...
@@ -222,12 +228,47 @@ class Misc:
def update(self): ...
def update_idletasks(self): ...
def bindtags(self, tagList: Optional[Any] = ...): ...
def bind(self, sequence: Optional[Any] = ..., func: Optional[Any] = ..., add: Optional[Any] = ...): ...
def unbind(self, sequence, funcid: Optional[Any] = ...): ...
def bind_all(self, sequence: Optional[Any] = ..., func: Optional[Any] = ..., add: Optional[Any] = ...): ...
def unbind_all(self, sequence): ...
def bind_class(self, className, sequence: Optional[Any] = ..., func: Optional[Any] = ..., add: Optional[Any] = ...): ...
def unbind_class(self, className, sequence): ...
# bind with isinstance(func, str) doesn't return anything, but all other
# binds do. The default value of func is not str.
@overload
def bind(
self,
sequence: Optional[str] = ...,
func: Optional[Callable[[Event[Misc]], Optional[Literal["break"]]]] = ...,
add: Optional[bool] = ...,
) -> str: ...
@overload
def bind(self, sequence: Optional[str], func: str, add: Optional[bool] = ...) -> None: ...
@overload
def bind(self, *, func: str, add: Optional[bool] = ...) -> None: ...
# There's no way to know what type of widget bind_all and bind_class
# callbacks will get, so those are Misc.
@overload
def bind_all(
self,
sequence: Optional[str] = ...,
func: Optional[Callable[[Event[Misc]], Optional[Literal["break"]]]] = ...,
add: Optional[bool] = ...,
) -> str: ...
@overload
def bind_all(self, sequence: Optional[str], func: str, add: Optional[bool] = ...) -> None: ...
@overload
def bind_all(self, *, func: str, add: Optional[bool] = ...) -> None: ...
@overload
def bind_class(
self,
className: str,
sequence: Optional[str] = ...,
func: Optional[Callable[[Event[Misc]], Optional[Literal["break"]]]] = ...,
add: Optional[bool] = ...,
) -> str: ...
@overload
def bind_class(self, className: str, sequence: Optional[str], func: str, add: Optional[bool] = ...) -> None: ...
@overload
def bind_class(self, className: str, *, func: str, add: Optional[bool] = ...) -> None: ...
def unbind(self, sequence: str, funcid: Optional[str] = ...) -> None: ...
def unbind_all(self, sequence: str) -> None: ...
def unbind_class(self, className: str, sequence: str) -> None: ...
def mainloop(self, n: int = ...): ...
def quit(self): ...
def nametowidget(self, name): ...
@@ -419,7 +460,22 @@ class BaseWidget(Misc):
def __init__(self, master, widgetName, cnf=..., kw=..., extra=...): ...
def destroy(self): ...
class Widget(BaseWidget, Pack, Place, Grid): ...
# This class represents any widget except Toplevel or Tk.
class Widget(BaseWidget, Pack, Place, Grid):
# Allow bind callbacks to take e.g. Event[Label] instead of Event[Misc].
# Tk and Toplevel get notified for their child widgets' events, but other
# widgets don't.
@overload
def bind(
self: _W,
sequence: Optional[str] = ...,
func: Optional[Callable[[Event[_W]], Optional[Literal["break"]]]] = ...,
add: Optional[bool] = ...,
) -> str: ...
@overload
def bind(self, sequence: Optional[str], func: str, add: Optional[bool] = ...) -> None: ...
@overload
def bind(self, *, func: str, add: Optional[bool] = ...) -> None: ...
class Toplevel(BaseWidget, Wm):
def __init__(self, master: Optional[Any] = ..., cnf=..., **kw): ...
@@ -440,8 +496,19 @@ class Canvas(Widget, XView, YView):
def addtag_overlapping(self, newtag, x1, y1, x2, y2): ...
def addtag_withtag(self, newtag, tagOrId): ...
def bbox(self, *args): ...
def tag_unbind(self, tagOrId, sequence, funcid: Optional[Any] = ...): ...
def tag_bind(self, tagOrId, sequence: Optional[Any] = ..., func: Optional[Any] = ..., add: Optional[Any] = ...): ...
@overload
def tag_bind(
self,
tagOrId: Union[str, int],
sequence: Optional[str] = ...,
func: Optional[Callable[[Event[Canvas]], Optional[Literal["break"]]]] = ...,
add: Optional[bool] = ...,
) -> str: ...
@overload
def tag_bind(self, tagOrId: Union[str, int], sequence: Optional[str], func: str, add: Optional[bool] = ...) -> None: ...
@overload
def tag_bind(self, tagOrId: Union[str, int], *, func: str, add: Optional[bool] = ...) -> None: ...
def tag_unbind(self, tagOrId: Union[str, int], sequence: str, funcid: Optional[str] = ...) -> None: ...
def canvasx(self, screenx, gridspacing: Optional[Any] = ...): ...
def canvasy(self, screeny, gridspacing: Optional[Any] = ...): ...
def coords(self, *args): ...
@@ -660,8 +727,18 @@ class Text(Widget, XView, YView):
): ...
def see(self, index): ...
def tag_add(self, tagName, index1, *args): ...
def tag_unbind(self, tagName, sequence, funcid: Optional[Any] = ...): ...
def tag_bind(self, tagName, sequence, func, add: Optional[Any] = ...): ...
# tag_bind stuff is very similar to Canvas
@overload
def tag_bind(
self,
tagName: str,
sequence: Optional[str],
func: Optional[Callable[[Event[Text]], Optional[Literal["break"]]]],
add: Optional[bool] = ...,
) -> str: ...
@overload
def tag_bind(self, tagName: str, sequence: Optional[str], func: str, add: Optional[bool] = ...) -> None: ...
def tag_unbind(self, tagName: str, sequence: str, funcid: Optional[str] = ...) -> None: ...
def tag_cget(self, tagName, option): ...
def tag_configure(self, tagName, cnf: Optional[Any] = ..., **kw): ...
tag_config: Any

View File

@@ -1,6 +1,8 @@
import sys
import tkinter
from typing import Any, List, Optional
from tkinter import Event
from typing import Any, Callable, Dict, List, Optional, Tuple, Type, TypeVar, Union, overload
from typing_extensions import Literal
def tclobjs_to_py(adict): ...
def setup_master(master: Optional[Any] = ...): ...
@@ -145,7 +147,19 @@ class Treeview(Widget, tkinter.XView, tkinter.YView):
def selection_remove(self, items): ...
def selection_toggle(self, items): ...
def set(self, item, column: Optional[Any] = ..., value: Optional[Any] = ...): ...
def tag_bind(self, tagname, sequence: Optional[Any] = ..., callback: Optional[Any] = ...): ...
# There's no tag_unbind() or 'add' argument for whatever reason.
# Also, it's 'callback' instead of 'func' here.
@overload
def tag_bind(
self,
tagname: str,
sequence: Optional[str] = ...,
callback: Optional[Callable[[Event[Treeview]], Optional[Literal["break"]]]] = ...,
) -> str: ...
@overload
def tag_bind(self, tagname: str, sequence: Optional[str], callback: str) -> None: ...
@overload
def tag_bind(self, tagname: str, *, callback: str) -> None: ...
def tag_configure(self, tagname, option: Optional[Any] = ..., **kw): ...
def tag_has(self, tagname, item: Optional[Any] = ...): ...