Repository navigation
Add concurrent.futures.InterpreterPoolExecutor #124694
Copy link
Copy link
Closed
Labels
3.14bugs and security fixesbugs and security fixesstdlibStandard Library Python modules in the Lib/ directoryStandard Library Python modules in the Lib/ directorytopic-subinterpreterstype-featureA feature request or enhancementA feature request or enhancement
Description
Feature or enhancement
Proposal:
While we wait on PEP 734, there's nothing blocking us from adding a new executor for multiple interpreters. Doing so would allow people to start trying them out. (I wish I had thought of this for 3.13!)
My planned design:
- mostly built on top of
ThreadPoolExecutor - callables (and args) passed as initializer or to
submit()ormap()will be pickled (same asProcessPoolExecutor) - initializer and
submit()arg can be a script instead of a callable (a script formap()doesn't make sense since there are no args) __init__()will take a new "shared" arg that corresponds to whatInterpreter.prepare_main()takes in PEP 734, to allow each worker interpreter to share some data
In the future we could support a more efficient "sharing" scheme than pickle. When (or if) PEP 734 is accepted, we can refactor the executor to use the interpreters module rather than using _interpreters directly.
Open questions:
- reconstitute and raise uncaught exceptions from running in the interpreter (like we do for
ProcessPoolExecutor)? - (optionally?) exec functions against main instead of the their original module, i.e. use the body of the function as a script?
Has this already been discussed elsewhere?
This is a minor feature, which does not need previous discussion elsewhere
Links to previous discussion of this feature:
No response
Linked PRs
- gh-124694: Add concurrent.futures.InterpreterPoolExecutor #124548
- gh-124694: In test_interpreter_pool, Restore the Asyncio Event Loop Policy During Cleanup #125708
- gh-124694: Document missing ctxkwargs argument in ThreadPoolExecutor #134321
- gh-124694: Add versionadded note to InterpreterPoolExecutor #140468
- [3.14] gh-124694: Add versionadded note to InterpreterPoolExecutor (GH-140468) #140605
- [3.15] gh-124694: Document missing ctxkwargs argument in ThreadPoolExecutor (GH-134321) #160459
- [3.14] gh-124694: Document missing ctxkwargs argument in ThreadPoolExecutor (GH-134321) #160460
Reactions are currently unavailable
Metadata
Metadata
Assignees
Labels
3.14bugs and security fixesbugs and security fixesstdlibStandard Library Python modules in the Lib/ directoryStandard Library Python modules in the Lib/ directorytopic-subinterpreterstype-featureA feature request or enhancementA feature request or enhancement
Projects
- StatusShow more project fieldsDone
Activity
gh-124694: Add concurrent.futures.InterpreterPoolExecutor (gh-124548)
gh-124694: In test_interpreter_pool, Restore the Asyncio Event Loop P…
pythongh-124694: Add concurrent.futures.InterpreterPoolExecutor (pyth…
pythongh-124694: In test_interpreter_pool, Restore the Asyncio Event …
pythongh-124694: Document missing ctxkwargs argument in ThreadPoolExe…
henryiii commentedon Jul 31, 2025
Does the pickling work?I've been trying several things on pickable arguments, but I keep gettingconcurrent.interpreters.NotShareableError: args not shareable. My first thought was this:But I get that error. Then I tried explicitly pickling:
But I still get this error:
Also, I'm not sure why the
Exception: AttributeError: module '__main__' has no attribute 'identity'without a traceback is at the top. Other executors are fine with code.I was actually trying to use this in a test for boost-histogram, trying to pass a numpy array in and a boost-histogram object back out, but it fails even with byte strings from pickle above.
Edit: I do think it's an issue with the import like seen at the top, and the traceback is a red herring. The tests version of this list
Exception: ModuleNotFoundError: No module named 'tests'at the top. So it's not able to import the function to run. I thought__main__support was fixed?It seems the subinterpreter's don't inherit the current
sys.path? Using pytest 7'spythonpathsetting doesn't work, they aren't picking up the added test paths.If I put the function inside my package, I get
ImportError: NumPy: dtype is already registeredwhich I think that's occurring when pybind11 is registering my dtype. I've opened an issue pybind/pybind11#5781; if I manually skip over that, it looks like numpy doesn't support subinterpreters yet, so I'd not really be able to do much with it yet.pythongh-124694: Add versionadded note to InterpreterPoolExecutor
gh-124694: Add versionadded note to InterpreterPoolExecutor (#140468)
pythongh-124694: Add versionadded note to InterpreterPoolExecutor (py…
[3.14] gh-124694: Add versionadded note to InterpreterPoolExecutor (G…
pythongh-124694: Add versionadded note to InterpreterPoolExecutor (py…
gh-124694: Document missing ctxkwargs argument in ThreadPoolExecutor (#…
[3.15] gh-124694: Document missing ctxkwargs argument in ThreadPoolEx…
[3.14] gh-124694: Document missing ctxkwargs argument in ThreadPoolEx…