- はじめに — GILを外した後に残る問題
- なぜ1つの.soが両ビルドを兼ねられないのか
- ホイールのマトリクス — PEP 803が実際に引用した数字
- abi3tがすること
- 代償 — abi3tはabi3より狭い
- 最も重要な誤解 — ロードできることとスレッドセーフであることは別
- 3.14には乗れない — そして、いつ使わないか
- では、Phase IIIはいつなのか
- おわりに
- 参考資料
はじめに — GILを外した後に残る問題
free-threaded Pythonの大きな物語は、もう片付いたように見えます。PEP 779が2025年6月16日に確定し、free-threadedビルドはPython 3.14から実験段階を脱しました。PEPの用語ではこれがPhase IIです — 公式にサポートされるが、まだ選択制のビルド。そしてPhase IIIは、free-threadedをデフォルトビルドにする段階です。
そこで自然な問いは「いつデフォルトになるのか」です。そして、その答えを阻んでいるのはインタプリタ性能だけではありません。
PEP 779のPhase II基準を見ると性能項目があります — 単一スレッドオーバーヘッドについて「15% as a hard performance target」を掲げ、PEP執筆時点の実測値はおおむね10%前後でした。メモリはpyperformanceの幾何平均基準で20%が目標でした。ここまではインタプリタ内部の問題です。
ところが、同じPEPのOpen Issuesにstable ABIが挙がっています。確定した要件としてではなく、開いた問いとして。そしてこの開いた問いこそが、性能の数字より先にエコシステムを縛っていた実質的なボトルネックでした。本稿は、その穴がPEP 803によってどう埋められるのか、そしてその代償が何かという話です。
なぜ1つの.soが両ビルドを兼ねられないのか
まず根本原因から。free-threadedビルドは単にGILを外すだけでなく、オブジェクトの形そのものを変えます。PEP 793の表現が正確です — 通常ビルドとfree-threadingビルドでは、Pythonオブジェクトのメモリレイアウトが異なります。参照カウント方式が変わり、オブジェクトヘッダにフィールドが追加されたためです。
レイアウトが違うと何が壊れるのか。コンパイル時に静的に確保されたPythonオブジェクトが壊れます。C拡張がソースコードに埋め込む構造体がこれに該当します。PEP 793は、モジュール定義がその中で最も多い障害だと指摘します — 1つのコンパイル済みライブラリファイルを通常ビルドとfree-threadedビルドの両方で使えなくしている最も一般的な障害物こそがPyModuleDefだ、というわけです。PyModuleDefは内部にPyModuleDef_Baseを持ち、それはさらにオブジェクトヘッダを持ちます。ヘッダサイズがビルドごとに違えば、その構造体を静的に埋め込んだ.soは片方のビルドでしか通用しません。
そのためABIが分かれました。cp314とcp314tは別々のABIであり、拡張はそれぞれ個別にビルドする必要があります。
ホイールのマトリクス — PEP 803が実際に引用した数字
ここでstable ABI(abi3)が存在する理由を思い出す必要があります。abi3は「Pythonのマイナーバージョンごとに再ビルドしなくて済む」ようにする仕組みです。バージョン軸を畳んでしまうわけです。一度ビルドすれば3.x以降でずっとロードされます。
問題は、free-threadedビルドではこれがまったく効かなかったことです。PEP 803の文言そのままに — stable ABIはfree-threadedビルドで使用できず、Py_LIMITED_APIとPy_GIL_DISABLEDマクロが両方定義されると拡張のビルドは失敗します。
つまり、free-threadingへ踏み出した瞬間、畳んでおいたバージョン軸がまた広がります。すると、ホイールの数はどうなるのか — PEP 803のMotivationは、抽象的な懸念ではなく実際のメンテナーの数字を引用しています。
- cryptography — 直近のリリースでホイールファイル48個を配布しました。メンテナーAlex Gaynorの言葉: "As long as we have O(1) builds, that's ok. What we can't/won't do is O(n) where we need new builds for every Python release."
- SciPy — 最後のリリースでCPython 4バージョンをサポートするため、バージョン別ホイール60個をアップロードしました。(SciPyステアリングカウンシル議長Ralf Gommers)
- pydantic-core — 最新リリースでホイール112個を配布し、この数はさらに増える見込みです。メンテナーDavid Hewittの警告が核心です: "if free-threading does not adopt a stable ABI, all the benefits above will be lost when free-threading becomes the default."
この最後の一文がPhase IIIに直結します。free-threadingがデフォルトになった瞬間、stable ABIがなければ、これまでabi3で得ていた利得はまるごと吹き飛びます。だからステアリングカウンシルは、free-threading用のstable ABIをPython 3.15に間に合わせて用意・定義すべきだという立場を取りました。PEP 803はその要求への答えです。
abi3tがすること
PEP 803 — "abi3t": Stable ABI for Free-Threaded Builds。著者はPetr ViktorinとNathan Goldbaum、2026年3月30日にAcceptedされ、Python 3.15を対象とします。
要点はabi3を修正することではなく、亜種をもう一つ作ることです。拡張はPy_LIMITED_APIの代わりに(正確には、それとは別に)Py_TARGET_ABI3Tを定義してコンパイルします。
/* Python.h をincludeする前に */
#define Py_TARGET_ABI3T 0x30f0000 /* 3.15 */
/* あるいはコンパイラフラグで */
/* -DPy_TARGET_ABI3T=0x30f0000 */
そして、ここが実務上もっとも重要な部分です。abi3tでコンパイルした拡張は、free-threadedビルド専用ではありません。PEPのAbstractの文言そのままに — 実務上、abi3t 3.15はabi3 3.15と互換性があります。PEPは、拡張の作者が両方のABIを一度に明示的にコンパイルし、ホイールタグabi3.abi3tでその互換性を知らせることを推奨しています。
まとめると、こうなります。
現在 (3.14まで)
Pythonバージョン × スレッディングモード × プラットフォーム → ホイールの爆発
cp313-*, cp313t-*, cp314-*, cp314t-*, ... プラットフォームごとに繰り返す
abi3t以後 (3.15+)
1つのバイナリが3.15以降のGILビルドとfree-threadedビルドの両方をカバー
myproject-1.0-cp315-abi3.abi3t-macosx_11_0_arm64.whl
→ バージョン軸とスレッディングモード軸が同時に畳まれる。残るのはプラットフォーム軸だけ。
ファイル名のタグも変わります — Unix系では.abi3.soの代わりに.abi3t.soを使います。
ランタイムの安全装置も同時に入ります。free-threadedビルドでPyModuleDef_Init()は、free-threading用ではないstable ABIを使う拡張を検知し、ロード時に案内メッセージを出して例外を投げます。静かに壊れる代わりに、うるさく拒否する道を選んだわけです。
代償 — abi3tはabi3より狭い
ここからが正直になるべき部分です。abi3tはタダのアップグレードではなく、より厳格なABIです。レイアウトの違いを吸収する唯一の方法が「レイアウトをそもそも見せない」ことだからです。
構造体が不透明になります。 Py_TARGET_ABI3Tでコンパイルすると、PyObject、PyVarObject、PyModuleDef_Base、PyModuleDefが不完全型になります。フィールドに直接アクセスできず、サイズやアライメントも分からず、他の構造体に埋め込むこともできません。
その結果、次のマクロが消えます — PyObject_HEAD、_PyObject_EXTRA_INIT、PyObject_HEAD_INIT、PyObject_VAR_HEAD、Py_SET_TYPE()。
C拡張を書いたことがある人なら、このリストのPyObject_HEADを見て手が止まるはずです。カスタム型を定義する標準的な慣用句がまるごと使えなくなるからです。
/* これまでのやり方 — abi3tでは不可能 */
typedef struct {
PyObject_HEAD /* サイズが分からないため禁止 */
int my_data;
} CustomObject;
/* abi3tのやり方 — ベースを外し「追加フィールド」だけを定義する */
typedef struct {
int my_data;
} CustomObjectData;
static PyType_Spec CustomType_spec = {
.basicsize = -sizeof(CustomObjectData), /* 負のbasicsize (PEP 697) */
/* ... */
};
データにアクセスするにはPyObject_GetTypeData()を使う必要がありますが、ここに落とし穴が一つあります — 第二引数は定義したクラスでなければならず、Py_TYPE(obj)ではありません。サブクラス化が絡むと両者がずれるからです。そのためインスタンスメソッドではMETH_METHODフラグとPyCMethodシグネチャでdefining_classを受け取るか、型トークンを使う必要があります。
モジュールのエントリポイントも切り替える必要があります。 PyInit_*フックの代わりにPEP 793のPyModExport_*フックを使わなければなりません。PyModuleDefを静的に確保できない以上、当然の帰結です。PyModule_GetDef()とPyType_GetModuleByDef()も、モジュールトークンベースのPyModule_GetToken() / PyType_GetModuleByToken()に置き換える必要があります。
そして、そもそも移植できないものもあります。 可変長型 — Py_tp_itemsizeやtp_itemsizeを使う型 — はabi3t 3.15に移植できません。回避策の話ではなく、単にできません。
前提条件も軽くありません。abi3tを目指すには、すでにabi3をサポートしていて、多段階初期化(PyModuleDef_Slot)を使っていて、モジュールが分離されているか、プロセスごとに一度だけロードされる必要があります。
ビルド時の条件分岐も整理する必要があります。PY_VERSION_HEX、PY_MAJOR_VERSION、PY_MINOR_VERSIONはビルド時点のバージョンを反映するため、ランタイム値であるPy_Versionに置き換える必要があり、Py_GIL_DISABLEDはabi3tでは常に定義されているため、分岐条件としては使えません。
最も重要な誤解 — ロードできることとスレッドセーフであることは別
本稿からたった一行だけ持ち帰るなら、これであるべきです。PEP 803本文の一文です。
"Implementing this PEP will make it possible to build extensions that can be successfully loaded on free-threaded Python, but not necessarily ones that are thread-safe without a GIL."
abi3tは配布問題を解くのであって、並行性の問題を解くわけではありません。あなたの拡張がabi3tできれいにビルドされ、free-threadedインタプリタにうまくロードされたとしても、ロックなしでグローバル状態にアクセスしていたコードが急に安全になるわけではありません。実際のスレッドセーフAPIは、PEPが明示的に後続の作業として先送りにした領域です。
この区別はランタイムの挙動にも表れます。free-threadedビルドはGILを再び有効化できます — 環境変数PYTHON_GILや-X gilオプションで。そして公式ドキュメントによれば、free-threading対応であると明示的に示されていないC拡張をインポートすると、GILが自動的に再び有効化されることがあり、その際は警告が出力されます。
つまり「ロードされる」「GILなしで動く」「GILなしで速くなる」は互いに別の3つの関門です。abi3tは最初の関門を量産できるようにするだけです。
3.14には乗れない — そして、いつ使わないか
abi3tにはバックポートがありません。PEPの表現では、abi3tを対象とする拡張は、以前のCPythonリリースとソースレベル(API)でも、コンパイル済みの形(ABI)でも後方互換ではありません。PyModuleDefを避け、新しいPyModExportフックを使わなければならないためです。PEPは、free-threaded 3.14以下を対象とする方法(cp314-abi3t)を提供しないと明言しており、その問題は外部ツールに委ねています。
実務的には、こういう意味です。3.10~3.14を引き続きサポートする必要があるなら、その区間の既存ホイールマトリクスはそのまま残ります。abi3tがもたらす救済は、3.15から始まり年を追うごとに積み上がる種類のものであって、来年CI時間が半分になるような種類のものではありません。
そして、誰もが乗り換える必要はありません。 3.15 What's Newがこれを明確にしています — stable ABIはCPythonの全機能を提供するわけではなく、abi3tへ移行できない拡張は、既存のstable ABI(abi3)とfree-threading用のバージョン別ABI(cp315t)を別々にビルドする方式をこれまで通り使えばよい、と。
まとめると、こう分かれます。
abi3tが値打ちを発揮する場合
- 配布しているホイールがすでに数十個台で、Pythonバージョンが増えるたびに線形に増える。
- すでに
abi3をサポートしていて多段階初期化を使っている — 前提条件をすでに半分以上満たしている。 - free-threadedユーザーを実際にサポートする計画がある。
過剰、あるいは不可能な場合
- 純粋なPythonパッケージである。free-threadingガイドの表現通り、純粋なPythonコードは設計上そのまま動作します — やることがありません。
- 可変長型を使っている、あるいはstable ABI外のAPIが必要である — そもそも対象ではありません。
- 拡張が社内専用で、Pythonバージョンを1つしかサポートしていない — 畳む軸がないので、移行コストだけが残ります。
では、Phase IIIはいつなのか
まず数字を正直に。単一スレッドオーバーヘッドは、公式ドキュメント基準でpyperformanceベンチマークスイート上の平均がmacOS aarch64で約1%、x86-64 Linuxで約8%です。ワークロードとハードウェアによって変わるという注記もドキュメントに付いています。
軌跡を見るとこうです。PyCon US 2026(5月中旬、ロングビーチ)で、CPythonコア開発者でありステアリングカウンシルメンバーでもあるThomas Woutersが行った発表をLWNがまとめました。3.13では単一スレッドワークロードが20~40%遅くなり、3.14では0~10%まで縮小しました。Wouters自身も、ARMで0%のスローダウンに達したことには「personally shocked」だったと語り、LinuxのGCCでは通常5%程度で、10%まで行くこともあると述べました。
エコシステム側は、LWN基準でPyPI上位360個のバイナリホイールのうち50%以上がfree-threadingをサポートしています。主にMetaとQuansightの作業のおかげです。(この「上位360個」という母数は、hugovkのトラッカーが追跡する「拡張を持つダウンロード上位360パッケージ」と同じ基準です。)
それでもPhase IIIにはPEPも日程もありません。PEP 779がこの点を明確にしています — Phase IIへの参入要件とPhase IIIの決定はまったく別の問題であり、後者はコミュニティの支持を中心に回る、と。Woutersの予測も、必ず彼自身の留保とともに引用しなければ公正ではありません。彼はfree-threaded版がいずれデフォルトのPythonになると信じているとしながらも、「I'm not saying this with any authority whatsoever」と釘を刺しました。彼個人の推測は3.16(2027年10月)以降、3.20(2031年10月)より前です。つまり、最も楽観的に見ても最低1年以上先で、幅は4年です。
残された宿題も明らかです。Woutersは、インタプリタとサードパーティパッケージの両方でさらなる性能・拡張性の改善が必要だと述べ、スレッド間のオブジェクト共有は依然として性能上の問題だと指摘しました。これはabi3tがまったく触れていない領域です。
日程感のために付け加えると、PEP 790基準でPython 3.15は2026年5月7日のbeta 1で機能凍結され、rc1は2026年8月4日、rc2は9月1日、最終リリースは2026年10月1日です。本稿を書いている今(7月中旬)はベータの区間で、公式ドキュメントも3.15.0b3基準でビルドされています。つまりabi3tは確定した設計ではありますが、まだリリースされたものではありません。
おわりに
free-threadingの話は、たいてい「GILがなくなる」から始まり、ベンチマークのグラフで終わります。しかし3.14でPhase IIを通過した後、実際に進展が必要だった場所はインタプリタではなく、配布パイプラインでした。abi3が畳んでおいたバージョン軸が、free-threadingを前にして再び広がる問題 — cryptographyの48個、SciPyの60個、pydantic-coreの112個というホイールマトリクスが倍になる問題です。
PEP 803のabi3tは、その軸を再び畳みます。1つのバイナリが3.15以降のGILビルドとfree-threadedビルドの両方を兼ね、タグはabi3.abi3tです。代償はより狭いABIです — 不透明になったPyObject、消えたPyObject_HEAD、負のbasicsize、PyModExportフック、移植不可能な可変長型。
そして、これが解く問題の境界を正確に知っておく必要があります。abi3tはあなたの拡張をfree-threaded Pythonにロードできるようにするだけで、スレッドセーフにはしません。それは依然としてあなた自身の仕事であり、PEP自身がそう書いています。
Phase IIIを待つ立場であれば、こうまとめられます — 性能はすでに目標近く(アーキテクチャによって1~8%)まで来て、エコシステムは上位360個の半分を超え、ABIの穴も3.15で埋まります。それでも、デフォルトビルドへの転換にはPEPすらありません。残っているのは技術ではなく合意だ、ということです。そして合意はベンチマークより遅く動きます。
参考資料
- PEP 803 – "abi3t": Stable ABI for Free-Threaded Builds (Petr Viktorin, Nathan Goldbaum)
- PEP 793 – PyModExport: A new entry point for C extension modules
- PEP 779 – Criteria for supported status for free-threaded Python
- PEP 790 – Python 3.15 Release Schedule
- Migrating to Stable ABI for free threading (abi3t) — Python 3.15 ドキュメント
- Python support for free threading — 公式HOWTO
- What's New In Python 3.15
- Free-threaded Python: past, present, and future — LWN (Thomas WoutersのPyCon US 2026発表のまとめ)
- Python Free-Threading Guide — パッケージ互換性トラッキング
- free-threaded wheels トラッカー (hugovk)
현재 단락 (1/88)
free-threaded Pythonの大きな物語は、もう片付いたように見えます。[PEP 779](https://peps.python.org/pep-0779/)が2025年6月16日に確定...