目次

このページ

Python Project Howto (日本語訳)

Version 0.7.1
2010 年 02 月 01 日
この文章は「 Python Project Howto 」の日本語訳です。
Translated by Hideo Hattori

目標

あなたはPythonでいくつかのコードを生み出しました。 あなたはこう考えます、「これは誰かの役に立つかも」と。 オープソースプロジェクトとしてそれをリリースしたいと思いました。 とても良いところに訪れましたね。

このドキュメントはPythonプロジェクトをリリースするあなたの手助けします。 あなたが作成することになるPythonプロジェクトのファイル構成は以下のようになっています。 私のプロジェクトである googlemaps モジュールを例に使いながら説明していきます。

Pythonプロジェクトの構成

目標としてはリリースの前にこれらのファイルを作成することです。 コードやコマンドを例に使いながら、順を追ってよいPythonソフトウェアを どうやったら作れるのかを説明していきます。 各リンクをクリックすることで、その章にジャンプします。 googlemaps source を見てください。このプロジェクトはひとつの モジュールから構成されていますが、フルパッケージ(バンドルモジュール)の モノよりは簡単です。それでははじめていきましょう。

プロジェクトのホスティング

ホストの選択

ユーザがあなたのソフトウェアをダウンロードし、どのように使用するのかを知るために、 そしてよいフィードバックを得るためにインターネット上で公開する必要があります。 いくつかのウェブサイトは無料でプロジェクトをホストできます。 一般的なホストは一覧を見てください。 基本的な要件としては、ウェブページ、バージョン管理システム、 そしてフィードバックシステムが使えることです。 フィードバックの仕組みとしては、バグトラッカやフォーラム、 メーリングリスト等があります。 ホスト先をもし決めかねているなら、 一番古くからあり多くの人に知られているSourceforgeを使うのが良いと思います。 今回はSourceforgeを使って説明していきます。

プロジェクト名の選択

あなたは登録にあたってプロジェクト名を決める必要があります。 プロジェク名は重要ですが、あまり多くの時間をかけすぎない方が良いと思います。 GoogleThe Python Package Indexfreshmeat 等で同じ名前がないか確認してみてください。 (商標はまた別ですが)ほとんど関係ないものであれば大丈夫でしょう。 もしあなたが考えた名前がすでに使われていた場合は”Py”か”Python”をつける、 または Monty Python からヒントを得ることを検討してみてください。

ノート

ホスト先でプロジェクト名または”省略表記名”を取得するかもしれません。 ホームページのURLがこれらに影響されて、”ファインダビリティ”を損なうことになるかもしれません。 プロジェクトの実際の名前はホスト上使用される表記と異なっていても問題ありませんが、 できるだけあわせた方がよいでしょう。 このことを重要なことだと考えるのなら、 プロジェクトの名前を変えるか、ミスマッチした名前を受け入れるか、 あなたの名前が使えるホスティングサービスを探すかしてください。

ノート

あなたは自分のウェブサイト上でプロジェクトをホストすることができますが、 それにはより多くの手間がかかります。

あなたが選択したホストのアカウントでサインアップします。 プロジェクトを登録し、プロジェクトのメタデータを入力します。 概要、カテゴリ、タグかキーワード、プログラミング言語、等が含まれます。 これらによってソフトウェアを簡単に探し出し、どのようなソフトウェアなのかというのを 理解してもらえるようになります。 (選択したホストによっては、この時点でソフトウェアのライセンスを選択する必要があります。 詳しくは ライセンス の章を参照してください。)

オープンソースプロジェクトのホスト一覧

バージョン管理

リポジトリ作成

コードをインターネット上で管理するために、 バージョン管理システム(VCSはリビジョン管理、ソースコード管理システムとも呼ばれます) の設定をおこなう必要があります。

