0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

ProcessPoolExecutor をデバッグ実行すると AttributeError が出る

Posted at

現象

Windows の Visual Studio Code の拡張機能を使って Python を F5 キーでデバッグ実行した時、 ProcessPoolExecutor を使っていると、プログラム終了時に以下のようなエラーが出る。

File "C:\Program Files\WindowsApps\PythonSoftwareFoundation.Python.3.12_3.12.2544.0_x64__*************\Lib\concurrent\futures\process.py", line 310, in weakref_cb
AttributeError: 'NoneType' object has no attribute 'debug'

(*************のところは、おそらく固有の番号なので隠した。)
ProcessPoolExecutor をwith ProcessPoolExecutor as executor:といった使い方をしていても出るし、executor.shutdown()を明示的に呼んでも出る。

考察

AIに聞いても、通常は問題ないとだけ返ってきて釈然としないので、ちょっと考えてみた。
エラーの出た所のソースコードを見に行ったところ、こんな感じになっている。

Lib/concurrent/futures/process.py
class _ExecutorManagerThread(threading.Thread):
    """Manages the communication between this process and the worker processes.

    The manager is run in a local thread.

    Args:
        executor: A reference to the ProcessPoolExecutor that owns
            this thread. A weakref will be own by the manager as well as
            references to internal objects used to introspect the state of
            the executor.
    """

    def __init__(self, executor):
        # Store references to necessary internals of the executor.

        # A _ThreadWakeup to allow waking up the queue_manager_thread from the
        # main Thread and avoid deadlocks caused by permanently locked queues.
        self.thread_wakeup = executor._executor_manager_thread_wakeup
        self.shutdown_lock = executor._shutdown_lock

        # A weakref.ref to the ProcessPoolExecutor that owns this thread. Used
        # to determine if the ProcessPoolExecutor has been garbage collected
        # and that the manager can exit.
        # When the executor gets garbage collected, the weakref callback
        # will wake up the queue management thread so that it can terminate
        # if there is no pending work item.
        def weakref_cb(_,
                       thread_wakeup=self.thread_wakeup):
            mp.util.debug('Executor collected: triggering callback for'
                          ' QueueManager wakeup')
            thread_wakeup.wakeup()

        self.executor_reference = weakref.ref(executor, weakref_cb)
        # 以下省略

多分ですが、mp.util.debug()を呼んでいるので、multiprocessingのユーティリティ関数群のデバッグ関数っぽいので、こんな感じではないかと。

  • VS Codeから実行したときに何らかの 'debug' という属性か何かがセットされ実行される

  • それにより、通常は実行されることのないデバッグ用関数mp.util.debug()が実行される。または、インスタンスがある状態で呼びだされるべきものが、ない状態で呼び出される

  • 意図しない実行により、結果的に、意図しない例外が発生してしまう

なお、mpは、multiprocessing の別名のようです。
multiprocessing.util.debug() はこんな感じ

Lib/multiprocessing/util.py
def debug(msg, *args):
    if _logger:
        _logger.log(DEBUG, msg, *args, stacklevel=2)

ということは、おそらく、mp.util のインスタンスが無いかNoneになっているような状態か?

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?