self._manager is None when proxy gets passed between processes and causes AttributeError

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

まだ誰も着手していません。

評価

難易度
3/5
見積もり時間
1〜2日
初心者へのやさしさ
25/100
issue の種類
バグ
明瞭さ
明確に書かれている
活発さ
停滞
技術スタック
python
領域
backend

調査の方向性

最小限の test.py の例で失敗を再現し、その後 Lib/multiprocessing/managers.py の BaseProxy._callmethod 周辺と、リンクされている PR gh-99598 を調査します。別のプロセスに渡された proxy が AttributeError なしで make_child を呼び出せ、回帰がテストでカバーされていれば完了です。

索引モデルが issue の本文から書いたものです。

説明

3.11 3.12 3.13 stdlib type-bug

Bug report

When a proxy derived from multiprocessing.managers.BaseProxy is passed between processes, the self._manager attribute becomes None. self._manager is however accessed to retrieve its _registry attribute, which contain the method_to_typeid map recorded into the manager viaBaseManager.register(), causing an AttributeError. The solution is to decouple the role of the manager from the role of the registry and propagate the registry separately. I'll submit a pull request to fix this.

Minimal failing example

test.py

from multiprocessing import Process
from multiprocessing.managers import BaseProxy, BaseManager


class Parent(object):
    def __init__(self, *args, **kwargs):
        pass

    def make_child(self):
        return Parent()


class MyManager(BaseManager):
    pass


def child_generator(parent):
    parent.make_child()


if __name__ == "__main__":
    MyManager.register('Parent', callable=Parent,
                       method_to_typeid={'make_child': 'Parent'})

    with MyManager() as manager:
        parent = manager.Parent()
        process = Process(target=child_generator, args=(parent, ))
        process.start()
        process.join()
Output
❯ python3 test.py
Process Process-2:
Traceback (most recent call last):
  File "/usr/local/Cellar/python@3.10/3.10.8/Frameworks/Python.framework/Versions/3.10/lib/python3.10/multiprocessing/process.py", line 314, in _bootstrap
    self.run()
  File "/usr/local/Cellar/python@3.10/3.10.8/Frameworks/Python.framework/Versions/3.10/lib/python3.10/multiprocessing/process.py", line 108, in run
    self._target(*self._args, **self._kwargs)
  File "test.py", line 18, in child_generator
    parent.make_child()
  File "<string>", line 2, in make_child
  File "/usr/local/Cellar/python@3.10/3.10.8/Frameworks/Python.framework/Versions/3.10/lib/python3.10/multiprocessing/managers.py", line 824, in _callmethod
    proxytype = self._manager._registry[token.typeid][-1]
AttributeError: 'NoneType' object has no attribute '_registry'

Environment

  • CPython versions tested on: 3.6, 3.7, 3.8, 3.9, 3.10
  • Operating system and architecture: macOS Monterey 12.6
Linked PRs
  • gh-99598
主要言語
Python
スター
77.2k
フォーク
36k
平均マージ
1日 9時間
マージ済み PR(30日)
558

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

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

はじめの一歩

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

python/cpython のほかの issue

python/cpython の issue をすべて見る

似ている issue

Python の issue をもっと見る

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

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