フリースレッド向け Stable ABI ("abi3t") への移行
************************************************

CPython 3.15 から、*フリースレッド* の Python に対応する Stable ABI が
サポートされます。 これはフリースレッドビルド向け Stable ABI、略して
"abi3t" と呼ばれます。 このドキュメントでは、C API を使う拡張をフリー
スレッドに対応させる方法を説明します。


移行する理由
============

Stable ABI を使う主な理由は、ライブラリの各バージョンについて、ビルド
して配布する成果物の数を減らすことです。

Stable ABI を使わない場合、サポートする CPython の機能リリースごとに別
の共有ライブラリと、通常は *wheel* 配布物をビルドする必要があります。
例えば、次の表の各タグは、それぞれ別のライブラリや wheel を表します。

+-------------------+-------------------------+--------------------------+
| CPython のバージ  | 非フリースレッド        | フリースレッド           |
| ョン              |                         |                          |
|===================|=========================|==========================|
| 3.12              | "cpython-312"           | ---                      |
+-------------------+-------------------------+--------------------------+
| 3.13              | "cpython-313"           | "cpython-313t"           |
+-------------------+-------------------------+--------------------------+
| 3.14              | "cpython-314"           | "cpython-314t"           |
+-------------------+-------------------------+--------------------------+
| 3.15              | "cpython-315"           | "cpython-315t"           |
+-------------------+-------------------------+--------------------------+
| 3.16              | "cpython-316"           | "cpython-316t"           |
+-------------------+-------------------------+--------------------------+
| 以降のバージョン  | "cpython-3*XX*"         | "cpython-3*XX*t"         |
+-------------------+-------------------------+--------------------------+

これではビルドの数が多くなります。 サポートするプラットフォームの数も
掛け合わせると、なおさらです。

CPython 3.2 で導入された Stable ABI ("abi3") を使うと、プラットフォー
ムごとに 1 つの拡張で、CPython の *非フリースレッド* ビルドすべてに対
応できます。

+-------------------+---------------------+--------------------------+
| CPython のバージ  | 非フリースレッド    | フリースレッド           |
| ョン              |                     |                          |
|===================|=====================|==========================|
| 3.12              | "abi3"              | ---                      |
+-------------------+                     +--------------------------+
| 3.13              |                     | "cpython-313t"           |
+-------------------+                     +--------------------------+
| 3.14              |                     | "cpython-314t"           |
+-------------------+                     +--------------------------+
| 3.15              |                     | "cpython-315t"           |
+-------------------+                     +--------------------------+
| 3.16              |                     | "cpython-316t"           |
+-------------------+                     +--------------------------+
| 以降のバージョン  |                     | "cpython-3*XX*t"         |
+-------------------+---------------------+--------------------------+

CPython 3.15 で導入されたフリースレッドビルド向け Stable ABI ("abi3t")
は、フリースレッドビルドで同じ役割を果たします。 非フリースレッドビル
ドとも互換性があります。

+-------------------+---------------------+--------------------+
| CPython のバージ  | 非フリースレッド    | フリースレッド     |
| ョン              |                     |                    |
|===================|=====================|====================|
| 3.12              | "abi3" *            | ---                |
+-------------------+                     +--------------------+
| 3.13              |                     | "cpython-313t"     |
+-------------------+                     +--------------------+
| 3.14              |                     | "cpython-314t"     |
+-------------------+---------------------+--------------------+
| 3.15              | "abi3t"                                  |
+-------------------+                     |                    |
| 3.16              |                                          |
+-------------------+                     |                    |
| 以降のバージョン  |                                          |
+-------------------+---------------------+--------------------+

* (前述のとおり、"abi3" 拡張はすべての非フリースレッドビルドと互換性が
あります。 この表で "abi3t" の対応範囲として示した 3.15 以降も含まれま
す。)


移行 *しない* 理由
------------------

Stable ABI には主に 2 つの欠点があります。

第 1 に、Stable ABI は性能より互換性を優先するため、拡張が遅くなる可能
性があります。 通常は気付かない程度の違いであり、同じソースから Stable
ABI 向けのビルドに加えて、主要な CPython バージョン向けの専用ビルドも
いくつか作ることで、影響を軽減できる場合が多くあります。

第 2 に、C API のすべてを利用できるわけではありません。 Stable ABI 向
けにビルドするには拡張を移植する必要があり、これが難しい場合や、まれに
不可能な場合もあります。

