https://github.com/python/cpython/commit/423ae0ff36c6485f722e0fe3274124dc3df09862
commit: 423ae0ff36c6485f722e0fe3274124dc3df09862
branch: main
author: Henry Schreiner <[email protected]>
committer: gpshead <[email protected]>
date: 2026-07-03T18:11:16Z
summary:

gh-150579: use lazy imports for concurrent.futures (GH-150585)

This module has a manual lazy import hack using `__getattr__`. Now that lazy 
imports exist and cannot be disabled, this could use lazy imports instead.

Key differences: this will now show up in sys.lazy_modules when accessed. Error 
messages should be a bit better without the wrapper `__getattr__` involved.  
That's the only differences I can think of.

Signed-off-by: Henry Schreiner <[email protected]>
Co-authored-by: Gregory P. Smith <[email protected]>

files:
A Misc/NEWS.d/next/Library/2026-07-03-17-29-34.gh-issue-150579.0tLpQukIU.rst
M Lib/concurrent/futures/__init__.py

diff --git a/Lib/concurrent/futures/__init__.py 
b/Lib/concurrent/futures/__init__.py
index d6ac4b3e0b675f..5d53a5ac50931d 100644
--- a/Lib/concurrent/futures/__init__.py
+++ b/Lib/concurrent/futures/__init__.py
@@ -17,6 +17,9 @@
                                       wait,
                                       as_completed)
 
+lazy from .process import ProcessPoolExecutor
+lazy from .thread import ThreadPoolExecutor
+
 __all__ = [
     'FIRST_COMPLETED',
     'FIRST_EXCEPTION',
@@ -40,26 +43,9 @@
     _interpreters = None
 
 if _interpreters:
+    lazy from .interpreter import InterpreterPoolExecutor  # noqa: F401
     __all__.append('InterpreterPoolExecutor')
 
 
 def __dir__():
     return __all__ + ['__author__', '__doc__']
-
-
-def __getattr__(name):
-    global ProcessPoolExecutor, ThreadPoolExecutor, InterpreterPoolExecutor
-
-    if name == 'ProcessPoolExecutor':
-        from .process import ProcessPoolExecutor
-        return ProcessPoolExecutor
-
-    if name == 'ThreadPoolExecutor':
-        from .thread import ThreadPoolExecutor
-        return ThreadPoolExecutor
-
-    if _interpreters and name == 'InterpreterPoolExecutor':
-        from .interpreter import InterpreterPoolExecutor
-        return InterpreterPoolExecutor
-
-    raise AttributeError(f"module {__name__!r} has no attribute {name!r}")
diff --git 
a/Misc/NEWS.d/next/Library/2026-07-03-17-29-34.gh-issue-150579.0tLpQukIU.rst 
b/Misc/NEWS.d/next/Library/2026-07-03-17-29-34.gh-issue-150579.0tLpQukIU.rst
new file mode 100644
index 00000000000000..7aff384431edc7
--- /dev/null
+++ b/Misc/NEWS.d/next/Library/2026-07-03-17-29-34.gh-issue-150579.0tLpQukIU.rst
@@ -0,0 +1,2 @@
+:mod:`concurrent.futures` now uses lazy imports for its executor submodules
+instead of a module ``__getattr__`` hook.

_______________________________________________
Python-checkins mailing list -- [email protected]
To unsubscribe send an email to [email protected]
https://mail.python.org/mailman3//lists/python-checkins.python.org
Member address: [email protected]

Reply via email to