You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
InterpreterPoolExecutor does not work as replacement of ThreadPoolExecutor. #136603
Exception: AttributeError: module '__main__' has no attribute 'fib'
The above exception was the direct cause of the following exception:
concurrent.interpreters.NotShareableError: object could not be unpickled
The above exception was the direct cause of the following exception:
Traceback (most recent call last):
File "/Users/xxxx/oss/cpython/op.py", line 14, in <module>
data = future.result()
File "/Users/xxxx/oss/cpython/Lib/concurrent/futures/_base.py", line 443, in resultreturnself.__get_result()
~~~~~~~~~~~~~~~~~^^
File "/Users/xxxx/oss/cpython/Lib/concurrent/futures/_base.py", line 395, in __get_resultraiseself._exception
File "/Users/xxxx/oss/cpython/Lib/concurrent/futures/thread.py", line 86, in run
result = ctx.run(self.task)
File "/Users/denny.na/oss/cpython/Lib/concurrent/futures/interpreter.py", line 85, in runreturnself.interp.call(do_call, self.results, *task)
~~~~~~~~~~~~~~~~^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/Users/xxxx/oss/cpython/Lib/concurrent/interpreters/__init__.py", line 233, in callreturnself._call(callable, args, kwargs)
~~~~~~~~~~^^^^^^^^^^^^^^^^^^^^^^^^
File "/Users/xxxx/oss/cpython/Lib/concurrent/interpreters/__init__.py", line 215, in _call
res, excinfo = _interpreters.call(self._id, callable, args, kwargs, restrict=True)
~~~~~~~~~~~~~~~~~~^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^concurrent.interpreters.NotShareableError: args not shareable
@xuantengh
I am waiting for @ericsnowcurrently 's reply. If this is the intention, most people will treat InterpreterPoolExecutor as the same as ThreadPoolExecutor, but actual behavior does not seem to be so; it should be documented.
But if it is not intended, it should be resolved before officially releasing 3.14.
As fib accesses the global scope to get itself it won't work. Thx to @efimov-mikhail for his example. I think we should consider adding some note to docs/howto about subinterpreters, since recursive functions are pretty commonly used for calculations that we want to parallelise.
Reacted by Mikhail Efimov, Donghee Na, Xuanteng Huang and ClericPy
I think we should consider adding some note to docs/howto about subinterpreters, since recursive functions are pretty commonly used for calculations that we want to parallelise.
There used to be a comment in concurrent.futures.rst for InterpreterPoolExecutor saying: Functions defined in the main module cannot be pickled and thus cannot be used.
I think we should consider adding some note to docs/howto about subinterpreters, since recursive functions are pretty commonly used for calculations that we want to parallelise.
Maybe I can file a PR for this?
It would be great, but it totally needs prior discussion. I think we should add a big section about recipes with subinterpreters, because there are more problems, than just defining recursive functions. E.g. top-level imports don't work either for the same reason. We should define preferred way to handle all these cases (ofc the discussion should involve Eric Snow and others involved in subinterpreters). We need to open another issue (or a discuss.python.org topic, potentially) :)
I clarified the issue that I met at #136659 (comment)
I think that we can reduce the scope of the issue because it is okay to run from Python 3.14b4 with __name__ == '__main__' idiom.
Activity
corona10 commentedon Jul 13, 2025
cc @hugovk We may need to add label release blocker for 3.14
xuantengh commentedon Jul 13, 2025
I think this is because
do_callis treated as a stateful function that cannot be shared between multiple interpreters:The
_interp_call_packfunction will check whether the function is stateless:cpython/Modules/_interpretersmodule.c
Lines 467 to 488 in 42b251b
where
do_callfails due to:cpython/Objects/codeobject.c
Lines 2006 to 2008 in 42b251b
And the unbound vars seem to be:
['BaseException', 'interpreters', 'print', 'sys', 'traceback']corona10 commentedon Jul 13, 2025
@xuantengh
I am waiting for @ericsnowcurrently 's reply. If this is the intention, most people will treat InterpreterPoolExecutor as the same as ThreadPoolExecutor, but actual behavior does not seem to be so; it should be documented.
But if it is not intended, it should be resolved before officially releasing 3.14.
efimov-mikhail commentedon Jul 13, 2025
JFTR: it works if we slightly rewrite this code:
Tapeline commentedon Jul 13, 2025
As
fibaccesses the global scope to get itself it won't work. Thx to @efimov-mikhail for his example. I think we should consider adding some note to docs/howto about subinterpreters, since recursive functions are pretty commonly used for calculations that we want to parallelise.xuantengh commentedon Jul 13, 2025
Maybe I can file a PR for this?
paultiq commentedon Jul 13, 2025
There used to be a comment in concurrent.futures.rst for InterpreterPoolExecutor saying:
Functions defined in the main module cannot be pickled and thus cannot be used.This comment was removed in #133957
Tapeline commentedon Jul 13, 2025
It would be great, but it totally needs prior discussion. I think we should add a big section about recipes with subinterpreters, because there are more problems, than just defining recursive functions. E.g. top-level imports don't work either for the same reason. We should define preferred way to handle all these cases (ofc the discussion should involve Eric Snow and others involved in subinterpreters). We need to open another issue (or a discuss.python.org topic, potentially) :)
efimov-mikhail commentedon Jul 13, 2025
Maybe we should start a d.p.o. thread on "How to teach subinterpreters" or something similar?
corona10 commentedon Jul 13, 2025
Can we just wait Eric's comment before do something?
corona10 commentedon Jul 14, 2025
I clarified the issue that I met at #136659 (comment)
I think that we can reduce the scope of the issue because it is okay to run from Python 3.14b4 with
__name__ == '__main__'idiom.So it looks reasonable to close this issue and focus on #136659
cc @ericsnowcurrently