特に "abi3t" には、CPython 3.15 で追加された API が必要です。 同じソー
スから古い CPython 向けにも拡張をビルドしたい場合は、主に 2 つの選択肢
があります。

* プリプロセッサの条件分岐を使う。

  このガイドに従って変更する際に、サポートしたい CPython バージョンで
  ビルドできなくなる変更には、"#ifdef Py_TARGET_ABI3T" ブロックを使っ
  てください。 従来のコードは "#else" ブロックに残します。

  **PEP 697** で導入された機能により、手書きの C 拡張では CPython 3.12
  まで対応を維持するのが現実的です。 Cython などのコード生成ツールでは
  、3.11 以前との互換性を維持する価値もあるでしょう。

* 古いバージョンのサポートを終了できるまで、"abi3t" へ移植せず、
  CPython のバージョンごとに別の拡張をビルドし続ける。

  これも妥当な方法です。 すべての拡張が今すぐ "abi3t" に移行する必要は
  ありません。


前提条件
========

このガイドでは、C または C++ で直接書いた拡張を "abi3t" に移植すること
を想定しています。

拡張が Cython のようなコード生成ツールや PyO3 のような言語バインディン
グを使っている場合は、そのツールが "abi3t" に対応するまで待つのがよい
でしょう。 そのようなツールを保守している場合は、このガイドの手順をツ
ールに合わせて応用できるかもしれません。


非フリースレッドの Stable ABI
-----------------------------

拡張は非フリースレッドの Stable ABI ("abi3") に対応している必要があり
ます。 未対応の場合は先に対応させるか、このガイドに記載されていない問
題も解決するつもりで読み進めてください。


フリースレッドへの対応
----------------------

厳密には必須条件ではありませんが、通常は "abi3t" への移植前に拡張をフ
リースレッドに対応させておくとよいでしょう。 手順は C API 拡張のフリー
スレッド対応 を参照してください。

参考:

  Porting Extension Modules to Support Free-Threading: 拡張の開発者向
  けにコミュニティが保守している移植ガイド。


拡張モジュールの分離
--------------------

モジュールは 複数フェーズ初期化 を使い、分離されているか、プロセスあた
りの読み込みを最大 1 回に制限する必要があります。 そうでなければ、先に
拡張モジュールを分離する に従ってください。 (簡単な方法については 分離
を避ける節 を参照してください。)


可変長の型を避ける
------------------

拡張が "Py_tp_itemsize" や "PyTypeObject.tp_itemsize" を使って可変長の
型を定義している場合、"abi3t" 3.15 には移植できません。


ビルドの設定
============

ビルドツールを使っている場合は、そのドキュメントで「"abi3t"」を検索し
、ABI を選択する手順に従ってください。 参考として、よく使われるビルド
ツールへのリンクを示します。

* meson-python

* scikit-build-core

* Maturin

ツールが正しいフラグを設定したか確認するには、"#include <Python.h>" の
直後に、一時的に次のコードを追加するとよいでしょう。

   #if Py_TARGET_ABI3T+0 <= 0x30f0000
   #error "abi3t define is not set!"
   #endif

This should result in a different error than ""abi3t" define is not
set".

参考:

  Building and distributing abi3t extensions: コミュニティが保守してい
  る Python Free-Threading Guide にある、ビルド設定と wheel のテストの
  例。

注釈:

  ビルドツールがまだ "abi3t" に対応していない場合は、"Python.h" をイン
  クルードする前に次のマクロを定義してください。

     #define Py_TARGET_ABI3T 0x30f0000

  または、例えば次のようにコンパイラのフラグで指定します。

     -DPy_TARGET_ABI3T=0x30f0000

  この設定で拡張をビルドできれば、CPython 3.15 以降と互換性のある拡張
  になります。このマクロを手動で設定した場合は、生成される拡張の名前と
  タグも後で手動で設定する必要があります。 これについては、後の タグ付
  けと配布 で説明します。

このガイドでは一連の変更を行います。 それぞれの変更後に、もとの
("abi3t" ではない) 設定でも拡張をビルドできることを確認してください。
できれば、サポートするすべての Python バージョンでテストを実行してくだ
さい。 これにより、移植中に既存の動作を壊していないことを確認できます
。


モジュールエクスポートフック
============================

この手順をまだ行っていなければ、拡張モジュールには
"PyInit_*<modname>*" という モジュール初期化関数 が定義されているはず
です ("modname" はモジュール名です)。 これを モジュールエクスポートフ
ック "PyModExport_*<modname>*" に移行する必要があります。 この機能は
**PEP 793** により CPython 3.15 で追加されました。

