Pythonのエコシステムでは、パッケージングは非常に重要なプロセスです。適切にパッケージ化されたプロジェクトは、他の開発者が簡単に利用できるようになり、再利用性やメンテナンス性が向上します。本記事では、Pythonの配布形式である「wheel」の仕組みと、setuptools・buildを使って配布可能なパッケージを作成する方法を、最新の推奨手順に沿って解説します。
wheelとは何か
Pythonパッケージの配布形式には、大きく分けてsdist(ソース配布)とwheel(ビルド済み配布)の2種類があります。
- sdist: ソースコードそのものをアーカイブしたもの。インストール時に環境側でビルドが必要になる場合がある。
- wheel: あらかじめビルド済みのバイナリ形式。インストール時にビルド処理が不要なため高速で、環境依存のトラブルも起きにくい。
wheelファイルの名前には、対応環境の情報が埋め込まれています。例えば my_package-0.1.0-py3-none-any.whl というファイル名は、以下のように分解できます。
my_package: パッケージ名0.1.0: バージョンpy3: 対応するPythonのバージョン(py3はPython 3系全般)none: ABI(バイナリ互換性)タグ。純粋なPythonコードのみの場合はnoneany: 対応プラットフォーム。C拡張を含まない場合はany(OS非依存)
C拡張を含むパッケージ(NumPyなど)の場合は、cp311-cp311-win_amd64のようにPythonバージョンとOS・CPUアーキテクチャに応じた複数のwheelが用意されます。
必要なツールのインストール
現在のPythonパッケージングでは、ビルドツールとしてbuildパッケージを使うのが標準的です(旧来のpython setup.py sdist bdist_wheelは非推奨になっています)。
pip install --upgrade setuptools wheel buildプロジェクトの構成
パッケージを作成するには、まずプロジェクトのディレクトリ構成を決定します。以下は一般的なPythonパッケージの構成例です。
my_package/
├── src/
│ └── my_package/
│ ├── __init__.py
│ └── module.py
├── pyproject.toml
└── README.mdsrc/my_package/: 実際のパッケージコードを含むディレクトリ(srcレイアウトにすることで、テスト時に誤って未インストールのコードを参照するミスを防げる)__init__.py: このファイルが存在することで、ディレクトリがパッケージとして認識されるpyproject.toml: パッケージのメタデータ・依存関係・ビルド方法を定義するファイル(旧setup.pyの役割)README.md: パッケージの説明や使用方法を記載するファイル
pyproject.tomlの作成
pyproject.tomlは、PEP 517/518で標準化されたパッケージ設定ファイルです。以下は基本的な例です。
[build-system]
requires = ["setuptools>=61.0"]
build-backend = "setuptools.build_meta"
[project]
name = "my_package"
version = "0.1.0"
description = "My sample Python package"
readme = "README.md"
authors = [
{ name="Your Name", email="your.email@example.com" }
]
dependencies = [
"numpy",
]
[project.urls]
Homepage = "https://github.com/yourusername/my_package"このファイルで、パッケージ名、バージョン、依存関係、著者情報などを指定します。
パッケージのビルド
次に、パッケージをビルドします。buildパッケージを使うと、sdistとwheelの両方が一度に生成されます。
python -m build実行すると、dist/ディレクトリにmy_package-0.1.0.tar.gz(sdist)とmy_package-0.1.0-py3-none-any.whl(wheel)が生成されます。
従来の方法(setup.pyを使う場合)
古いプロジェクトではsetup.pyを使う方法もまだ見られますが、python setup.py sdist bdist_wheelという直接呼び出しはsetuptools自体が非推奨としています。setup.pyしかない既存プロジェクトでも、python -m buildコマンド自体はそのまま使えます(buildが内部でsetup.pyを呼び出す)。
パッケージのインストール
ビルドしたパッケージをローカル環境にインストールするには、以下のコマンドを使用します。
pip install dist/my_package-0.1.0-py3-none-any.whlこれにより、作成したパッケージがインストールされ、他のPythonスクリプトからインポートして使用できるようになります。開発中で編集のたびに再ビルドしたくない場合は、以下のように-eオプションで編集可能モードでインストールできます。
pip install -e .PyPIへのアップロード
作成したパッケージをPython Package Index(PyPI)にアップロードすることで、他のユーザーがpip installでインストールできるようになります。アップロードにはtwineを使用します。
pip install twine
twine upload dist/*実行するとPyPIのアカウント情報(またはAPIトークン)を求められます。正しい情報を入力すると、パッケージがアップロードされます。
よくあるエラーと対処法
ERROR: Failed building wheel for 'パッケージ名'
C言語などで書かれた拡張モジュールを含むパッケージ(NumPy、pandasの一部依存など)をインストールしようとした際に、対応するビルド済みwheelが提供されていない環境(マイナーなOS・古いPythonバージョン・特殊なCPUアーキテクチャなど)だと、ソースからのビルドが試みられて失敗することがあります。
- pipとsetuptools、wheelを最新版に上げてから再試行する:
pip install --upgrade pip setuptools wheel - 可能であれば対応済みのPythonバージョンに変更する(新しすぎる・古すぎるバージョンは対応wheelがないことが多い)
Microsoft Visual C++ 14.0 or greater is required(Windows)
Windows環境で、C拡張を含むパッケージのビルドに必要なコンパイラが見つからない場合に発生します。Microsoft C++ Build Toolsをインストールすることで解決します。
error: invalid command 'bdist_wheel'
wheelパッケージがインストールされていない環境で、旧来のsetup.py bdist_wheelを実行しようとすると発生します。pip install wheelでインストールすれば解決しますが、根本的には本記事で紹介したpython -m buildへの移行を推奨します。
まとめ
Pythonパッケージングは、他の開発者とコードを共有し、再利用可能なライブラリを作成するための重要なプロセスです。wheelはビルド済みの高速な配布形式であり、現在はpyproject.toml + python -m buildを使うのが標準的な作成方法です。旧来のsetup.py sdist bdist_wheelは非推奨になっているため、新規プロジェクトではpyproject.tomlベースの構成に統一することをおすすめします。