python / python/cpython

InterpreterPoolExecutor Failure When `__name__ == '__main__'`: Idiom Not Used

オープン
#136,659 コメント 7 件 リアクション 0 件 担当者 1 名 GitHub で見る

@ericsnowcurrently がすでに取り組んでいます。

2025年7月14日 から。

stdlib topic-subinterpreters type-bug
主要言語
Python
スター
77.2k
フォーク
35.9k
PR マージ指標
PR 指標を取得中

説明

Bug report

Bug description:

From @corona10:

import concurrent.futures
from concurrent.futures import InterpreterPoolExecutor, ThreadPoolExecutor


def fib(n):
    if n < 2:
        return n
    return fib(n-1) + fib(n-2)

with InterpreterPoolExecutor(max_workers=5) as executor:
    futures = {executor.submit(fib, n): n for n in range(10)}
    for future in concurrent.futures.as_completed(futures):
        n = futures[future]
        data = future.result()
        print(f"fib({n}): {data}")

This fails with:

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:
...

The failure goes away if the "executable" part of the script is wrapped in an if __name__ == '__main__': block.

This is because of how Interpreter.call() sends functions between interpreters. It mostly pickles them. On the other side, functions are looked up by name in the defining module. For the __main__ module, this is a problem.

The original script only runs in the main interpreter, so the function will not be found in the other interpreter's __main__ module. We must run the script in the other interpreter, but without polluting __main__ and avoiding executing anything but the desired function definition. We partially solve this by calling runpy.run_path() with a different module name than __main__.

multiprocessing faces a similar situation. See the "Safe importing of main module" entry in the https://docs.python.org/3/library/multiprocessing.html#the-spawn-and-forkserver-start-methods section.

The solution here is probably the same: document that users should apply if __name__ == '__main__':. We may also be able to accommodate this in the code somewhat, since we know when we are running the script in the other interpreter. However, there's a limit to how much we can do so without introducing nontrivial complexity.

CPython versions tested on:

CPython main branch

Operating systems tested on:

No response

コントリビューションガイド

コントリビューションガイドを開く

はじめの一歩

  1. issue を最後まで読み、次にプロジェクトのコントリビューションガイドを読みます。
  2. 着手することを issue にコメントします — 二人が同じ作業をするのを防げます。
  3. リポジトリをフォークし、ブランチを切って変更します。
  4. issue 番号を参照したプルリクエストを送ります。

評価

この issue はまだ評価されていません。

新しい issue をメールで受け取る

初心者向けの GitHub issue を短くまとめたダイジェスト。