Subversionは広く知られたバージョン管理システムで、最も使われています。 多くのホストでサポートされていて、すべてのプラットフォーム(OS)で使うことができます。 この文章ではSubversionを使って説明しますが、 もちろん他のバージョン管理システムを選択してもかまいません。 機能としてはそれらは基本的に同じであり、 後々変更したいと思ったらexportしてからimportすればよいのです。

ホストの選択によってバージョン管理システムの選択にも制限があることに注意してください、 逆もまたしかりです。

プロジェクトのウェブサイトでSVN(git、hg、bzr...)リポジトリを作成してください。

コードのバックアップ

何か起こった時のために、バックアップとしていつでもtarボールを作成しておくのは良い心がけです。

ノート

この文章ではUnixコマンドとパスを使っていますが、他のOSでも概念は共有できます。

Pythonのソースが /path/to/googlemaps/googlemaps.py にあるとします。 /path/to/ はシステムに、 googlemaps はプロジェクト名によって必要に応じて置き換えてください。 tarボールを作成するには以下のようにします:

$ cd /path/to/

$ tar czvf googlemaps.tgz googlemaps/

このとき、( *.pyc のような)コンパイル済みファイル、バイナリファイル、 隠れ設定ファイルやディレクトリ、そして公開によって共有したくない個別ファイルは消去すべきです。

編集用の新しいディレクトリを作成するために、コードがあるディレクトリ自体を移動させます。

$ mv googlemaps/ googlemaps-backup/

リポジトリのチェックアウト

URLかコマンドによってリポジトリをチェックアウトします。 svn コマンドでSourceforgeからチェックアウトを行うには以下を実行します:

$ cd /path/to/googlemaps

$ svn co https://googlemaps.svn.sourceforge.net/svnroot/googlemaps googlemaps

新たに作成された googlemaps ディレクトリには .svn ディレクトリ(VCSによって異なります)が含まれています。

ワーキングリポジトリにコードをコピーする

新しく作成された googlemaps ディレクトリ(これがプロジェクトです!)に ソースコード用に新しいサブディレクトリを作成します。 ソースコードはプロジェクトかパッケージと同じ名前のサブディレクトリに格納します。

$ svn mkdir /path/to/googlemaps/googlemaps (これは svn の例!)