既存の初期化関数は、次のようになっているはずです ("<modname>" と
"<moddef>" は自分のコードの名前になります)。

   PyMODINIT_FUNC
   PyInit_<modname>(void)
   {
       return PyModuleDef_Init(&<moddef>);
   }

"return" の前に処理がある場合は、"Py_mod_create" または "Py_mod_exec"
スロットの関数に移してください。 関連する情報は PyInit のドキュメント
を参照してください。

この関数は "PyModuleDef" オブジェクト (上のコードの "<moddef>") を参照
しています。 その定義は次のようになっているはずですが、値は異なり、一
部のフィールド名が指定されていなかったり、フィールドが省略されていたり
するかもしれません。

   static PyModuleDef <moddef> = {
       PyModuleDef_HEAD_INIT,
       .m_name = "my_module",
       .m_doc = "my docstring",
       .m_size = sizeof(my_state_struct),
       .m_methods = my_methods,
       .m_slots = my_slots,
       .m_traverse = my_traverse,
       .m_clear = my_clear,
       .m_free = my_free,
   };

この定義と "PyInit" 関数を削除し、次のコードに置き換えてください。 後
方互換性を保つ場合は、削除する代わりに "#ifndef Py_TARGET_ABI3T" ブロ
ックに入れます。

   PyABIInfo_VAR(abi_info);

   static PySlot my_slot_array[] = {
       PySlot_STATIC_DATA(Py_mod_abi, &abi_info),
       PySlot_STATIC_DATA(Py_mod_name, "my_module"),
       PySlot_STATIC_DATA(Py_mod_doc, "my docstring"),
       PySlot_SIZE(Py_mod_state_size, sizeof(my_state_struct)),
       PySlot_STATIC_DATA(Py_mod_methods, my_methods),
       PySlot_STATIC_DATA(Py_mod_slots, my_slots),
       PySlot_FUNC(Py_mod_state_traverse, my_traverse),
       PySlot_FUNC(Py_mod_state_clear, my_clear),
       PySlot_FUNC(Py_mod_state_free, my_free),
       PySlot_END
   };

   PyMODEXPORT_FUNC
   PyModExport_<modname>(void)
   {
       return my_slot_array;
   }

もともと存在しなかったフィールドは省き (新設の "Py_mod_abi" は例外です
)、自分のコードの値に置き換えてください。

この API の詳細は "PySlot" と エクスポートフック のドキュメントを参照
してください。

この例のように、"PyModExport_" 関数では静的データへのポインタを返す *
だけ* にしてください。 ほかの処理を避けられない場合は、PyModExport の
ドキュメントの注意事項 を参照してください。

注釈:

  Setuptools ビルドツールを使って Windows 向けにビルドする場合、
  "PyInit_*<modname>*" 関数を削除すると、リンカエラー "LINK : error
  LNK2001: unresolved external symbol PyInit_*<modname>*" が発生するこ
  とがあります。 原因は Setuptools が "/EXPORT" リンカフラグを渡すこと
  です。 このフラグは Python 3.15 から不要になっています (gh-141671 を
  参照)。 回避策として、ダミーの "PyInit_*<modname>*" 関数を追加できま
  す。 Python 3.15 以降では "PyModExport_*<modname>*" が存在するとこの
  関数は呼ばれないため、常に失敗する実装で構いません。

     // 次の問題の回避策: https://github.com/pypa/distutils/issues/387
     PyMODINIT_FUNC
     PyInit_<modname>(void)
     {
         PyErr_SetString(PyExc_SystemError,
                         "PyInit_* called for module with PyModExport_*");
         return NULL;
     }

  (この問題は Setuptools 84.0.0 に存在します。 より新しいバージョンで
  は修正されている可能性があります。)


既存のスロット
--------------

"Py_mod_slots" スロットがある場合は、それが参照する配列を確認してくだ
さい。 次のような "PyModuleDef_Slot" 配列になっているはずです。

   static PyObject *create_module(PyObject *spec, PyModuleDef *def) { ... }
   static int my_first_module_exec(PyObject *module) { ... }
   static int my_second_module_exec(PyObject *module) { ... }

   static PyModuleDef_Slot my_slots[] = {
      {Py_mod_gil, Py_MOD_GIL_NOT_USED},
      {Py_mod_multiple_interpreters, Py_MOD_PER_INTERPRETER_GIL_SUPPORTED},
      {Py_mod_create, my_module_create},
      {Py_mod_exec, my_first_module_exec},
      {Py_mod_exec, my_second_module_exec},
      {0, NULL}
   };


