タイトルが長いな。
コマンドを wheel パッケージにしたときに、そのコマンドとパッケージのバージョンを合わせたい、という当然の欲求を満足するための、(現在のところ)最良と思われる方法を見つけたのでメモしておく。
コマンドでバージョンを出力するには、コマンドのスクリプト中でバージョンがわからなければならないし、パッケージングするためには setup.py の中でバージョンがわからなければならない。当然のことながら、両方にバージョンを書くのは愚の骨頂。だからどこか1ヵ所でバージョンを定義して、それをコマンドと setup.py から参照することにする。
で、それはどこなのかというと、モジュールの __init__.py の中だ。この定義をコマンドと setup.py の両方から参照するんだけど、ちょっと工夫が必要だった。
ここでは、簡単な Hello world コマンドを例に説明する。ファイル構成はこんな感じ。
^o^ > tree /f .
フォルダー パスの一覧
ボリューム シリアル番号は 666A-93A9 です
C:\USERS\TAKATOH\DOCUMENTS\SANDBOX\HELLOPY
│ setup.py
│
└─hello
hello.py
__init__.py
hello ディレクトリがモジュールになっていて、コマンドの実体(関数)は hello/hello.py ファイルに書いてある。
バージョンの定義は、次の通り、hello/__init__.py の中。
__version__ = '0.3.2'
バージョン番号はいろいろ試行錯誤した結果を反映している。
これを setup.py から参照するのは簡単。モジュールをインポートして変数を参照するだけ。
import setuptools import hello setuptools.setup( name='hellopy', description='hello app.', version=hello.__version__, author='takatoh', author_email='[email protected]', packages=setuptools.find_packages(), classifiers=[ 'License :: OSI Approved :: MIT License', 'Programming Language :: Python', 'Programming Language :: Python :: 3', ], entry_points={ 'console_scripts': [ 'hellopy=hello.hello:main', ], } )
コマンドから参照するにはもうちょっと工夫が必要。こうなった。
import os import argparse here = os.path.abspath(os.path.dirname(__file__)) about = {} with open(os.path.join(here, '__init__.py')) as f: exec(f.read(), about) VERSION = 'v' + about['__version__'] def main(): parser = argparse.ArgumentParser(description='Hello tool.') parser.add_argument('name', metavar='NAME', type=str, nargs='?', default='world') parser.add_argument('-v', '--version', action='version', version=VERSION) args = parser.parse_args() print('Hello, {name}!'.format(name=args.name)) if __name__ == '__main__': main()
hello/__init__.py を読み込んで exec で評価して変数への参照を得ている。直接 hello モジュールをインポートできれば楽なんだけど、このコマンド(スクリプト)自体が hello モジュールに属しているので、それはできないみたいだ。
というわけで、この方法が一番いいようだ。もっといい方法が見つかるまではこれで行こうと思う。
最後に、実際に wheel パッケージを作って、インストールして試してみよう。
^o^ > python setup.py bdist_wheel
^o^ > pip install dist/hellopy-0.3.2-py3-none-any.whl
^o^ > hellopy --version
v0.3.2
^o^ > hellopy
Hello, world!
^o^ > hellopy Andy
Hello, Andy!
うまくいってる。