Public

Pythonパッケージング入門:setuptools、wheel、pipを使った配布可能なパッケージの作成方法

※本記事には広告・アフィリエイトリンクが含まれます

Python Python
t-salad t-salad committed 487420c

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コードのみの場合はnone
  • any: 対応プラットフォーム。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.md
  • src/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ベースの構成に統一することをおすすめします。

Python Packaging User Guide

build - PyPI

関連書籍

スポンサーリンク
スポンサーリンク
★ この記事をXでシェア はてなブックマーク
関連記事