Setuptoolsの統合—ドキュメントをクリックします
Setuptoolsの統合
コマンドラインユーティリティを作成するときは、Unixシバンを使用するのではなく、setuptoolsで配布されるモジュールとして作成することをお勧めします。
なぜあなたはそれをしたいのですか? 理由はたくさんあります。
従来のアプローチの問題の1つは、Pythonインタープリターがロードする最初のモジュールの名前が正しくないことです。 これは小さな問題のように聞こえるかもしれませんが、非常に重要な意味があります。
最初のモジュールは実際の名前では呼び出されませんが、インタープリターは名前を
__main__
に変更します。 これは完全に有効な名前ですが、別のコードがそのモジュールからインポートする場合、実際の名前で2回目のインポートがトリガーされ、突然コードが2回インポートされることを意味します。すべてのプラットフォームで実行が簡単なわけではありません。 LinuxおよびOSXでは、ファイルの先頭(
#!/usr/bin/env python
)にコメントを追加でき、スクリプトは実行可能ファイルのように機能します(実行可能ビットが設定されていると仮定)。 ただし、これはWindowsでは機能しません。 Windowsでは、インタープリターをファイル拡張子に関連付けることができます(.py
で終わるすべてをPythonインタープリターで実行するなど)。virtualenvでスクリプトを使用する場合は、問題が発生します。実際、virtualenvでスクリプトを実行することは、OSXとLinuxでも問題になります。 従来のアプローチでは、正しいPythonインタープリターが使用されるように、virtualenv全体をアクティブ化する必要があります。 あまりユーザーフレンドリーではありません。
主なトリックは、スクリプトがPythonモジュールである場合にのみ機能します。 アプリケーションが大きくなりすぎて、パッケージの使用を開始したい場合は、問題が発生します。
序章
スクリプトをsetuptoolsにバンドルするために必要なのは、Pythonパッケージのスクリプトとsetup.py
ファイルだけです。
このディレクトリ構造を想像してみてください。
yourscript.py
setup.py
yourscript.py
の内容:
setup.py
の内容:
from setuptools import setup
setup(
name='yourscript',
version='0.1',
py_modules=['yourscript'],
install_requires=[
'Click',
],
entry_points='''
[console_scripts]
yourscript=yourscript:cli
''',
)
魔法はentry_points
パラメーターにあります。 console_scripts
の下では、各行が1つのコンソールスクリプトを識別します。 等号(=
)の前の最初の部分は、生成する必要のあるスクリプトの名前です。2番目の部分は、クリックコマンドでコロン(:
)が続くインポートパスです。
それでおしまい。
スクリプトのテスト
スクリプトをテストするには、新しいvirtualenvを作成してから、パッケージをインストールします。
$ virtualenv venv
$ . venv/bin/activate
$ pip install --editable .
その後、コマンドが使用可能になります。
パッケージ内のスクリプト
スクリプトが大きくなり、Pythonパッケージに含まれているスクリプトに切り替えたい場合、必要な変更は最小限です。 ディレクトリ構造が次のように変更されたとしましょう。
yourpackage/
__init__.py
main.py
utils.py
scripts/
__init__.py
yourscript.py
この場合、setup.py
ファイルでpy_modules
を使用する代わりに、packages
とsetuptoolsの自動パッケージ検索サポートを使用できます。 それに加えて、他のパッケージデータを含めることもお勧めします。
これらは、setup.py
の変更されたコンテンツになります。
from setuptools import setup, find_packages
setup(
name='yourpackage',
version='0.1',
packages=find_packages(),
include_package_data=True,
install_requires=[
'Click',
],
entry_points='''
[console_scripts]
yourscript=yourpackage.scripts.yourscript:cli
''',
)