このBlogは移転しました。今後は aish.dev を御覧ください。

Python 3.8 の概要 (その6) - 拡張モジュール関連

拡張モジュールがリリースビルド/デバッグビルドで共用可能に

これまで、デバッグ用にビルドされたPythonでは、Pythonのメモリ使用状況を調査するための機能 が有効になっていました。このため、リリース用にビルドされたPythonデバッグ用にリリースされたPythonでは、内部のデータ構造が一部異なっており、拡張モジュールのバイナリもリリースビルド用とデバッグビルド用を別々に作成する必要がありました。

Python3.8のデバッグビルドではこの機能がオフになり、リリースビルド用の拡張モジュールをデバッグビルドでも利用できるようになりました。これまで、デバッグビルドのPythonで調査するときには使用する拡張モジュールもすべてデバッグビルド用に再構築していましたが、この作業が不要になりました。

拡張モジュールが共有ライブラリ版とスタティック版で共用可能に

Pythonの構築方法には、Python本体を共有ライブラリとして実行ファイルとは別のファイルに作成する 共有ライブラリ版 と、すべてを実行ファイルで持つ スタティック版 があります。

これまで、共有ライブラリ版のPythonで拡張モジュールをビルドすると、拡張モジュールもPython本体の拡張モジュール(libpython3.x.soなど)にリンクされていました。しかし、スタティック版のPythonでは libpython3.x.so が存在しないため、共有ライブラリ版用にビルドした拡張モジュールは、スタティック版では利用できませんでした。

しかし、拡張モジュールと libpython3.x.so をリンクする必要があるのはかなり特殊なケースに限られるため、利便性を優先して拡張モジュールは libpython3.x とリンクしないように修正されました。これにより、共有ライブラリ版でもスタティック版でもおなじ拡張モジュールを利用できるようになります。

拡張モジュールのバージョン間の互換性を放棄

これはあまり今どきのユーザには関係のない変更だと思いますが、感慨深かったので取り上げます。

従来、Pythonの拡張モジュールは、古いバージョンのPython用にビルドされた拡張モジュールでも、新しいPythonで利用できるようになっていました。例えば、Python 2.0である拡張モジュールをインストールし、そのあと Python 2.0を削除して Python 2.1をインストールしても、そもまま問題なく利用できるようになっていました。

いまではこんな使い方をする人はいないと思いますが、インターネット接続が今ほど普及しておらず、また PyPIpip もない時代には拡張モジュールのビルド・インストールはけっこうな難作業で、できるだけ簡単に使い回せるようになっていました。

しかし、いまでは共有ライブラリを使い回すよりも、うまく共有ライブラリをプロジェクト間で分離するほうが重要な時代となりました。主要なパッケージはバイナリが提供されるようになっていますので、ビルド・インストールの手間も最小限です。

そこで、Python3.8から、旧バージョン用の拡張モジュールは、新しいバージョンでは利用できなくなりました。もともと、実際に複数バージョンで利用できる拡張モジュールはそれほど多くはなかったと思われますが、公式に動作を保証しない、と表明されました。

2009年頃までは、共有モジュールの互換性を確保するためにこんな PEP が出ていたぐらいですが、その後の環境の変化で、ついにこのPEPも不要と成り果てました。今となってはユーザに関係ある話ではないのですが、Pythonの歴史を紹介する意味でちょっと解説してみました。