Skip to content

Commit 954ce8c

Browse files
authored
create _tkinter stub (#4372)
1 parent adcd691 commit 954ce8c

File tree

4 files changed

+141
-12
lines changed

4 files changed

+141
-12
lines changed

pyproject.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ extra_standard_library = [
1515
"_curses",
1616
"_markupbase",
1717
"_random",
18+
"_tkinter",
1819
"_weakrefset",
1920
"genericpath",
2021
"opcode",

stdlib/3/_tkinter.pyi

Lines changed: 93 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,93 @@
1+
from typing import Any, Tuple, Union
2+
3+
# _tkinter is meant to be only used internally by tkinter, but some tkinter
4+
# functions e.g. return _tkinter.Tcl_Obj objects. Tcl_Obj represents a Tcl
5+
# object that hasn't been converted to a string.
6+
#
7+
# There are not many ways to get Tcl_Objs from tkinter, and I'm not sure if the
8+
# only existing ways are supposed to return Tcl_Objs as opposed to returning
9+
# strings. Here's one of these things that return Tcl_Objs:
10+
#
11+
# >>> import tkinter
12+
# >>> text = tkinter.Text()
13+
# >>> text.tag_add('foo', '1.0', 'end')
14+
# >>> text.tag_ranges('foo')
15+
# (<textindex object: '1.0'>, <textindex object: '2.0'>)
16+
class Tcl_Obj:
17+
string: str # str(tclobj) returns this
18+
typename: str
19+
20+
class TclError(Exception): ...
21+
22+
# This class allows running Tcl code. Tkinter uses it internally a lot, and
23+
# it's often handy to drop a piece of Tcl code into a tkinter program. Example:
24+
#
25+
# >>> import tkinter, _tkinter
26+
# >>> tkapp = tkinter.Tk().tk
27+
# >>> isinstance(tkapp, _tkinter.TkappType)
28+
# True
29+
# >>> tkapp.call('set', 'foo', (1,2,3))
30+
# (1, 2, 3)
31+
# >>> tkapp.eval('return $foo')
32+
# '1 2 3'
33+
# >>>
34+
#
35+
# call args can be pretty much anything. Also, call(some_tuple) is same as call(*some_tuple).
36+
#
37+
# eval always returns str because _tkinter_tkapp_eval_impl in _tkinter.c calls
38+
# Tkapp_UnicodeResult, and it returns a string when it succeeds.
39+
class TkappType:
40+
# Please keep in sync with tkinter.Tk
41+
def call(self, __command: Union[str, Tuple[Any, ...]], *args: Any) -> str: ...
42+
def eval(self, __script: str) -> Any: ...
43+
adderrorinfo: Any
44+
createcommand: Any
45+
createfilehandler: Any
46+
createtimerhandler: Any
47+
deletecommand: Any
48+
deletefilehandler: Any
49+
dooneevent: Any
50+
evalfile: Any
51+
exprboolean: Any
52+
exprdouble: Any
53+
exprlong: Any
54+
exprstring: Any
55+
getboolean: Any
56+
getdouble: Any
57+
getint: Any
58+
getvar: Any
59+
globalgetvar: Any
60+
globalsetvar: Any
61+
globalunsetvar: Any
62+
interpaddr: Any
63+
loadtk: Any
64+
mainloop: Any
65+
quit: Any
66+
record: Any
67+
setvar: Any
68+
split: Any
69+
splitlist: Any
70+
unsetvar: Any
71+
wantobjects: Any
72+
willdispatch: Any
73+
74+
ALL_EVENTS: int
75+
FILE_EVENTS: int
76+
IDLE_EVENTS: int
77+
TIMER_EVENTS: int
78+
WINDOW_EVENTS: int
79+
80+
DONT_WAIT: int
81+
EXCEPTION: int
82+
READABLE: int
83+
WRITABLE: int
84+
85+
TCL_VERSION: str
86+
TK_VERSION: str
87+
88+
# TODO: figure out what these are (with e.g. help()) and get rid of Any
89+
TkttType: Any
90+
_flatten: Any
91+
create: Any
92+
getbusywaitinterval: Any
93+
setbusywaitinterval: Any

stdlib/3/tkinter/__init__.pyi

Lines changed: 44 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,18 @@
1+
import _tkinter
12
import sys
23
from enum import Enum
34
from tkinter.constants import * # noqa: F403
45
from types import TracebackType
56
from typing import Any, Callable, Dict, Generic, List, Optional, Tuple, Type, TypeVar, Union, overload
67
from typing_extensions import Literal, TypedDict
78

8-
TclError: Any
9+
TclError = _tkinter.TclError
910
wantobjects: Any
1011
TkVersion: Any
1112
TclVersion: Any
12-
READABLE: Any
13-
WRITABLE: Any
14-
EXCEPTION: Any
13+
READABLE = _tkinter.READABLE
14+
WRITABLE = _tkinter.WRITABLE
15+
EXCEPTION = _tkinter.EXCEPTION
1516

1617
# If a manual page mentions Tk_GetAnchor or refers to another manual page named
1718
# 'options', then it means this. Note that some ttk widgets have other things
@@ -142,6 +143,7 @@ def getboolean(s): ...
142143
# This class is the base class of all widgets. Don't use BaseWidget or Widget
143144
# for that because Tk doesn't inherit from Widget or BaseWidget.
144145
class Misc:
146+
tk: _tkinter.TkappType
145147
def destroy(self): ...
146148
def deletecommand(self, name): ...
147149
def tk_strictMotif(self, boolean: Optional[Any] = ...): ...
@@ -431,7 +433,6 @@ class Wm:
431433
class Tk(Misc, Wm):
432434
master: Optional[Any]
433435
children: Dict[str, Any]
434-
tk: Any
435436
def __init__(
436437
self,
437438
screenName: Optional[str] = ...,
@@ -441,11 +442,43 @@ class Tk(Misc, Wm):
441442
sync: bool = ...,
442443
use: Optional[str] = ...,
443444
) -> None: ...
444-
def loadtk(self) -> None: ...
445+
def loadtk(self) -> None: ... # differs from _tkinter.TkappType.loadtk
445446
def destroy(self) -> None: ...
446447
def readprofile(self, baseName: str, className: str) -> None: ...
447448
report_callback_exception: Callable[[Type[BaseException], BaseException, TracebackType], Any]
448-
def __getattr__(self, attr: str) -> Any: ...
449+
# Tk has __getattr__ so that tk_instance.foo falls back to tk_instance.tk.foo
450+
# Please keep in sync with _tkinter.TkappType
451+
call: Callable[..., str]
452+
eval: Callable[[str], Any]
453+
adderrorinfo: Any
454+
createcommand: Any
455+
createfilehandler: Any
456+
createtimerhandler: Any
457+
deletecommand: Any
458+
deletefilehandler: Any
459+
dooneevent: Any
460+
evalfile: Any
461+
exprboolean: Any
462+
exprdouble: Any
463+
exprlong: Any
464+
exprstring: Any
465+
getboolean: Any
466+
getdouble: Any
467+
getint: Any
468+
getvar: Any
469+
globalgetvar: Any
470+
globalsetvar: Any
471+
globalunsetvar: Any
472+
interpaddr: Any
473+
mainloop: Any
474+
quit: Any
475+
record: Any
476+
setvar: Any
477+
split: Any
478+
splitlist: Any
479+
unsetvar: Any
480+
wantobjects: Any
481+
willdispatch: Any
449482

450483
def Tcl(screenName: Optional[Any] = ..., baseName: Optional[Any] = ..., className: str = ..., useTk: bool = ...): ...
451484

@@ -908,8 +941,10 @@ class OptionMenu(Menubutton):
908941

909942
class Image:
910943
name: Any
911-
tk: Any
912-
def __init__(self, imgtype, name: Optional[Any] = ..., cnf=..., master: Optional[Any] = ..., **kw): ...
944+
tk: _tkinter.TkappType
945+
def __init__(
946+
self, imgtype, name: Optional[Any] = ..., cnf=..., master: Optional[Union[Misc, _tkinter.TkappType]] = ..., **kw
947+
): ...
913948
def __del__(self): ...
914949
def __setitem__(self, key, value): ...
915950
def __getitem__(self, key): ...

stdlib/3/tkinter/ttk.pyi

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
1+
import _tkinter
12
import sys
23
import tkinter
3-
from tkinter import Event
44
from typing import Any, Callable, List, Optional, overload
55
from typing_extensions import Literal
66

@@ -9,7 +9,7 @@ def setup_master(master: Optional[Any] = ...): ...
99

1010
class Style:
1111
master: Any
12-
tk: Any
12+
tk: _tkinter.TkappType
1313
def __init__(self, master: Optional[Any] = ...): ...
1414
def configure(self, style, query_opt: Optional[Any] = ..., **kw): ...
1515
def map(self, style, query_opt: Optional[Any] = ..., **kw): ...
@@ -154,7 +154,7 @@ class Treeview(Widget, tkinter.XView, tkinter.YView):
154154
self,
155155
tagname: str,
156156
sequence: Optional[str] = ...,
157-
callback: Optional[Callable[[Event[Treeview]], Optional[Literal["break"]]]] = ...,
157+
callback: Optional[Callable[[tkinter.Event[Treeview]], Optional[Literal["break"]]]] = ...,
158158
) -> str: ...
159159
@overload
160160
def tag_bind(self, tagname: str, sequence: Optional[str], callback: str) -> None: ...

0 commit comments

Comments
 (0)