GV

GeezerVison

The World Wide Web, restored to 800 pixels of glory.

Home|About|Gaming cabinet|Archives|How it works|Starter sites

On this site

  • Sign in
  • ActionsCI/CD and automation
  • CodespacesCloud development environments
  • All Features
  • Documentation
  • Training
  • Certifications
  • Build with Copilot
  • Customize Copilot
  • Integrations
  • Trending repos
  • GitHub Sponsors
  • Developer articles
  • Enterprises

This view

  • Original page
  • New address

GeezerVison is showing github.com — gh-154675: Improve import performance of ``tkinter`` library with lazy imports by sharktide · Pull Request #148409 · python/cpython

Conversation

@sharktide

@sharktide sharktide commented Apr 11, 2026 •
edited by bedevere-app Bot
Loading

Uh oh!

There was an error while loading. Please reload this page.

Copy link
Copy Markdown
Contributor

Similar to #109789 but for Tkinter
EDIT: I can’t generate a direct comparison graph currently, but expect a 20-30% performance increase.

  • Issue: Improve import time of various stdlib modules #137855
  • Issue: Improve import time of various stdlib modules #154675

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

danielhollas reacted with heart emoji
All reactions
  • ❤️ 1 reaction
sharktide and others added 6 commits April 11, 2026 08:55
@sharktide
Lazy import modules in tkinter __init__
f0e2f9b
@sharktide
Add _get_magic_re and _get_space_re functions.
4bcb491
@sharktide
Update usage in _stringify
995d6a1
@sharktide
Add docstring to new functions
44567a4
@sharktide
Format
0dfab78
@sharktide
Add NEWS entry
ce94f9e
@bedevere-app bedevere-app Bot added the awaiting review label Apr 11, 2026
@bedevere-app bedevere-app Bot mentioned this pull request Apr 11, 2026
Improve import time of various stdlib modules #109653
Closed
@sharktide
sharktide marked this pull request as draft April 12, 2026 00:04
@bedevere-app bedevere-app Bot removed the awaiting review label Apr 12, 2026
@sharktide
Move lazy import re down in the file
01000ea
danielhollas
danielhollas reviewed Apr 12, 2026
View reviewed changes
Comment thread Lib/tkinter/__init__.py Resolved

Uh oh!

There was an error while loading. Please reload this page.

Comment thread Lib/tkinter/__init__.py Resolved

Uh oh!

There was an error while loading. Please reload this page.

sharktide added 2 commits April 11, 2026 20:39
@sharktide
Reorder imports for clarity
1da6e7b
@sharktide
Stop lazy imported modules from appearing in __all__
f0bd1eb
@sharktide
sharktide marked this pull request as ready for review April 12, 2026 01:58
@bedevere-app bedevere-app Bot added the awaiting review label Apr 12, 2026
@sharktide

sharktide commented Apr 12, 2026

Copy link
Copy Markdown
Contributor Author

cc @AlexWaygood

All reactions

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

danielhollas
danielhollas reviewed Apr 12, 2026
View reviewed changes
Comment thread Lib/tkinter/__init__.py Resolved

Uh oh!

There was an error while loading. Please reload this page.

danielhollas
danielhollas reviewed Apr 12, 2026
View reviewed changes
Comment thread Lib/tkinter/__init__.py Resolved

Uh oh!

There was an error while loading. Please reload this page.

sharktide added 2 commits April 12, 2026 09:35
@sharktide
Remove lazy import from sys and types
e9803f4
@sharktide
Improved docstrings for new functions
8350043
@danielhollas

danielhollas commented Apr 12, 2026

Copy link
Copy Markdown
Contributor

@sharktide please also add a test verifying that the lazy modules are indeed not imported. See #144387 for how to do it.

All reactions

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

sharktide added 4 commits April 12, 2026 11:37
@sharktide
Add TestTkImportTime test class in MISC
2558665
@sharktide
Lazy import os and traceback
5674a95
@sharktide
Fix import in lazy import test
b78daf7
@sharktide
Update NEWS entry
e269325
picnixz
picnixz requested changes Apr 12, 2026
View reviewed changes

@picnixz picnixz left a comment

Copy link
Copy Markdown
Member

There was a problem hiding this comment.

Choose a reason for hiding this comment

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

EDIT: I can’t generate a direct comparison graph currently, but expect a 20-30% performance increase.

tkinter is not a common module while enum is and that's the rationale why we wanted to improve the import time of enum. I would also not say "expect a XX" increase without convincing arguments (it could be more, it could be less, but I don't think it's relevant to shoot a random number like that).

The change to import re adds more functions that are less readable IMO. I don't think it's worth it. For traceback it may be ok but os is a cheap module so I don't think it's worth either.

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

AlexWaygood reacted with thumbs up emoji
All reactions
  • 👍 1 reaction
