[3.15] gh-150579: use lazy imports for concurrent.futures (GH-150585) (#152975)

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.
(cherry picked from commit 423ae0ff36)

Signed-off-by: Henry Schreiner <henryfs@princeton.edu>
Co-authored-by: Henry Schreiner <henryfs@princeton.edu>
Co-authored-by: Gregory P. Smith <greg@krypto.org>
This commit is contained in:
Miss Islington (bot)
2026-07-04 05:20:49 +02:00
committed by GitHub
parent 8d08232817
commit 2dd5d4e1ec
2 changed files with 6 additions and 18 deletions
+4 -18
View File
@@ -17,6 +17,9 @@ from concurrent.futures._base import (FIRST_COMPLETED,
wait,
as_completed)
lazy from .process import ProcessPoolExecutor
lazy from .thread import ThreadPoolExecutor
__all__ = [
'FIRST_COMPLETED',
'FIRST_EXCEPTION',
@@ -40,26 +43,9 @@ except ImportError:
_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}")
@@ -0,0 +1,2 @@
:mod:`concurrent.futures` now uses lazy imports for its executor submodules
instead of a module ``__getattr__`` hook.