"py_mod_create"
~~~~~~~~~~~~~~~

"Py_mod_create" エントリーがある場合は、その関数の第 2 引数に、削除す
る "PyModuleDef" の代わりに "NULL" を渡してもよいことを確認してくださ
い。 多くの場合、この引数は使われていません。 名前を変更して確かめられ
ます。

   static PyObject *create_module(PyObject *spec, PyModuleDef *_unused) { ... }

引数が使われている場合は、別の方法でデータを渡してください。 多くの場
合、その情報は静的なので直接参照できます。 (複数のモジュールで同じ関数
を使い回している場合は、別々の関数を定義することを検討してください。)


Multiple "py_mod_exec"
~~~~~~~~~~~~~~~~~~~~~~

"Py_mod_exec" エントリーが *複数* ある場合は、1 つにまとめてください。
各関数を呼び出す新しい関数を作り、既存のスロットをそれに置き換えます。

   static int my_module_exec(PyObject *module) {
      if (my_first_module_exec(module) < 0) return -1;
      if (my_second_module_exec(module) < 0) return -1;
   }

   static PyModuleDef_Slot my_slots[] = {
      ...
      /* (remove other Py_mod_exec slots) */
      ...
      {Py_mod_exec, my_module_exec},
      {0, NULL}
   };

各関数がほかで使われていなければ、代わりにそれぞれの本体を 1 つにまと
めることもできます。


スロット配列の統合
~~~~~~~~~~~~~~~~~~

Python 3.14 との互換性を維持する必要がなくなったら、任意の整理として、
スロットを "PySlot" 配列に移し、定義を "PySlot_DATA" と "PySlot_FUNC"
に変えることができます。

   static PySlot my_slot_array[] = {
       ...
       PySlot_DATA(Py_mod_gil, Py_MOD_GIL_NOT_USED),
       PySlot_DATA(Py_mod_multiple_interpreters,
            Py_MOD_PER_INTERPRETER_GIL_SUPPORTED)
       PySlot_FUNC(Py_mod_create, my_module_create),
       PySlot_FUNC(Py_mod_exec, my_module_exec),
       PySlot_END
   };

この変更を行ったら、もとの "PyModuleDef_Slot" 配列と、それを指す
"Py_mod_slots" エントリーを削除してください。


関連付けられた "PyModuleDef"
----------------------------

新しい API は "PyModuleDef" 構造体を使わないため、作成されたモジュール
にモジュール定義は関連付けられません。 その結果、次の関数の動作が変わ
ります。

* "PyModule_GetDef()"

* "PyType_GetModuleByDef()"

これらの関数を使っているか、コードを確認してください。 使っていなけれ
ば、この節は読み飛ばせます。

これらの関数は、通常 2 つの目的で使われます。

1. モジュールの作成に使われた定義を取得する。 新しい API ではこれはで
   きなくなります。 モジュールは定義への参照を保持しなくなるため、必要
   なデータを受け渡す別の方法を考える必要があります。

2. あるモジュールオブジェクトが「自分のもの」かを確認する。 この用途に
   は、モジュールを識別する不透明なポインタである モジュールトークン
   を使います。 トークンを使うには、一意な静的変数を宣言するか、既存の
   ものを再利用します。 例えば、次のようにします。

      static char my_token;

   その変数へのポインタを、モジュールの "PySlot" 配列の新しいエントリ
   ーとして追加します。

      static PySlot my_slot_array[] = {
         ...
         PySlot_STATIC_DATA(Py_mod_token, &my_token),
         PySlot_END
      }

   そして、次のような "PyModule_GetDef()" の呼び出しを、

      PyModuleDef *def = PyModule_GetDef(module);

   "PyModule_GetToken()" に置き換えます。 この関数は出力用引数を使い、
   例外を送出して失敗することがあります。

      void *token;
      if (PyModule_GetToken(module, &token) < 0) {
          /* エラーを処理する */
      }

   また、次のような "PyType_GetModuleByDef()" の呼び出しを、

      PyObject *module = PyType_GetModuleByDef(type, my_def);
      /* エラーを処理し、module を使う */

   強参照を返す "PyType_GetModuleByToken()" に置き換えます。

      PyObject *module = PyType_GetModuleByToken(type, my_token);
      /* handle error; use module */
      Py_XDECREF(module);