@bedevere-app bedevere-app Bot added awaiting changes and removed awaiting review labels Apr 12, 2026
@bedevere-app

bedevere-app Bot commented Apr 12, 2026

Copy link
Copy Markdown

A Python core developer has requested some changes be made to your pull request before we can consider merging it. If you could please address their requests along with any other requests in other reviews from core developers that would be appreciated.

Once you have made the requested changes, please leave a comment on this pull request containing the phrase I have made the requested changes; please review again. I will then notify any core developers who have left a review that you're ready for them to take another look at this pull request.

All reactions

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

@danielhollas

danielhollas commented Apr 12, 2026

Copy link
Copy Markdown
Contributor

FWIW The 20-30% is likely in the right ballpark, here's the tuna-visualized output from running

python3.15 -Ximporttime -c 'import tkinter' 2> out

using uv's build of python3.15a8.

image

We should definitely keep traceback lazy as it import _colorize module. Otherwise agreed, not sure if the added complexity is worth it for this specific module.

sharktide reacted with thumbs up emoji
All reactions
  • 👍 1 reaction

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

@sharktide

sharktide commented Apr 12, 2026

Copy link
Copy Markdown
Contributor Author

The added complexity is minimal. It's just a very basic wrapper around a variable. I was able to make it in ~5 minutes on mobile.

All reactions

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

@picnixz

picnixz commented Apr 12, 2026

Copy link
Copy Markdown
Member

The added complexity is minimal.

It's not. It's about code readability. It's not because you did in 5 minutes that it's not complex. The problem is that we have more indirect references.

danielhollas and sharktide reacted with thumbs up emoji
All reactions
  • 👍 2 reactions

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

@hugovk

hugovk commented Apr 12, 2026

Copy link
Copy Markdown
Member

Here's a smaller diff that does it the way tokenize.py used to. It adds a fast functools import.

Details
diff --git a/Lib/tkinter/__init__.py b/Lib/tkinter/__init__.py
index 63340aafa77..f2313a5cfa9 100644
--- a/Lib/tkinter/__init__.py
+++ b/Lib/tkinter/__init__.py
@@ -33,6 +33,7 @@
 from tkinter.constants import *
 import collections
 import enum
+import functools
 import sys
 import types
 
@@ -51,28 +52,16 @@
 WRITABLE = _tkinter.WRITABLE
 EXCEPTION = _tkinter.EXCEPTION
 
-_magic_re = None
-_space_re = None
+_MAGIC_RE_PAT = r'([\\{}])'
+_SPACE_RE_PAT = r'(?a)([\s])'
+
+
+@functools.lru_cache
+def _compile(expr):
+    return re.compile(expr)
+
 
-def _get_magic_re():
-    """
-    Internal function that acts as a wrapper
-    for the re import to make it lazy.
-    """
-    global _magic_re
-    if _magic_re is None:
-        _magic_re = re.compile(r'([\\{}])')
-    return _magic_re
 
-def _get_space_re():
-    """
-    Internal function that acts as a wrapper
-    for the re import to make it lazy.
-    """
-    global _space_re
-    if _space_re is None:
-        _space_re = re.compile(r'([\s])', re.ASCII)
-    return _space_re
 
 def _join(value):
     """Internal function."""
@@ -83,7 +72,7 @@ def _stringify(value):
     if isinstance(value, (list, tuple)):
         if len(value) == 1:
             value = _stringify(value[0])
-            if _get_magic_re().search(value):
+            if _compile(_MAGIC_RE_PAT).search(value):
                 value = '{%s}' % value
         else:
             value = '{%s}' % _join(value)
@@ -94,14 +83,14 @@ def _stringify(value):
             value = str(value)
         if not value:
             value = '{}'
-        elif _get_magic_re().search(value):
+        elif _compile(_MAGIC_RE_PAT).search(value):
             # add '\' before special characters and spaces
-            value = _get_magic_re().sub(r'\\\1', value)
+            value = _compile(_MAGIC_RE_PAT).sub(r'\\\1', value)
             value = value.replace('\n', r'\n')
-            value = _get_space_re().sub(r'\\\1', value)
+            value = _compile(_SPACE_RE_PAT).sub(r'\\\1', value)
             if value[0] == '"':
                 value = '\\' + value
-        elif value[0] == '"' or _get_space_re().search(value):
+        elif value[0] == '"' or _compile(_SPACE_RE_PAT).search(value):
             value = '{%s}' % value
     return value
Here's imports of `main`, this PR, my suggestion on macOS. The latter two save about 1ms from avoiding `re`, might be more on other systems.
Details tkinter-pythonexe-import tkinter-pythonexe-import (1) tkinter-pythonexe-import (2)
All reactions

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

@AlexWaygood AlexWaygood changed the title gh-109653: Improve import preformance of tkinter library with lazy imports gh-109653: Improve import performance of tkinter library with lazy imports Apr 12, 2026
@sharktide

