Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
48 changes: 29 additions & 19 deletions stdlib/_tkinter.pyi
Original file line number Diff line number Diff line change
@@ -1,6 +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, Literal, final, overload
from typing_extensions import TypeAlias, deprecated

# _tkinter is meant to be only used internally by tkinter, but some tkinter
Expand Down Expand Up @@ -54,22 +55,23 @@ _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, /): ...
# 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, 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], /): ...
Comment on lines +61 to +66
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

See above.

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, /) -> Literal[0, 1]: ...
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: ...
Expand All @@ -81,15 +83,23 @@ 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): ...
if sys.version_info >= (3, 14):
@overload
def wantobjects(self) -> Literal[0, 1]: ...
else:
@overload
def wantobjects(self) -> bool: ...

@overload
def wantobjects(self, wantobjects: Literal[0, 1] | bool, /) -> None: ...
def willdispatch(self) -> None: ...
if sys.version_info >= (3, 12):
def gettrace(self, /) -> _TkinterTraceFunc | None: ...
Expand All @@ -112,7 +122,7 @@ TK_VERSION: Final[str]

@final
class TkttType:
def deletetimerhandler(self): ...
def deletetimerhandler(self) -> None: ...

if sys.version_info >= (3, 13):
def create(
Expand All @@ -125,7 +135,7 @@ if sys.version_info >= (3, 13):
sync: bool = False,
use: str | None = None,
/,
): ...
) -> TkappType: ...

else:
def create(
Expand All @@ -138,7 +148,7 @@ else:
sync: bool = False,
use: str | None = None,
/,
): ...
) -> TkappType: ...

def getbusywaitinterval() -> int: ...
def setbusywaitinterval(new_val: int, /) -> None: ...
39 changes: 24 additions & 15 deletions stdlib/tkinter/__init__.pyi
Original file line number Diff line number Diff line change
@@ -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
Expand Down Expand Up @@ -1005,34 +1005,43 @@ 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, /): ...
# TODO: Figure out what arguments the following `func` callbacks should accept
def createcommand(self, name: str, func: Callable[..., object], /) -> None: ...
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Are you sure that func takes arbitrary arguments? Maybe @Akuli, our resident tkinter expert has some insights. We should at least leave a TODO comment to check this.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It seems to be a callback that takes two arguments like in createfilehandler. But I decided to leave it like that for now because I wasn't sure about it.
I was only sure that it was Callable because there was a check for it in the code.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can you add a "TODO" comment to this and the other callables?

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It seems like the arguments are always passed as strings, but I might be missing something. Keyword arguments are never given, because they are not a thing in Tcl.

>>> import tkinter; r = tkinter.Tk(); r.withdraw()
''
>>> r.createcommand("foo", (lambda *args: print(args)))
>>> r.call("foo", 1, 2, 3)
('1', '2', '3')
'None'
>>> r.eval("foo 1 2 3")
('1', '2', '3')
'None'
>>> r.call("foo", [1, 2, 3])
('1 2 3',)
'None'
>>> r.eval("foo [list 1 2 3]")
('1 2 3',)
'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: ...
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same question here.

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], /): ...
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

And here.

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, /) -> Literal[0, 1]: ...
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): ...
if sys.version_info >= (3, 14):
@overload
def wantobjects(self) -> Literal[0, 1]: ...
else:
@overload
def wantobjects(self) -> bool: ...

@overload
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: ...
Expand Down