みなさま、Pythonのパッケージ化はしたことありますでしょうか?最近以下のような記事を書きましたが、ツールを作ったものの、それを配布しようとなると、Pythonのパッケージ化に関して分からないことがあり、pypiにパッケージを登録して試してみました。
これらの記事を書いたときの自分の考えは以下のとおりです。
pip install -e .
してコマンドにパス通すの、微妙すぎる- setup.pyで、scriptsなりconsole_scriptsを使えば、コマンドが/usr/bin配下にインストールされパスを通すことができるので、どちらかでやったほうがいい
- 前者であればmain関数を用意せずとも、ファイル名を書くだけなので、そのほうが楽だと思える
コマンドにパスを通すという観点で、このような内容を書きました。
しかしながら、その後コメントにあるように、パッケージ化することを考えるなら、console_scriptsのほうがよいのではというご意見を頂き、実際どうなのだろうと思ったのです。
ということで、pypiに登録してみました。レポジトリは以下。
console_scriptsでやったもの
- レポジトリURL: https://github.com/masudaK/justHello/
- pypi URL: https://pypi.python.org/pypi/justHello/
scriptsでやったもの
- レポジトリURL: https://github.com/masudaK/justHello2/
- pypi URL: https://pypi.python.org/pypi/justHello2/
2つの差異はsetup.pyの記述だけです。 前者はこんな感じ。
entry_points={ 'console_scripts': ['justHello = bin.justHello:main'] },
bin配下をモジュール化して、main関数(名前はなんでもいい)として登録する必要があります。
後者はこんな感じ。
scripts=['bin/justHello2'],
ファイル名をそのまま書くだけですね。
ちなみにbin以下のファイルはこんな感じのスクリプトになってます。
def main(): print('Hello World') if __name__ == '__main__': main()
シェバンも書かず、main関数があるのみです。 では、パッケージインストール後の変化を見てみましょう。
console_scripts
console_scriptsを使ったものをpipで入れるとこんな感じになります。
# pip install justHello Downloading/unpacking justHello Downloading justHello-0.0.19.tar.gz Running setup.py egg_info for package justHello Installing collected packages: justHello Running setup.py install for justHello Installing justHello script to /usr/bin Successfully installed justHello Cleaning up...
/usr/bin以下にちゃんと入りますね。 次に、インストールされたコマンドを見ましょう。
#!/usr/bin/python # EASY-INSTALL-ENTRY-SCRIPT: 'justHello==0.0.19','console_scripts','justHello' __requires__ = 'justHello==0.0.19' import sys from pkg_resources import load_entry_point if __name__ == '__main__': sys.exit( load_entry_point('justHello==0.0.19', 'console_scripts', 'justHello')() )
見事にシェバンが追加されて、load_entry_point関数で、いい感じで読み込んでくれています。
scripts
まずインストールのログ。
# pip install justHello2 Downloading/unpacking justHello2 Downloading justHello2-0.0.2.tar.gz Running setup.py egg_info for package justHello2 Installing collected packages: justHello2 Running setup.py install for justHello2 changing mode of build/scripts-2.6/justHello2 from 644 to 755 changing mode of /usr/bin/justHello2 to 755 Successfully installed justHello2 Cleaning up...
/usr/bin以下にインストールだけではなくて、パーミッションも変わってますね。 となると、console_scriptsでは、パーミッション変えてくれないのでしょうか。
$ ll /usr/bin/justHello* -rwxr-xr-x 1 root root 314 1月 29 22:12 2015 /usr/bin/justHello -rwxr-xr-x 1 root root 77 1月 29 22:12 2015 /usr/bin/justHello2
そういうわけではないようです。となると、そこまで大きな変化はないかもしれません。
次にbin以下のファイルを見てみましょう。
def main(): print('Hello World') if __name__ == '__main__': main()
まんまですね。シェバンもなく、そのままのコードが置かれてます。 importとかあった場合に、モジュールのパスがどこを基準に書かれているか初めて見た人は混乱するかと。 また、そのままということはシェバンを書いたままパッケージ化してしまうと、そのシェバンに従ってインタープリタが固定されてしまいます。 自分の環境では/usr/bin/python3を指定して動かしていたから、そのままパッケージ化してしまったとすると、利用者の環境では動かない可能性も出てくるわけです。
「ロジックが入る」という表現をコメントでされたのですが、要はこのように処理がそのまま書かれているという状態なのですね。
終わりに
ここまで書いたとおりではありますが、console_scriptのほうが綺麗ではありますね。ただ、main関数のように一つにまとめて、それをsetup.pyで指定しなければいけないなど、ほんのほんのちょっとだけ気を遣う必要があります。まぁ、最初からそう書いておけば問題無いですし、移行するにしても、そこまでの労力ではないでしょう。
と、実際にレポジトリに登録して、試してみました。コメントでご助言頂いたこうへいさんほんとにありがとうございました!!