sharktide commented Apr 12, 2026 •
edited
Loading

Uh oh!

There was an error while loading. Please reload this page.

Copy link
Copy Markdown
Contributor Author

I just ran some tests in a headless windows environment, and the 3.15 main branch was 23ms, this pr was 18ms, @hugovk’s idea was also 18ms.

IMO it’s worth making these imports lazy, up to y’all which impl you like better. For readability, I prefer mine because it’s almost the same as the original code, save for the two wrapper functions, but they preserve the same names as before so it is easier to understand for me at least, but @hugovk’s idea is also just as good.

P.S. The system I tested on has low-end specs and it’s headless (I use it for cybersecurity testing), but nevertheless those times are what I got.

All reactions

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

@picnixz

picnixz commented Apr 12, 2026 •
edited
Loading

Uh oh!

There was an error while loading. Please reload this page.

Copy link
Copy Markdown
Member

I am honestly against the change for re and will still be -1 unless we revert those parts. I don't think it's worth changing the re part. The functools approach is a bit clearer to read but honestly I don't think it's really necessary. Removing the local imports to traceback and os are okayish (it'll be easier to read the source code), but otherwise, it just adds un-necessary complexity.

Importing tkinter is unlikely to be the bottleneck in tkinter-based applications.

All reactions

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

@github-actions

github-actions Bot commented May 18, 2026

Copy link
Copy Markdown

This PR is stale because it has been open for 30 days with no activity.

All reactions

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

@github-actions github-actions Bot added the stale Stale PR or inactive for long period of time. label May 18, 2026
@hugovk hugovk changed the title gh-109653: Improve import performance of tkinter library with lazy imports gh-137855: Improve import performance of tkinter library with lazy imports Jun 22, 2026
@bedevere-app bedevere-app Bot mentioned this pull request Jun 22, 2026
Improve import time of various stdlib modules #137855
Closed
@github-actions github-actions Bot removed the stale Stale PR or inactive for long period of time. label Jun 23, 2026
@hugovk hugovk changed the title gh-137855: Improve import performance of tkinter library with lazy imports gh-154675: Improve import performance of tkinter library with lazy imports Jul 25, 2026
@bedevere-app bedevere-app Bot mentioned this pull request Jul 25, 2026
Improve import time of various stdlib modules #154675
Open
@ambv

ambv commented Oct 20, 2026 •
edited
Loading

Uh oh!

There was an error while loading. Please reload this page.

Copy link
Copy Markdown
Contributor

This PR is superseded by #156841, a newer open pull request for the same issue (gh-154675), and it no longer merges cleanly. Closing to cull the number of open pull requests. Do not reopen this pull request without getting a go-ahead from a triager or core developer.

Sorry, incorrectly flagged as a duplicate.

All reactions

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

@ambv ambv closed this Oct 20, 2026
@ambv ambv reopened this Oct 21, 2026
@bedevere-app bedevere-app Bot added the type-feature A feature request or enhancement label Oct 21, 2026
@read-the-docs-community

read-the-docs-community Bot commented Oct 21, 2026

Copy link
Copy Markdown

Documentation build overview

📚 cpython-previews | 🛠️ Build #35284769 | 📁 Comparing e269325 against main (1277a5e)

  🔍 Preview build  

337 files changed · + 1 added · ± 317 modified · - 19 deleted

+ Added

  • library/asyncio-policy.html

± Modified

  • glossary.html
  • index.html
  • license.html
  • py-modindex.html
  • _static/tachyon-example-heatmap.html
  • c-api/allocation.html
  • c-api/arg.html
  • c-api/buffer.html
  • c-api/bytearray.html
  • c-api/bytes.html
  • and 307 more...

- Deleted

  • builtins/constants.html
  • builtins/exceptions.html
  • builtins/functions.html
  • builtins/index.html
  • builtins/stdtypes.html
  • builtins/threadsafety.html
  • builtins/time-complexity.html
  • c-api/sentinel.html
  • c-api/slots.html
  • deprecations/pending-removal-in-3.21.html
  • and 9 more...
All reactions

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Reviewers

@picnixz picnixz picnixz requested changes
+1 more reviewer
@danielhollas danielhollas danielhollas left review comments
Reviewers whose approvals may not affect merge requirements

Uh oh!

There was an error while loading. Please reload this page.

Assignees

No one assigned

Labels

awaiting changes type-feature A feature request or enhancement

Projects

None yet

Milestone

No milestone

Development

Successfully merging this pull request may close these issues.

Uh oh!

There was an error while loading. Please reload this page.

5 participants

@sharktide @danielhollas @picnixz @hugovk @ambv
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
You are visitor 01402503 — GeezerVison does not store the pages you look up.
Best viewed with Netscape Navigator 4.7 or Internet Explorer 6 at 800×600. No cookies required.