From f0e2f9b2b7c1bb1e19ed30cfbd8393859b8b6bb4 Mon Sep 17 00:00:00 2001 From: Rihaan Meher Date: Sat, 11 Apr 2026 08:55:54 -0500 Subject: [PATCH 1/9] Lazy import modules in tkinter __init__ --- Lib/tkinter/__init__.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/Lib/tkinter/__init__.py b/Lib/tkinter/__init__.py index ba8365f56c37a7..0c92fa1eb1f49a 100644 --- a/Lib/tkinter/__init__.py +++ b/Lib/tkinter/__init__.py @@ -30,15 +30,15 @@ tk.mainloop() """ -import collections -import enum +lazy import collections +lazy import enum import sys -import types +lazy import types import _tkinter # If this fails your Python may not be configured for Tk TclError = _tkinter.TclError from tkinter.constants import * -import re +lazy import re wantobjects = 1 _debug = False # set to True to print executed Tcl/Tk commands From 4bcb4911a80c01e8cdb6faafa48cc9bcae916e91 Mon Sep 17 00:00:00 2001 From: Rihaan Meher Date: Sat, 11 Apr 2026 09:00:21 -0500 Subject: [PATCH 2/9] Add _get_magic_re and _get_space_re functions. --- Lib/tkinter/__init__.py | 18 ++++++++++++++---- 1 file changed, 14 insertions(+), 4 deletions(-) diff --git a/Lib/tkinter/__init__.py b/Lib/tkinter/__init__.py index 0c92fa1eb1f49a..a7ea453e407817 100644 --- a/Lib/tkinter/__init__.py +++ b/Lib/tkinter/__init__.py @@ -50,10 +50,20 @@ WRITABLE = _tkinter.WRITABLE EXCEPTION = _tkinter.EXCEPTION - -_magic_re = re.compile(r'([\\{}])') -_space_re = re.compile(r'([\s])', re.ASCII) - +_magic_re = None +_space_re = None + +def _get_magic_re(): + global _magic_re + if _magic_re is None: + _magic_re = re.compile(r'([\\{}])') + return _magic_re + +def _get_space_re(): + global _space_re + if _space_re is None: + _space_re = re.compile(r'([\s])', re.ASCII) + return _space_re def _join(value): """Internal function.""" From 995d6a1e736d7201d2741ad7fd329cad32293cc8 Mon Sep 17 00:00:00 2001 From: Rihaan Meher Date: Sat, 11 Apr 2026 09:03:12 -0500 Subject: [PATCH 3/9] Update usage in _stringify --- Lib/tkinter/__init__.py | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/Lib/tkinter/__init__.py b/Lib/tkinter/__init__.py index a7ea453e407817..9da383b54a4402 100644 --- a/Lib/tkinter/__init__.py +++ b/Lib/tkinter/__init__.py @@ -75,7 +75,7 @@ def _stringify(value): if isinstance(value, (list, tuple)): if len(value) == 1: value = _stringify(value[0]) - if _magic_re.search(value): + if _get_magic_re().search(value): value = '{%s}' % value else: value = '{%s}' % _join(value) @@ -86,14 +86,14 @@ def _stringify(value): value = str(value) if not value: value = '{}' - elif _magic_re.search(value): + elif _get_magic_re().search(value): # add '\' before special characters and spaces - value = _magic_re.sub(r'\\\1', value) + value = _get_magic_re().sub(r'\\\1', value) value = value.replace('\n', r'\n') - value = _space_re.sub(r'\\\1', value) + value = _get_space_re().sub(r'\\\1', value) if value[0] == '"': value = '\\' + value - elif value[0] == '"' or _space_re.search(value): + elif value[0] == '"' or _get_space_re().search(value): value = '{%s}' % value return value From 44567a4dd02b8320d1202401a7066db139be8d4d Mon Sep 17 00:00:00 2001 From: Rihaan Meher Date: Sat, 11 Apr 2026 09:06:16 -0500 Subject: [PATCH 4/9] Add docstring to new functions --- Lib/tkinter/__init__.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/Lib/tkinter/__init__.py b/Lib/tkinter/__init__.py index 9da383b54a4402..3ae8ce2c33cfec 100644 --- a/Lib/tkinter/__init__.py +++ b/Lib/tkinter/__init__.py @@ -54,12 +54,14 @@ _space_re = None def _get_magic_re(): + """Internal function.""" global _magic_re if _magic_re is None: _magic_re = re.compile(r'([\\{}])') return _magic_re def _get_space_re(): + """Internal function.""" global _space_re if _space_re is None: _space_re = re.compile(r'([\s])', re.ASCII) From 0dfab7876fd3b651801d1c312a128b3b70c6904b Mon Sep 17 00:00:00 2001 From: Rihaan Meher Date: Sat, 11 Apr 2026 09:10:30 -0500 Subject: [PATCH 5/9] Format --- Lib/tkinter/__init__.py | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/Lib/tkinter/__init__.py b/Lib/tkinter/__init__.py index 3ae8ce2c33cfec..75bc42d092e073 100644 --- a/Lib/tkinter/__init__.py +++ b/Lib/tkinter/__init__.py @@ -29,16 +29,16 @@ button.pack(side=BOTTOM) tk.mainloop() """ +import _tkinter # If this fails your Python may not be configured for Tk +from tkinter.constants import * lazy import collections lazy import enum -import sys +lazy import sys lazy import types +lazy import re -import _tkinter # If this fails your Python may not be configured for Tk TclError = _tkinter.TclError -from tkinter.constants import * -lazy import re wantobjects = 1 _debug = False # set to True to print executed Tcl/Tk commands @@ -71,7 +71,6 @@ def _join(value): """Internal function.""" return ' '.join(map(_stringify, value)) - def _stringify(value): """Internal function.""" if isinstance(value, (list, tuple)): From ce94f9ea6af039ad648380395061f97d447eedb9 Mon Sep 17 00:00:00 2001 From: sharktide Date: Sat, 11 Apr 2026 18:49:57 -0500 Subject: [PATCH 6/9] Add NEWS entry --- .../next/Library/2026-04-11-18-49-40.gh-issue-109653.VXU-w8.rst | 2 ++ 1 file changed, 2 insertions(+) create mode 100644 Misc/NEWS.d/next/Library/2026-04-11-18-49-40.gh-issue-109653.VXU-w8.rst diff --git a/Misc/NEWS.d/next/Library/2026-04-11-18-49-40.gh-issue-109653.VXU-w8.rst b/Misc/NEWS.d/next/Library/2026-04-11-18-49-40.gh-issue-109653.VXU-w8.rst new file mode 100644 index 00000000000000..0302faf9c88efa --- /dev/null +++ b/Misc/NEWS.d/next/Library/2026-04-11-18-49-40.gh-issue-109653.VXU-w8.rst @@ -0,0 +1,2 @@ +Reduce the import time of :mod:`tkinter` with lazy imports. Patch by Rihaan +Meher. From 01000ea3176d3310d3b9785cb58f648814a91c23 Mon Sep 17 00:00:00 2001 From: Rihaan Meher Date: Sat, 11 Apr 2026 19:18:21 -0500 Subject: [PATCH 7/9] Move lazy import re down in the file --- Lib/tkinter/__init__.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/Lib/tkinter/__init__.py b/Lib/tkinter/__init__.py index 75bc42d092e073..29963768b23dad 100644 --- a/Lib/tkinter/__init__.py +++ b/Lib/tkinter/__init__.py @@ -36,7 +36,6 @@ lazy import enum lazy import sys lazy import types -lazy import re TclError = _tkinter.TclError @@ -46,6 +45,8 @@ TkVersion = float(_tkinter.TK_VERSION) TclVersion = float(_tkinter.TCL_VERSION) +lazy import re + READABLE = _tkinter.READABLE WRITABLE = _tkinter.WRITABLE EXCEPTION = _tkinter.EXCEPTION From 1da6e7b7cc0063fc347b5a24b2d0730761335bf2 Mon Sep 17 00:00:00 2001 From: Rihaan Meher Date: Sat, 11 Apr 2026 20:39:44 -0500 Subject: [PATCH 8/9] Reorder imports for clarity --- Lib/tkinter/__init__.py | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/Lib/tkinter/__init__.py b/Lib/tkinter/__init__.py index 29963768b23dad..1ceae22a15704c 100644 --- a/Lib/tkinter/__init__.py +++ b/Lib/tkinter/__init__.py @@ -31,12 +31,12 @@ """ import _tkinter # If this fails your Python may not be configured for Tk from tkinter.constants import * +import collections +import enum -lazy import collections -lazy import enum lazy import sys lazy import types - +lazy import re TclError = _tkinter.TclError wantobjects = 1 @@ -45,8 +45,6 @@ TkVersion = float(_tkinter.TK_VERSION) TclVersion = float(_tkinter.TCL_VERSION) -lazy import re - READABLE = _tkinter.READABLE WRITABLE = _tkinter.WRITABLE EXCEPTION = _tkinter.EXCEPTION From f0bd1ebd7c4c6ac7126d7fc8332e59744427d6fc Mon Sep 17 00:00:00 2001 From: Rihaan Meher Date: Sat, 11 Apr 2026 20:46:27 -0500 Subject: [PATCH 9/9] Stop lazy imported modules from appearing in __all__ --- Lib/tkinter/__init__.py | 1 + 1 file changed, 1 insertion(+) diff --git a/Lib/tkinter/__init__.py b/Lib/tkinter/__init__.py index 1ceae22a15704c..9ba3caeda85d8c 100644 --- a/Lib/tkinter/__init__.py +++ b/Lib/tkinter/__init__.py @@ -5104,6 +5104,7 @@ def _test(): __all__ = [name for name, obj in globals().items() if not name.startswith('_') and not isinstance(obj, types.ModuleType) + and not isinstance(obj, types.LazyImportType) and name not in {'wantobjects'}] if __name__ == '__main__':