テクノロジー · 実用ガイド

Python の「Can’t pickle local object」?serializer を変える前に process 境界を証明

例外は worker が再構成できない object を示します。start method、callable、argument graph、import path を記録してから修正します。

Original technical diagram of Python process serialization boundaries.
オリジナルイラスト:launcher、callable、argument、worker import の境界を証明。 Watch at Ease

process 境界で送る object が serialize または名前解決できません。nested function、lambda、closure、bound method、lock、socket、またはそれらを保持するinstanceが候補です。

本番launcherからPython/library version、start method、module、qualified name、argument type、fresh child importを一つのledgerにします。

1. 実際のlauncherとstart methodを固定

同じscript、runner、notebook、IDE、service、frameworkで再現し、python -VV、sys.executable、context、get_start_method()を記録します。

tracebackを保存し、start、map、submit、queue、result、worker startupのどこで失敗したか特定します。

2. callableとobject graphを特定

type(fn)、__module__、__qualname__を記録します。<locals>や<lambda>はmodule attributeとして解決不能の証拠です。

callableと各argumentを個別にpickle testし、secretではなく最初のfailure typeと安全なpathだけ残します。

3. fresh interpreterでimportを証明

最小worker entrypointをmodule top levelへ移し、process作成をmain guard内に置き、本番package pathからimport可能にします。

同じinterpreterとworking directoryの新しいprocessでmoduleとqualified nameを解決します。

4. parent resourceとplain task dataを分離

bound methodはinstance全体を取り込みます。lock、file、socket、client、connectionはchildで作るかsmall configに置換します。

argumentが失敗するならplain recordへ縮小し、initializerかworker内でresourceを再構成します。

5. start methodとserializer変更を限定判断

forkで一つのLinux testが通ってもportable contractではなく、threaded libraryでは危険な場合があります。

cloudpickleやdillはdependency、compatibility、deserialization trustを変えるため明示契約でのみ採用します。

6. fresh-worker exit test

同じproduction launcherとstart methodで小さなdeterministic taskを実行し、import、input、result、clean exitを確認します。

interpreter、start method、qualified name、input schema、worker PID、result checksum、exit statusを記録します。

Original decision diagram for Python process serialization repairs.
オリジナルイラスト:証明済みの境界だけを修正し fresh worker で再確認。 Watch at Ease