From 3caf2ebe30a9b822512920cb188aa25f654c936a Mon Sep 17 00:00:00 2001 From: donbarbos Date: Tue, 13 Jan 2026 21:39:41 +0400 Subject: [PATCH 1/3] [tkinter] Annotate few methods Source: https://github.com/python/cpython/blob/main/Modules/_tkinter.c --- stdlib/_tkinter.pyi | 35 ++++++++++++++++++----------------- stdlib/tkinter/__init__.pyi | 28 ++++++++++++++-------------- 2 files changed, 32 insertions(+), 31 deletions(-) diff --git a/stdlib/_tkinter.pyi b/stdlib/_tkinter.pyi index a3868f467c6c..73bc8426e09c 100644 --- a/stdlib/_tkinter.pyi +++ b/stdlib/_tkinter.pyi @@ -1,4 +1,5 @@ import sys +from _typeshed import FileDescriptorLike, Incomplete from collections.abc import Callable from typing import Any, ClassVar, Final, final from typing_extensions import TypeAlias, deprecated @@ -54,22 +55,22 @@ _TkinterTraceFunc: TypeAlias = Callable[[tuple[str, ...]], object] @final class TkappType: # Please keep in sync with tkinter.Tk - def adderrorinfo(self, msg: str, /): ... + def adderrorinfo(self, msg: str, /) -> None: ... def call(self, command: Any, /, *args: Any) -> Any: ... - def createcommand(self, name: str, func, /): ... + def createcommand(self, name: str, func: Callable[..., object], /) -> None: ... if sys.platform != "win32": - def createfilehandler(self, file, mask: int, func, /): ... - def deletefilehandler(self, file, /) -> None: ... + def createfilehandler(self, file: FileDescriptorLike, mask: int, func: Callable[..., object], /) -> None: ... + def deletefilehandler(self, file: FileDescriptorLike, /) -> None: ... - def createtimerhandler(self, milliseconds: int, func, /): ... - def deletecommand(self, name: str, /): ... - def dooneevent(self, flags: int = 0, /): ... + def createtimerhandler(self, milliseconds: int, func: Callable[..., object], /): ... + def deletecommand(self, name: str, /) -> None: ... + def dooneevent(self, flags: int = 0, /) -> int: ... def eval(self, script: str, /) -> str: ... - def evalfile(self, fileName: str, /): ... - def exprboolean(self, s: str, /): ... - def exprdouble(self, s: str, /): ... - def exprlong(self, s: str, /): ... - def exprstring(self, s: str, /): ... + def evalfile(self, fileName: str, /) -> str: ... + def exprboolean(self, s: str, /) -> int: ... + def exprdouble(self, s: str, /) -> float: ... + def exprlong(self, s: str, /) -> int: ... + def exprstring(self, s: str, /) -> str: ... def getboolean(self, arg, /) -> bool: ... def getdouble(self, arg, /) -> float: ... def getint(self, arg, /) -> int: ... @@ -81,13 +82,13 @@ class TkappType: def loadtk(self) -> None: ... def mainloop(self, threshold: int = 0, /) -> None: ... def quit(self) -> None: ... - def record(self, script: str, /): ... + def record(self, script: str, /) -> str: ... def setvar(self, *ags, **kwargs): ... if sys.version_info < (3, 11): @deprecated("Deprecated since Python 3.9; removed in Python 3.11. Use `splitlist()` instead.") def split(self, arg, /): ... - def splitlist(self, arg, /): ... + def splitlist(self, arg, /) -> tuple[Incomplete, ...]: ... def unsetvar(self, *args, **kwargs): ... def wantobjects(self, *args, **kwargs): ... def willdispatch(self) -> None: ... @@ -112,7 +113,7 @@ TK_VERSION: Final[str] @final class TkttType: - def deletetimerhandler(self): ... + def deletetimerhandler(self) -> None: ... if sys.version_info >= (3, 13): def create( @@ -125,7 +126,7 @@ if sys.version_info >= (3, 13): sync: bool = False, use: str | None = None, /, - ): ... + ) -> TkappType: ... else: def create( @@ -138,7 +139,7 @@ else: sync: bool = False, use: str | None = None, /, - ): ... + ) -> TkappType: ... def getbusywaitinterval() -> int: ... def setbusywaitinterval(new_val: int, /) -> None: ... diff --git a/stdlib/tkinter/__init__.pyi b/stdlib/tkinter/__init__.pyi index ef57faa2b009..ef7ae8539443 100644 --- a/stdlib/tkinter/__init__.pyi +++ b/stdlib/tkinter/__init__.pyi @@ -1,6 +1,6 @@ import _tkinter import sys -from _typeshed import Incomplete, MaybeNone, StrOrBytesPath +from _typeshed import FileDescriptorLike, Incomplete, MaybeNone, StrOrBytesPath from collections.abc import Callable, Iterable, Mapping, Sequence from tkinter.constants import * from tkinter.font import _FontDescription @@ -1005,32 +1005,32 @@ class Tk(Misc, Wm): # Tk has __getattr__ so that tk_instance.foo falls back to tk_instance.tk.foo # Please keep in sync with _tkinter.TkappType. # Some methods are intentionally missing because they are inherited from Misc instead. - def adderrorinfo(self, msg: str, /): ... + def adderrorinfo(self, msg: str, /) -> None: ... def call(self, command: Any, /, *args: Any) -> Any: ... - def createcommand(self, name: str, func, /): ... + def createcommand(self, name: str, func: Callable[..., object], /) -> None: ... if sys.platform != "win32": - def createfilehandler(self, file, mask: int, func, /): ... - def deletefilehandler(self, file, /) -> None: ... + def createfilehandler(self, file: FileDescriptorLike, mask: int, func: Callable[..., object], /) -> None: ... + def deletefilehandler(self, file: FileDescriptorLike, /) -> None: ... - def createtimerhandler(self, milliseconds: int, func, /): ... - def dooneevent(self, flags: int = 0, /): ... + def createtimerhandler(self, milliseconds: int, func: Callable[..., object], /): ... + def dooneevent(self, flags: int = 0, /) -> int: ... def eval(self, script: str, /) -> str: ... - def evalfile(self, fileName: str, /): ... - def exprboolean(self, s: str, /): ... - def exprdouble(self, s: str, /): ... - def exprlong(self, s: str, /): ... - def exprstring(self, s: str, /): ... + def evalfile(self, fileName: str, /) -> str: ... + def exprboolean(self, s: str, /) -> int: ... + def exprdouble(self, s: str, /) -> float: ... + def exprlong(self, s: str, /) -> int: ... + def exprstring(self, s: str, /) -> str: ... def globalgetvar(self, *args, **kwargs): ... def globalsetvar(self, *args, **kwargs): ... def globalunsetvar(self, *args, **kwargs): ... def interpaddr(self) -> int: ... def loadtk(self) -> None: ... - def record(self, script: str, /): ... + def record(self, script: str, /) -> str: ... if sys.version_info < (3, 11): @deprecated("Deprecated since Python 3.9; removed in Python 3.11. Use `splitlist()` instead.") def split(self, arg, /): ... - def splitlist(self, arg, /): ... + def splitlist(self, arg, /) -> tuple[Incomplete, ...]: ... def unsetvar(self, *args, **kwargs): ... def wantobjects(self, *args, **kwargs): ... def willdispatch(self) -> None: ... From 4fd1d546edd1b9d8302298002a21ab2ae3b10cb8 Mon Sep 17 00:00:00 2001 From: donbarbos Date: Wed, 14 Jan 2026 13:07:56 +0400 Subject: [PATCH 2/3] Annotate wantobjects --- stdlib/_tkinter.pyi | 7 +++++-- stdlib/tkinter/__init__.pyi | 5 ++++- 2 files changed, 9 insertions(+), 3 deletions(-) diff --git a/stdlib/_tkinter.pyi b/stdlib/_tkinter.pyi index 73bc8426e09c..2eeec0fd9296 100644 --- a/stdlib/_tkinter.pyi +++ b/stdlib/_tkinter.pyi @@ -1,7 +1,7 @@ import sys from _typeshed import FileDescriptorLike, Incomplete from collections.abc import Callable -from typing import Any, ClassVar, Final, final +from typing import Any, ClassVar, Final, final, overload from typing_extensions import TypeAlias, deprecated # _tkinter is meant to be only used internally by tkinter, but some tkinter @@ -90,7 +90,10 @@ class TkappType: def splitlist(self, arg, /) -> tuple[Incomplete, ...]: ... def unsetvar(self, *args, **kwargs): ... - def wantobjects(self, *args, **kwargs): ... + @overload + def wantobjects(self) -> int: ... + @overload + def wantobjects(self, wantobjects: int, /) -> None: ... def willdispatch(self) -> None: ... if sys.version_info >= (3, 12): def gettrace(self, /) -> _TkinterTraceFunc | None: ... diff --git a/stdlib/tkinter/__init__.pyi b/stdlib/tkinter/__init__.pyi index ef7ae8539443..44fee5066679 100644 --- a/stdlib/tkinter/__init__.pyi +++ b/stdlib/tkinter/__init__.pyi @@ -1032,7 +1032,10 @@ class Tk(Misc, Wm): def splitlist(self, arg, /) -> tuple[Incomplete, ...]: ... def unsetvar(self, *args, **kwargs): ... - def wantobjects(self, *args, **kwargs): ... + @overload + def wantobjects(self) -> int: ... + @overload + def wantobjects(self, wantobjects: int, /) -> None: ... def willdispatch(self) -> None: ... def Tcl(screenName: str | None = None, baseName: str | None = None, className: str = "Tk", useTk: bool = False) -> Tk: ... From 2b322a4058039129233a41e46a47ac48e0c3348a Mon Sep 17 00:00:00 2001 From: donbarbos Date: Thu, 15 Jan 2026 00:02:12 +0400 Subject: [PATCH 3/3] Update --- stdlib/_tkinter.pyi | 16 +++++++++++----- stdlib/tkinter/__init__.pyi | 14 ++++++++++---- 2 files changed, 21 insertions(+), 9 deletions(-) diff --git a/stdlib/_tkinter.pyi b/stdlib/_tkinter.pyi index 2eeec0fd9296..5e46668e08b1 100644 --- a/stdlib/_tkinter.pyi +++ b/stdlib/_tkinter.pyi @@ -1,7 +1,7 @@ import sys from _typeshed import FileDescriptorLike, Incomplete from collections.abc import Callable -from typing import Any, ClassVar, Final, final, overload +from typing import Any, ClassVar, Final, Literal, final, overload from typing_extensions import TypeAlias, deprecated # _tkinter is meant to be only used internally by tkinter, but some tkinter @@ -57,6 +57,7 @@ class TkappType: # Please keep in sync with tkinter.Tk def adderrorinfo(self, msg: str, /) -> None: ... def call(self, command: Any, /, *args: Any) -> Any: ... + # TODO: Figure out what arguments the following `func` callbacks should accept def createcommand(self, name: str, func: Callable[..., object], /) -> None: ... if sys.platform != "win32": def createfilehandler(self, file: FileDescriptorLike, mask: int, func: Callable[..., object], /) -> None: ... @@ -67,7 +68,7 @@ class TkappType: def dooneevent(self, flags: int = 0, /) -> int: ... def eval(self, script: str, /) -> str: ... def evalfile(self, fileName: str, /) -> str: ... - def exprboolean(self, s: str, /) -> int: ... + def exprboolean(self, s: str, /) -> Literal[0, 1]: ... def exprdouble(self, s: str, /) -> float: ... def exprlong(self, s: str, /) -> int: ... def exprstring(self, s: str, /) -> str: ... @@ -90,10 +91,15 @@ class TkappType: def splitlist(self, arg, /) -> tuple[Incomplete, ...]: ... def unsetvar(self, *args, **kwargs): ... + if sys.version_info >= (3, 14): + @overload + def wantobjects(self) -> Literal[0, 1]: ... + else: + @overload + def wantobjects(self) -> bool: ... + @overload - def wantobjects(self) -> int: ... - @overload - def wantobjects(self, wantobjects: int, /) -> None: ... + def wantobjects(self, wantobjects: Literal[0, 1] | bool, /) -> None: ... def willdispatch(self) -> None: ... if sys.version_info >= (3, 12): def gettrace(self, /) -> _TkinterTraceFunc | None: ... diff --git a/stdlib/tkinter/__init__.pyi b/stdlib/tkinter/__init__.pyi index 44fee5066679..90225a8a3652 100644 --- a/stdlib/tkinter/__init__.pyi +++ b/stdlib/tkinter/__init__.pyi @@ -1007,6 +1007,7 @@ class Tk(Misc, Wm): # Some methods are intentionally missing because they are inherited from Misc instead. def adderrorinfo(self, msg: str, /) -> None: ... def call(self, command: Any, /, *args: Any) -> Any: ... + # TODO: Figure out what arguments the following `func` callbacks should accept def createcommand(self, name: str, func: Callable[..., object], /) -> None: ... if sys.platform != "win32": def createfilehandler(self, file: FileDescriptorLike, mask: int, func: Callable[..., object], /) -> None: ... @@ -1016,7 +1017,7 @@ class Tk(Misc, Wm): def dooneevent(self, flags: int = 0, /) -> int: ... def eval(self, script: str, /) -> str: ... def evalfile(self, fileName: str, /) -> str: ... - def exprboolean(self, s: str, /) -> int: ... + def exprboolean(self, s: str, /) -> Literal[0, 1]: ... def exprdouble(self, s: str, /) -> float: ... def exprlong(self, s: str, /) -> int: ... def exprstring(self, s: str, /) -> str: ... @@ -1032,10 +1033,15 @@ class Tk(Misc, Wm): def splitlist(self, arg, /) -> tuple[Incomplete, ...]: ... def unsetvar(self, *args, **kwargs): ... + if sys.version_info >= (3, 14): + @overload + def wantobjects(self) -> Literal[0, 1]: ... + else: + @overload + def wantobjects(self) -> bool: ... + @overload - def wantobjects(self) -> int: ... - @overload - def wantobjects(self, wantobjects: int, /) -> None: ... + def wantobjects(self, wantobjects: Literal[0, 1] | bool, /) -> None: ... def willdispatch(self) -> None: ... def Tcl(screenName: str | None = None, baseName: str | None = None, className: str = "Tk", useTk: bool = False) -> Tk: ...