"PyObject" の不透明化
=====================

"abi3t" では "PyObject" と "PyVarObject" の構造体は不透明です。

メンバーへのアクセスは禁止されています。 メンバーにアクセスしている場
合は、それぞれのドキュメントに記載された取得・設定用の関数に置き換えて
ください。

* "PyObject.ob_type"

* "PyObject.ob_refcnt"

* "PyVarObject.ob_size"

また、コンパイラには "PyObject" 構造体の *サイズ* が分かりません。 サ
イズは CPython のビルドごとに変わる可能性があり、*実際に変わります*。

注釈:

  サイズは実行時に取得できますが (例えば Python コードで
  "sys.getsizeof(object())" を使えます)、それをもとにポインタのオフセ
  ットを計算したくなっても避けてください。 オブジェクトのメモリレイア
  ウトは、将来の "abi3t" の実装で変わる可能性があります。


独自の型の定義
--------------

"PyObject" が不透明になるため、独自の型を定義する従来の方法は使えなく
なります。

   typedef struct {
      PyObject_HEAD  // サイズが不明な `PyObject ob_base;` に展開される

      int my_data;
   } CustomObject;

   static PyType_Spec CustomType_spec = {
      ...
      .basicsize = sizeof(CustomObject),
      ...
   };

おそらく、すべてのクラス定義 *と*、そのクラスのデータにアクセスするす
べてのコードを書き直す必要があります。 これが "abi3t" 対応に必要な最大
の変更になるでしょう。

こうした型ごとに、インスタンス全体の "struct" を定義する代わりに、スー
パークラスのフィールドを含めず、そのクラス固有の「追加」フィールドだけ
を持つ構造体を定義してください。

   typedef struct {
      int my_data;
   } CustomObjectData;

名前も変更してください。 この構造体を使うコードのほぼすべてに変更が必
要です (特に、新しい構造体のポインタと "PyObject*" は相互にキャストで
きません)。 名前を変えれば、使用箇所をコンパイルエラーで見つけられます
。 ただし、"typeof" や C++ の "auto" など、型名を直接書かない方法を使
っている箇所では、この方法は使えません。 特に注意し、未定義の動作を検
出するツールの利用を検討してください。

次に、クラスの作成時には "basicsize" を *負の値* にして、インスタンス
*全体* のサイズではなく「追加」の格納領域のサイズを示します。

   static PyType_Spec CustomType_spec = {
      ...
      .basicsize = -sizeof(CustomObjectData), /* マイナス符号に注意 */
      ...
   };

"Py_tp_members" を使っている場合は、各メンバーに "Py_RELATIVE_OFFSET"
フラグを設定し、新しい構造体を基準とした "offset" を指定してください。


独自の型のデータへのアクセス
----------------------------

ここからが難しい部分です。 この構造体にアクセスするすべてのコードに
"PyObject_GetTypeData()" の呼び出しを追加し、"PyObject *" から
"CustomObjectData *" ポインタを取得する必要があります。

   PyObject *obj = ...;
   CustomObjectData *data = PyObject_GetTypeData(obj, cls);

この呼び出しには、自分のクラスの *型オブジェクト* ("cls") が必要です。

そのクラスがサブクラス化できない場合 (つまり "Py_TPFLAGS_BASETYPE" フ
ラグを使わない場合)、"cls" は "Py_TYPE(obj)" です。 それ以外の場合、
"PyObject_GetTypeData()" に "Py_TYPE" を **使わないでください**。 無関
係なサブクラス用のメモリが返されるかもしれません。 例えば、利用者が次
のようなサブクラスを作ったとします。

   class Sub(YourCustomClass):
      __slots__ = ('a', 'b')

このとき "Py_TYPE(obj)" は "Sub" であり、メモリの配置は次のようになっ
ているかもしれません。

   ╭─ PyObject *obj
   │              ╭─ 取得したいポインタ
   │              │                    ╭─ PyObject_GetTypeData(obj, Py_TYPE(obj))
   ▼              ▼                    ▼
   ┌──────────┬───┬────────────────┬───┬─────────────┬───┬─────────────┐
   │ PyObject │...│ CustomTypeData │...│ PyObject *a │...│ PyObject *b │
   └──────────┴───┴────────────────┴───┴─────────────┴───┴─────────────┘

(省略記号はパディングが入る可能性を示します。 このメモリレイアウトは保
証されていません。 将来の Python ではパディングが変わったり、構造体の
順序が変わったりする可能性もあります。)

