wait,
as_completed)
-__all__ = (
+__all__ = [
'FIRST_COMPLETED',
'FIRST_EXCEPTION',
'ALL_COMPLETED',
'Executor',
'wait',
'as_completed',
- 'InterpreterPoolExecutor',
'ProcessPoolExecutor',
'ThreadPoolExecutor',
-)
+]
+
+
+try:
+ import _interpreters
+except ImportError:
+ _interpreters = None
+
+if _interpreters:
+ __all__.append('InterpreterPoolExecutor')
def __dir__():
global ProcessPoolExecutor, ThreadPoolExecutor, InterpreterPoolExecutor
if name == 'ProcessPoolExecutor':
- from .process import ProcessPoolExecutor as pe
- ProcessPoolExecutor = pe
- return pe
+ from .process import ProcessPoolExecutor
+ return ProcessPoolExecutor
if name == 'ThreadPoolExecutor':
- from .thread import ThreadPoolExecutor as te
- ThreadPoolExecutor = te
- return te
+ from .thread import ThreadPoolExecutor
+ return ThreadPoolExecutor
- if name == 'InterpreterPoolExecutor':
- try:
- from .interpreter import InterpreterPoolExecutor as ie
- except ModuleNotFoundError:
- ie = InterpreterPoolExecutor = None
- else:
- InterpreterPoolExecutor = ie
- return ie
+ if _interpreters and name == 'InterpreterPoolExecutor':
+ from .interpreter import InterpreterPoolExecutor
+ return InterpreterPoolExecutor
raise AttributeError(f"module {__name__!r} has no attribute {name!r}")
import contextlib
import io
import os
+import subprocess
import sys
+import textwrap
import time
import unittest
from concurrent.futures.interpreter import BrokenInterpreterPool
# Weak references don't cross between interpreters.
raise unittest.SkipTest('not applicable')
+ @support.requires_subprocess()
+ def test_import_interpreter_pool_executor(self):
+ # Test the import behavior normally if _interpreters is unavailable.
+ code = textwrap.dedent("""
+ import sys
+ # Set it to None to emulate the case when _interpreter is unavailable.
+ sys.modules['_interpreters'] = None
+ from concurrent import futures
+
+ try:
+ futures.InterpreterPoolExecutor
+ except AttributeError:
+ pass
+ else:
+ print('AttributeError not raised!', file=sys.stderr)
+ sys.exit(1)
+
+ try:
+ from concurrent.futures import InterpreterPoolExecutor
+ except ImportError:
+ pass
+ else:
+ print('ImportError not raised!', file=sys.stderr)
+ sys.exit(1)
+
+ from concurrent.futures import *
+
+ if 'InterpreterPoolExecutor' in globals():
+ print('InterpreterPoolExecutor should not be imported!',
+ file=sys.stderr)
+ sys.exit(1)
+ """)
+
+ cmd = [sys.executable, '-c', code]
+ p = subprocess.run(cmd, capture_output=True)
+ self.assertEqual(p.returncode, 0, p.stderr.decode())
+ self.assertEqual(p.stdout.decode(), '')
+ self.assertEqual(p.stderr.decode(), '')
+
class AsyncioTest(InterpretersMixin, testasyncio_utils.TestCase):