箱が…

Amazon箱ストラクチャーが崩れてきそうです。ダンボー作ろうかな。

Builtoutを使う Egg基礎編

前回の概要編では訳文的なノリで書いてみましたが、なかなか上手くいかないものですね

今回はPython Eggsを作るために必要なものについて書きます。

とはいったものの、Buildout(zc.buildout)を使うのに何故Eggの話を挟む必要があるのか、と思っている方もいると思います。
その理由は簡単です。BuildoutはPyPIやローカルにあるEgg(.eggまたはEggにする前のソースコード)を組み合わせてアプリケーション(のための環境)を構築するシステムだからです。
つまりBuildoutはEggがベースになっているので、あなたが今から書こうとしているアプリケーションもEggである必要があるのです。

そういうわけなので、この記事を読んでEggを作れるようになりましょう。

念のためご存じない方のために説明しますが、Python EggsとはJavaでいうところのJAR(Java ARchive)にあたるもので、PythonのパッケージのファイルをまとめてZIPで固めたファイル(拡張子は.egg)のことです。
また、Eggに必要なファイル(setup.py)を含んだPythonのパッケージで、まだEggとして固められていないものも便宜上Eggと呼ぶことにします。

Pythonのパッケージについて

Pythonのチュートリアルにも書かれていますが、パッケージとはPythonのモジュール(*.py)のコレクションのことです。
具体的には、あるディレクトリ直下に__init__.pyという名前のファイルがあれば、それはパッケージです。ファイル1つだとパッケージにする意味は薄いですが。
__init__.pyが存在すれば中身は空でも問題ありませんが、パッケージの初期化コードを書いたりドキュメンテーション文字列(docstring)にパッケージの簡単な説明を書いたりすることが多いようです。

setuptools

setuptoolsとはPythonのパッケージをダウンロード/ビルド/インストールが自動で、アンインストールが(頑張れば)手動でできるようになるパッケージマネージャです。
Pythonには元々標準ライブラリにdistutilsという配布物の構築・インストールができる仕組みが備わっていますが、setuptoolsはこれを強化する目的で作られたようです。
Python関係の記事でよく出てくる easy_install というコマンドはsetuptoolsが由来です。

ところが、setuptoolsの開発が滞ってきたおりに上位互換性をもつdistributeというパッケージマネージャが現れ、現在ではこのdistributeを使う方がよいとされています。
つまり distutils < setuptools < distribute の順でよりモダンであり、かついい感じということのようです。
なので、まだsetuptoolsを使っている方は distribute · PyPI を今すぐ手に入れましょう

パッケージの構成

ここからは実際にPythonのパッケージを作って、Eggに仕立ててみましょう。
Pythonのパッケージは、だいたい以下のようなディレクトリ・ファイル構成になります。

+ deepblue_sources
    - setup.py
    + deepblue
        - __init__.py
        - answer.py

一応パッケージの実物を置いておきます。

setup.pyを書く

Eggにはsetup.pyが欠かせません。Eggの全てのメタデータはこのsetup.pyに定義します。
setup.pyの中身はこんな感じになります。

# -*- coding: utf-8 -*-

from setuptools import setup

setup(name='deepblue',
      version='0.0.1',
      packages=['deepblue'])

関数 setup() がsetup.pyの本体で、これにメタデータを食わせます。

引数name

パッケージの名前であり、正式な識別子です。

引数version

パッケージのバージョンで、一応一定のフォーマットで記述しましょうということになっています

引数packages

Pythonのパッケージのディレクトリ(直下に__init__.pyを含む)を指定します。
詳細はhttp://www.python.jp/doc/release/distutils/setupscript.html#listing-packagesを参照してください

setup.pyを使う

setup.py が完成したら、コマンドラインから実行してみましょう。
--help オプションを与えると setup.py はヘルプメッセージを出力して終了します。

$ python setup.py --help
Common commands: (see '--help-commands' for more)

  setup.py build      will build the package underneath 'build/'
  setup.py install    will install the package

Global options:
  --verbose (-v)      run verbosely (default)
  --quiet (-q)        run quietly (turns verbosity off)
(長すぎるので略)

$ python setup.py --name
deepblue

$ python setup.py --version
0.0.1

ではいよいよEggを作ってみたいと思います。

$ python setup.py bdist_egg
running bdist_egg
running egg_info
creating deepblue.egg-info
writing deepblue.egg-info/PKG-INFO
(やっぱり長すぎるので以下略)

コマンドを実行するといくつかのディレクトリが作られ、その中のdistディレクトリ下にEgg(*.egg)ができているはずです

$ ls
build             deepblue.egg-info setup.py
deepblue          dist

$ ls dist
deepblue-0.0.1-py2.7.egg

Eggができました!

setup.py その他のコマンド

setup.py --help にも書かれていますが、bdist_eggの他にも便利なコマンドがいくつもあるので少し触れておきます。
というかBuildoutを扱うなら知っておいた方がいいと思います。

setup.py install

言わずと知れたパッケージのインストールコマンド
デフォルトではPythonのsite-packagesにパッケージをインストールする

setup.py develop

そのへんのディレクトリに置いてある開発中のパッケージへのリンク(symlink等ではない)をsite-packagesに張ることで、パッケージを擬似的にインストールする。
develop install とか呼ばれるらしい。
-u オプションでリンクを解除できる。

おわりに

今回長かった…

次回、Buildoutセットアップ編ではセットアップの方法とかはまりポイントとか書きます。