正しいクラスを取得するには、主に 2 つの方法があります。

* インスタンスメソッドでは、"PyCMethod" シグネチャと
  "PyMethodDef.ml_flags" の "METH_METHOD" ビットを使い、
  "defining_class" 引数でクラスを受け取れます。

* それ以外の場合は、"Py_tp_token" スロットを使ってクラスに一意な静的ト
  ークンを設定し、次のようにします。

     PyTypeObject cls;
     if (PyType_GetBaseByToken(Py_TYPE(obj), my_tp_token, &cls) < 0) {
         /* handle error */
     }
     CustomObjectData *data = PyObject_GetTypeData(obj, cls);

  型のトークンは、このガイドの前半 で説明したモジュールトークンと同じ
  ように働きます。


ビルド時の条件分岐を避ける
==========================

拡張の *ビルド* に使った Python のバージョンを特定する API を使ってい
ないか、コードを確認してください。 そのバージョンは拡張を実行する
Python のバージョンとは一致しなくなるため、この情報を使うコードには変
更が必要なことが多くあります。 確認するマクロは次のとおりです。

* "PY_VERSION_HEX", "PY_MAJOR_VERSION", "PY_MINOR_VERSION":

  * 実行時のバージョンを取得するには、"Py_Version" を使います。

  * 利用可能な C API を判断するには、"Py_TARGET_ABI3T" を使います。 こ
    のマクロには、サポートする最も古いバージョンが設定されています。

* "Py_GIL_DISABLED": "abi3t" では、このマクロは常に定義されています。
  フリースレッドの Python で動くコードは、GIL が有効でも動作する *はず
  * です (GIL は実行時に有効化できるためです)。 通常は実際に *動作しま
  す* が、何らかの理由で複数の *アタッチされたスレッド状態* を同時に必
  要とする場合は例外です。


その他のコードの変更
====================

コンパイルエラーや警告がまだ残っている場合は、解決方法を探してください
。 残念ながら、このガイドには限界があり、拡張に必要になり得るすべての
コード変更を網羅することはできません。

ほかの拡張の開発者も遭遇しそうな問題が見つかった場合は、このガイドにつ
いて issue を報告する か、プルリクエストを送ることを検討してください。

現在の "abi3t" では解決できない問題もあり得ます。 その場合でも、報告す
ることで CPython の次のバージョンで優先的に対応されるかもしれません。


タグ付けと配布
==============

"abi3t" に対応したビルドツールを使っていれば、拡張の準備はできています
。 ただし、正しくビルドされたか確認するとよいでしょう。

"abi3t" 向けにビルドした拡張の拡張子は、次のようになります。

* Windows: ほかの拡張と同じく ".pyd"。

* Linux、macOS、その他 ".so" サフィックスを使うシステム: ".abi3t.so"
  (".cpython-315t.so" や ".abi3.so" **ではありません**)。 フリースレッ
  ドビルドでも非フリースレッドビルドでも、".abi3t.so" 拡張を読み込みま
  す。

* その他のシステム: 配布元に確認し、必要に応じてこのガイドを更新してく
  ださい。

拡張を *wheel* として配布する場合は、次のタグを使います。

* Python タグ: "cp3*XX*"。 *XX* は、拡張が対応するようにビルドされた最
  も古い Python バージョンです。 例えば、"Py_TARGET_ABI3T" を
  "0x30f0000" に設定した場合は "cp315" です。 ほかの値は Stable ABI 向
  けのコンパイル を参照してください。

* ABI タグ: "abi3.abi3t"。 これは非フリースレッドビルドとフリースレッ
  ドビルドの両方に対応することを示す *圧縮タグ集合* です。

例えば、wheel のファイル名は次のようになります。

   myproject-1.0-cp315-abi3.abi3t-macosx_11_0_arm64.whl

参考: PyPA のパッケージ配布メタデータにある Platform Compatibility Tags。

ファイル名やタグが正しくなければ修正してください。


テスト
======

複数の CPython バージョンと互換性のある拡張をビルドしたら、サポートす
る各バージョン (例えば 3.15、3.16 など) で必ず *テスト* してください。
Stable ABI が保証するのは *ABI* の互換性だけです。 動作には、**PEP
387** の対象となる意図的な変更も、バグによる変更もあり得ます。

CPython のフリースレッドビルドと非フリースレッドビルドの両方で、必ずテ
ストを実行してください。

テストが通れば、おめでとうございます！ "abi3t" 拡張の完成です。