$ cp -a /path/to/googlemaps-backup/* /path/to/googlemaps/

リポジトリにコードを追加する

$ cd /path/to/googlemaps/

$ svn add *

変更をコミットする

$ svn commit -m "Initial import."

プロジェクトホストのサーバにマスターファイルが作成されました。 以降、自分のマシン上のワーキングディレクトリですべての変更を行います。 最新のバージョン管理システムを使っているのなら、適宜リンクを参照してください。 ただ基本的には、どのバージョン管理システムもソースコードの追加、移動、削除ができます。 svn での基本的なコマンドは以下です:

svn stat - 変更と追加状態の表示
svn commit - 変更の保存
svn add - 新規ファイルをバージョン管理下におく
svn mv - ファイルの移動したいときに使用 ( /bin/mv の代わりに使用)
svn rm - ファイルの削除を通知 ( /bin/rm の代わりに使用)
svn mkdir - ワーキングコピーに新たなディレクトリを作成 ( /bin/mkdir の代わりに使用)
svn update - リポジトリからワーキングコピー変更を反映

バージョン管理システム一覧

コードの品質

良いコードを書くこととは長い旅のようなものです。 Andrew HuntとDavid Thomasによって書かれた「 達人プログラマー 」 (原書:The Pragmatic Programmer)は良い足がかりとなります。 Steve McConnell著「 Code Complete 」も良いでしょう。 良いデザインと実装について学び、そしてそれを使ってみてください。 たぶん一番の近道は他のハッカーにあなたのコードを読んでもらい、使ってもらうことです。 他の人、つまり同僚や顧客、潜在的な雇用者が読めるようなコードを書いてください、 そうすればプロジェクトは評判になってきます。 学んだことを活かして良いコードを書いてください。 (##それがあなたの落胆と時間の節約になるとだけ言っておきます。)

良いコードを書くこととは芸術のようなものです。 美意識は主観的なものですがPythonでは PEP 8 と呼ばれる標準スタイルガイドがあります。 PEP 8を読んでください。 pep8 と呼ばれるツールがあるので、それを対象となるコードに使用して構文をチェックしてください。

良いコードを書くこととは科学のようなものです。 コードの品質は客観的な数値として計測することができるのです。 まずは ユニットテスト が正しく実施できていることを確認してください。 次に Pylint でチェックして、 よく コードの臭いen )を確認してください。

Pylint

$ sudo easy_install pylint

$ pylint mymodule.py

Pylintはコードの多くの潜在的な問題を警告してくれます。 あなたはまず命名規則に関して気づかされる部分があることでしょう。 キャメルケースである ClassNames (クラス名)と ExceptionNames (例外名)は例外として(それは エラー とされます)、 普通はすべての名前は lowercase_with_underscores (小文字とアンダースコア)にすべきです。 “定数” は UPPER_CASE_UNDERSCORE (大文字とアンダースコア)にします。 _private_identifiers (プライベート変数名)はアンダースコアで始めます。 ただしモジュールの場合、パブリックなクラス、関数、データは __all__ と呼ばれるグローバルスコープのリストで定義するのが良い方法です:

__all__ = ['GoogleMaps', 'GoogleMapsError']

以下に要点を簡単に書きます。 1文字や2文字の変数名は短すぎます。字下げは4つのスペースです。 オペレータ(訳注:+や-等)の前後やカンマの後ろにはホワイトスペースを入れます。 ドキュメンテーション文字列を書きます。 シャドウ変数(訳注:同じ名前の変数を使用して変数を再定義すること)は使ってはいけません。 NoneTrueFalse との比較は is を使います。 Exception のサブクラスでモジュール例外を使ってください。 try はできるだけ限定した使い方をしてください、 ( Exception を使わないときは)可能な限り例外を捉えるようにしてください。 コードをシンプルに保ってください。最後に重要なことですが、グローバル変数を使わないでください。

Pylintが出力する警告について学んでください。 フェールスポジティブ(訳注:ツール側の誤判定)であれば無視してもかまいません。 もしPylintが誤っていて本当にあなたのコードが正しいものであれば、 以下のようにしてPylintにわかるようにコードに明示してください:

def fetch_json(query_url, params={}, headers={}):       # pylint: disable-msg=W0102
    ...

少なくとも8以上のスコアをとれるようにしてください。 個人的には、1行あたりの最大長が79文字以内になっているかどうかの警告についてはなおすようにしています (ユーザが対話的なヘルプを使えるように、ドキュメンテーション文字列を書くようにしています)。

将来に対する準備

Pythonは Python 2 と下位互換の無い Python 3 に移行し始めています、 将来に備えて、Python 2.6以降で -3 オプションを指定して ユニットテスト を実行しておきましょう:

$ python -3 test/test_mymodule.py

Python 3に変更したときに出力される警告を参照できます。 もし本気でPython 3上で動かしたいと思うのであれば、 2to3 ツールを使ってPython 3のコードに変換してください、 そして、Python 3をインストールし(Python 2もまだ置いておいて!)、 ユニットテストを実行してください。 両方のバージョンをメンテナンスしないでください、 2to3 を実行することでバージョン2.xのソースコードでも動かせますので。

コードの品質はオープンソースプロジェクトにおいて最も重要な事柄のひとつです。 いったんパッケージの準備が整えば、コードの品質向上に多くの時間を注ぎ込むことになるでしょう。

Pythonのコード品質関連ツール一覧

ユニットテスト

良い方法はユニットテスト実行して常にコードをチェックすることです。 変更のたびに自動的に行わせるようにすればなお良いです。 コードを書いたらテストを行うのが ユニットテスト の前提です。 そうすることで容易にコードを変更することができるようになります。 ここで言う ユニット とは、モジュール、クラス、または関数のことで、部分的な機能毎にわけてテストします。 そうすることで全体の動作が保証されるのです。

doctest

Pythonは2つのテスト用標準モジュールを持っています、 doctestunittest (こちらが重要!)です。 doctest は一石二鳥なモジュールで、コード例で使い方を説明しますが まさにあなたが予想した通りの答えになります。 Pythonインタラクティブシェルで実行し、それをチェックして、 ドキュメンテーション文字列に貼付ければよいのです:

def local_search(self, query, numresults=_LOCAL_RESULTS_PER_PAGE, **kwargs):
    """
    Searches Google Local for the string `query` and returns a
    dictionary of the results.

    >>> gmaps = GoogleMaps()
    >>> local = gmaps.local_search('sushi san francisco, ca')
    >>> result = local['responseData']['results'][0]
    >>> print result['titleNoFormatting']
    Sushi Groove
    """

そして以下のようにメインルーチンを追加すれば良いのです:

if __name__ == "__main__":
    import doctest
    doctest.testmod()

スクリプトとして実行すれば、 doctest モジュールは自動的にドキュメンテーション文字列からテストコードを取り出し、 実行し、ドキュメンテーション文字列上の出力結果と比較してテスト結果を出力します。

テストコードを書くことで 良いドキュメント の一部となり、 doctest を使うことで大した労力を伴うことなくテストが行えるのです。

unittest

unittest モジュールはPython標準の “重量級” ユニットテストフレームワークです。 doctest より少しだけ融通が利き、機能が充実していますが、 使いこなすには少し時間をかけて学ぶ必要があります。 以下は unittest モジュールを使ったテストです:

import unittest
from googlemaps import GoogleMaps

class Test(unittest.TestCase):
    """Unit tests for googlemaps."""

    def test_local_search(self):
        """Test googlemaps local_search()."""
        gmaps = GoogleMaps(GMAPS_API_KEY, referrer_url='http://www.google.com/')
        local = gmaps.local_search('sushi san francisco, ca')
        result = local['responseData']['results'][0]
        self.assertEqual(result['titleNoFormatting'], 'Sushi Groove')

if __name__ == "__main__":
    unittest.main()

test/test_googlemaps.py を呼び出します、一般的に test と言う名前でディレクトリの中に格納しておきます、そして test_modulename.py というファイル名にします。 modulename モジュールのためのテストはすべてこのファイルで行い、 modulename のすべての機能をテストするようにします。

doctestを使いたいのなら test/test_modulename.py を以下のようにして実行してください:

import unittest
import doctest

import googlemaps

class Test(unittest.TestCase):
    """Unit tests for googlemaps."""

    def test_doctests(self):
        """Run googlemaps doctests"""
        doctest.testmod(googlemaps)

if __name__ == "__main__":
    unittest.main()

Pythonのユニットテストのための標準が unittest モジュールです。 ##多くのツールやIDEで使われており、 unittest のテストがインターフェースとなっています。

テストを作成する

VCSを使ってプロジェクトのルートディレクトリに test ディレクトリを作成してください:

$ cd /path/to/googlemaps/

$ svn mkdir test

test_modulename.py ファイルを作成し、 unittest モジュールをインポートしてください。 テストモジュールはプロジェクト本体のコードとディレクトリを分けてください。 PYTHONPATH 環境変数にその親ディレクトリを追加してください。実行までの手順は以下です:

$ cd /path/to/googlemaps

$ export PYTHONPATH=$PYTHONPATH:/path/to/googlemaps/googlemaps

$ python test/test_googlemaps.py

最後に、Pythonで人気のあるユニットテストフレームワークを紹介します。 nose です。 nose モジュールはシンプルでありながら、 unittest モジュールを拡張したフレームワークです (例えば、自動であなたのテストコードを見つけたり、 PYTHONPATH を設定してくれたり、ということができます)。 ただしPythonの標準モジュールには含まれていませんので注意してください。

まとめると、ユニットテストを書き、それを実行します。いつでもです。 そうすることで、コードをリリースに関して自身が湧くようになってきます。

ユニットテストに関する資料

ドキュメンテーション

良いドキュメントはユーザにコードの使用方法を示すことと、 あなたが 信頼できるものを作成していると思ってもらうために重要なものになります。 doctest モジュールを使えば、ドキュメントを使ったテストができるのです。 Pythonでは docstrings モジュールを使ってソースコードの中にドキュメントを 入れることができます、##よく3つのコメントの意味を担っています。 ドキュメンテーション文字列の拡張フォーマッティング、見栄えの良いドキュメントの印刷または ウェブページの生成を自動的に行うことが可能です。

私はコードを書く 前に (または並行して)ドキュメントを書くことを提案します。 これはユーザ中心のデザインとして用いられているすばらしい方法です。 あなたはいくつかのポイントについて使用方法を書くべきです、## そうすることで、より簡単に実装でき、テストも保守も楽になります、賭けてもよいです。 コードをコミットする前にドキュメントを書くことで、 どのようにそれが動作するのか理解し易くなります。

あなたが高レベルのモジュールを書くときにはうまく働きます。 自分自身に尋ねてみてください、 XYZ というモジュールを見つけ出したとして、 それに何を求めるでしょうか?どうやって使うの?まず何から調べればいいの? どんな例を見たい? 良いドキュメント(とコード)を あなた のために書いてください。 このすばらしい架空のモジュールのためにドキュメントを書いてください。

ドキュメンテーション文字列内でreStructuredTextを使う

Pythonコミュニティはドキュメンテーション文字列のマークアップのために reStructuredText を使用することに興味が向いているようです。 Javadocのような感じです。使用例を示します:

def reverse_geocode(self, lat, lng, sensor='false', oe='utf8', ll='', spn='', gl=''):
    """
    Converts a (latitude, longitude) pair to an address.

    Interesting bits:

    >>> gmaps = GoogleMaps()
    >>> reverse = gmaps.reverse_geocode(38.887563, -77.019929)
    >>> address = reverse['Placemark'][0]['address']
    >>> print address
    200 6th St SW, Washington, DC 20024, USA
    >>> accuracy = reverse['Placemark'][0]['AddressDetails']['Accuracy']
    >>> print accuracy
    8

    :param lat: latitude
    :type lat: float
    :param lng: longitude
    :type lng: float
    :return: `Reverse geocoder return value`_ dictionary giving closest
        address(es) to `(lat, lng)`
    :rtype: dict
    :raises GoogleMapsError: If the coordinates could not be reverse geocoded.

    Keyword arguments and return value are identical to those of :meth:`geocode()`.

    .. _`Reverse geocoder return value`:
        http://code.google.com/apis/maps/documentation/geocoding/index.html#ReverseGeocoding

    """

以下のような感じで自動的にHTMLを生成できます:

GoogleMaps.reverse_geocode(lat, lng, sensor='false', oe='utf8', ll='', spn='', gl='')

Converts a (latitude, longitude) pair to an address.

Interesting bits:

>>> gmaps = GoogleMaps(api_key)
>>> reverse = gmaps.reverse_geocode(38.887563, -77.019929)
>>> address = reverse['Placemark'][0]['address']
>>> print address
Independence and 6th SW, Washington, DC 20024, USA
>>> accuracy = reverse['Placemark'][0]['AddressDetails']['Accuracy']
>>> print accuracy
9
パラメタ:
  • lat (float) – latitude
  • lng (float) – longitude
戻り値:

Reverse geocoder return value dictionary giving closest address(es) to (lat, lng)

戻り値の型:

dict

例外 GoogleMapsError:
 

If the coordinates could not be reverse geocoded.

Keyword arguments and return value are identical to those of geocode().

キーポイント:

  • 通常のドキュメンテーション文字列のフォーマットは PEP 257 を参照してください。
  • 識別子への参照は `バッククオート` で囲みます。
  • :param lat: latutide は引数の説明です。
  • :type lat: float は引数の型についてです。
  • :return: dictionary giving closest addresses... は戻り値の説明です。
  • :rtype: dict は戻り値の型についてです。
  • :raises GoogleMapsError: If coordinates could not... は例外についてです。
  • >>> はdoctestの始まりを示し、自動的にコードを整形します。 :: か4つのスペースで字下げし、空行で分離します。
  • 他のメソッド、関数、クラス、モジュールは :meth:`mymethod`:func:`myfunc`:class:`myclass`:mod:`mymodule` のようにします。
  • ハイパーリンクは `Google`_ のようにバッククオート(`)で囲ってアンダーバー(_)を単語末尾につけます。 リンク先を指定したい場合は .. _Google: http://www.google.com/ のようにしてください。
  • 詳しくは reStructuredText のドキュメントを参照するようにしてください。

Sphinxを使ってドキュメントを生成する

Sphinx を使ってドキュメントを作成する方法をお教えしましょう。 SphinxはPython自身の公式ドキュメンテーションツールであり、Pythonのプロジェクトで多数使われています。 http://docs.python.org/ で作成されたものを見ることができます。 Sphinxであなたのモジュール用に自動的なドキュメント生成するためのセットアップは簡単です。 プロジェクトのルートディレクトリ(ドキュメント作成の場所としては一般的な場所です)にVCSを使って doc/ ディレクトリを作成し、 sphinx-quickstart コマンドを打ちます:

$ cd /path/to/googlemaps

$ svn mkdir doc

$ cd doc

$ sudo easy_install sphinx

$ sphinx-quickstart

いくつかの質問に答えます(デフォルトが良いでしょう。ただし、 autodoc モジュールは’yes’と答えておきましょう)。 答え終わったら、 index.rst ファイルに以下を追加しましょう:

.. automodule:: googlemaps

##ドキュメンテーション文字列の中には含まないでください。 もちろん index.rst と Sphinxの conf.py ファイルはバージョン管理しておきましょう:

$ svn add index.rst conf.py

doc/ ディレクトリ上で sphinx-build コマンドを実行し、ドキュメントを生成しましょう:

$ sphinx-build . html/

(動作には、環境変数 PYTHONPATH/path/to/googlemaps/googlemaps を追加する必要があるかもしれません。)

doc/html/ にHTMLドキュメントが作成されます。Sphinxは非常に美しいドキュメントを生成します。 ウェブブラウザでそれを見てみてください。 ##あなたが書いたものが美しく仕上げられるので、 より良いドキュメントを作成しようと思うようになるでしょう。

README

コードのドキュメンテーション文字列とHTMLドキュメントに加えて、 README.txt ファイルをディレクトリのトップレベルに作成すべきです。 もちろんバージョン管理も行いましょう。 README.txt ファイルは以下のものを含むべきです:

  • パッケージ名、バージョン、リリースの日付
  • パッケージの説明文
  • 依存しているPythonのバージョン
  • パッケージのインストール方法( easy_install packagename で十分でしょう)
  • もしあなたのパッケージにスクリプトが含まれているのであればその使用方法
  • パッケージの作者名と連絡手段##
  • コピーライトと ライセンス について
  • ドキュメントへのリンク

中にはこれらの内容を複数のファイルに分けて ( INSTALLAUTHORSANNOUNCE 等)作成する人がいますが、 個人的にはできるだけシンプルにするほうが好みです。

もしすでにドキュメンテーション文字列かその他のものに上記のような情報を書いているのなら、 必ず don’t repeat yourself [05]: Sphinxを使ってプレーン(reStructured)テキストを生成するか、スクリプトを使って README.txt ファイルを生成してください。 mymodule.__doc__ のようにすれば、モジュールやクラス、関数等から ドキュメンテーション文字列を取得することができます。 Sphinxでプレーン(reStructured)テキストを text/ ディレクトリに作成する方法は以下になります:

$ sphinx-build -b text . text/

ドキュメンテーションに関する資料

ライセンス

あなたはコードのライセンスを決める必要があります。 一般的なオープンソースライセンスはGPLやLGPL、BSDライセンス、 MIT/X11ライセンス、Apapcheライセンス、Eclipseライセンス、Mozillaライセンスです。 ここではあなたのライセンス選択のガイドとなるように、いくつかのリソースを示します。 あなたのライセンスの選択によって、どのオープンソースプロジェクトに取り入れられるのかが変わってきます。 プロジェクトホストの選択によっても、ホストが使っているソフトウェアが決まっていますので、 ライセンス選択に関係するかもしれません。 ライセンスについて学んで、コードがどう使われるのかを考えて、ライセンスを選択してください。

ライセンスを選択する際は、 Open Source Initiative でライセンスの全文を見ることができます。 ライセンスをよく読んで、それに同意してください。 その全文をコピーして、プロジェクトのトップディレクトリの LICENSE.txt ファイルを作成してそれを 張り付けてください(VCSで管理もおこなってください)。 すべてのソースコードの一番上の部分にコメントとしてライセンス情報を記入しておいてください。 参照先情報を含む、要約した文章を含むようにしてください。 あなたのソースコードにライセンスの全文を書く必要はありません、 以下で示した情報を参照するようにしてください。 もしかなりの量のドキュメントがあるなら、 フリーなドキュメント向けライセンス を選択して ドキュメントだけわけてライセンス設定すると良いでしょう。

ライセンスに関する資料

パッケージング

パッケージングはディレクトリ構成を整えて、ユーザがダウンロードして使ってもらうようにすることです。 Pythonでは distutils を使うのが一般的です。 setup.py ファイルを作成し、 easy_install コマンドを実行します。

setup.py

以下が setup.py の例です:

from distutils.core import setup
import sys

sys.path.append('googlemaps')
import googlemaps


setup(name='googlemaps',
      version='1.0',
      author='John Kleint',
      author_email='py-googlemaps-general@lists.sourceforge.net',
      url='http://sourceforge.net/projects/py-googlemaps/',
      download_url='https://sourceforge.net/projects/py-googlemaps/files/',
      description='Easy geocoding, reverse geocoding, driving directions, and local search in Python via Google.',
      long_description=googlemaps.GoogleMaps.__doc__,
      package_dir={'': 'googlemaps'},
      py_modules=['googlemaps'],
      provides=['googlemaps'],
      keywords='google maps local search ajax api geocode geocoding directions navigation json',
      license='Lesser Affero General Public License v3',
      classifiers=['Development Status :: 5 - Production/Stable',
                   'Intended Audience :: Developers',
                   'Natural Language :: English',
                   'Operating System :: OS Independent',
                   'Programming Language :: Python :: 2',
                   'License :: OSI Approved :: GNU Library or Lesser General Public License (LGPL)',
                   'License :: OSI Approved :: GNU Affero General Public License v3',
                   'Topic :: Internet',
                   'Topic :: Internet :: WWW/HTTP',
                   'Topic :: Scientific/Engineering :: GIS',
                  ],
     )

もし download_url をまだ書いていなくても心配しないでください。 自分モジュールの __doc__ 文字列を long_description に使っています、 どんなテキストでも使用することができます。 パッケージにモジュールを含んでいるのであれば py_modulespackages を入れ替えて package_dir を削除してください。 PyPIの trove classifiers リストから classifiers の項目を見つけてください。 もしサードパーティのパッケージかモジュールに依存しているのなら、 required キーワードを設定してください。

以下は、 パッケージルートディレクトリに作成した MANIFEST.in ファイルです、これは ドキュメントやその他のファイルをパッケージに含める時に必要です:

recursive-include doc/html *
prune doc/html/.doctrees/
exclude doc/html/.buildinfo
include LICENSE.txt

では setup.py sdist コマンドでパッケージをビルドしてみましょう:

$ python setup.py sdist

エラーが発生していなければ dist/googlemaps-1.0.tar.gz が作成されているはずです。 cheesecake_index コマンドを使って、インストールに問題が無いことと パッケージ提供に問題が無いかを確認しましょう:

$ sudo easy_install cheesecake

$ cheesecake_index --path=dist/googlemaps-1.0.tar.gz

パッケージがインストールできることをすぐに確認できます。 個人的にはインストールのし易さとドキュメントの整備具合にやや比重が置かれているように思います、 cheesecake index によると70%位を目指すと良いそうです。

パッケージングに関する資料

リリース

dist/googlemaps-1.0.tar.gz ファイルをビルドできました、 さっそくアップロードしてみましょう。プロジェクトホストはリリースのためにファイルを アップロードをするように言ってきます、たいていのホスト先はウェブかSCP/SFTPかFTP経由で 行うことになるでしょう。ではパッケージをアップロードしましょう、 docs/html ディレクトリに ドキュメントをアップロードしてください(サブディレクトリを忘れないでください)。 ライセンス等の情報が変わっているのであれば、アップロード後にプロジェクト情報を変更してください。 あなたのプログラムがGUIであれば、いくつかスクリーンショットを撮って、 プロジェクトのウェブページに加えると良いでしょう。

パッケージをダウンロードできるURLをコピーして(リンクを含んだページが良いでしょう)、 setup.pydownload_url に設定してください。

PyPI

あなたはおそらく Python Package Index にパッケージを登録したくなるでしょう。 PyPIは、 easy_installpip を使って、自動でダウンロードとインストールをおこなえます。 PyPIアカウントを取得する必要があります(無料です)。 取得はこのような感じでパスワードを使うことによってPyPIのウェブサイトか コマンドライン経由でおこなうことができます:

$ python setup.py sdist register upload

これでパッケージのビルド、ユーザネームとパスワードの問い合わせ、 PyPIへのパッケージ(とメタデータの)登録、アップロードができます。 パッケージのアップロードは必ず必要というわけではありませんが、 パッケージ自体を探し出すのが簡単になります。

また、Windowsユーザ向けのインストーラを作成することもできます:

$ python setup.py bdist_wininst upload

これで dist/googlemaps-1.0.win32.exe のようなファイルが作成され、 アップロードも行えます。(Python2.6では変な名前がつくバグがありますが、リネームするだけで解決できます。)

PyPIで http://pypi.python.org/pypi/projectname/ プロジェクトページを訪れてみてください、 setup.pylong_description の文がウェブページのはじめの方にきているのに気づいたでしょう。 PyPIは reStructuredText をうまく理解して、あなたが書いた long_description を抜き出して 表示してくれるのです。 PyPIはreStructuredTextを sphinx-build -b text . text/ と実行したときのような “シンプルな” テキスト形式にします。 バージョンナンバーを変えずに再登録することで修正することができます。 また、PyPIのウェブサイト経由でもプロジェクトのメタデータを編集することができます。

最後に

Pythonパッケージのリリース、おめでとう! あなたのコードは成長し、よい土台ができ、 Pythonのオープソースプロジェクトのメカニズムについて知ることができたのです。 最後になりましたが、オープソースプロジェクトの運営については Karl Fogelが執筆した無料の書籍「 Producing Open Source Software 」(訳注: [10] ) を読むとよいでしょう。それでは幸運を。

人生の楽しい面だけをみていようぜ...
人生の楽しい面だけをみていようぜ...
[02]訳注:原書名「The Pragmatic Programmer」
[03]訳注:原書名「Code Complete」
[05]日本語リンク
[10]日本語訳「 オープンソースソフトウェアの育て方
Author:John Kleint <First initial. Last name. Gmail.>
Version:0.7.1
License:Creative Commons Attribution-Share Alike 3.0 ( ja )
URL:http://infinitemonkeycorps.net/docs/pph/

翻訳について

## がついている箇所はほとんど意味読み取れなかったところです。 翻訳についての質問・改訳点等ありましたら服部 <syobosyobo@gmail.com> までご連絡いただければさいわいです。