やりたいこと Pythonモジュールをパッケージ化 モジュールのテストのために、pytestのディレクトリ構成(src、test)を使用 モジュールを使った、コマンドラインツールをインストール 作成するファイル一覧1234567891011121314├── LICENSE├── Makefile├── README.md├── setup.cfg├── setup.py├── src│ ├── consoleapp│ │ ├── __init__.py│ │ └── cli.py│ └── mypackage│ ├── __init__.py│ └── mymodule.py└── test └── test_mypackage.py setup.pysetup.pyはsetup()を呼ぶだけの内容。 123from setuptools import setupsetup() setup.cfgsetup.cfgはパッケージに関する情報を記述する。[metadata]は自身の内容を記述する。通常gitリポジトリで作成するLICENSEとREADME.mdは流用する形にしている。 12345678910111213141516171819202122232425262728[metadata]name = console_scriptsversion = attr: consoleapp.__version__url = https://xxxxxxxxxxxxxxxxxxxxxauthor = XXXXXXXXXXauthor_email = xxxxxxx@xxxxxxxxxxxxlicense_file = LICENSEdescription = console scriptslong_description = file: README.mdlong_description_content_type = text/markdown[options]zip_safe = Falsepackage_dir= =srcpackages = find:install_requires =[options.extras_require]dev = pytest[options.packages.find]where=src[options.entry_points]console_scripts = consapp = consoleapp.cli:main srcディレクトリ以下にソースコードを置くための記述package_dirでsrcディレクトリを指定する。パッケージを探索もsrcディレクトリを参照する。 1234567[options]package_dir= =srcpackages = find:[options.packages.find]where=src pytestでテストするために開発時はpytestパッケージをインストールする[options.extras_require]で指定したオプションを使って開発時のインストールでpytestパッケージを要求パッケージにする。 123[options.extras_require]dev = pytest 開発時は以下のコマンドで、指定した要求パッケージをインストールすることができる。 1pip install -e .[dev] コマンドラインツールをインストールする[options.entry_points]でコマンドラインツールとしてインストールする。下の設定例ではconsappというコマンド名で/usr/local/binにインストールされる。consoleapp:mainでconsoleapp.pyにあるmainを実行する。 123[options.entry_points]console_scripts = consapp = consoleapp.cli:main バージョン情報を参照するバージョン情報を__init__.pyに記述。 1__version__ = '0.0.1' 記述したバージョン情報はattrで参照できる。 1version = attr: consoleapp.__version__ サンプルコード(src/mypackage/mymodule.py)mypackage/mymodule.pyとして以下の内容を作成。 12def add(x, y): return x + y サンプルコード(src/consoleapp/cli.py)cli.pyはmypackage/mymodule.pyを使って結果を表示するmain()が定義している。 1234567891011121314import randomimport mypackage.mymoduledef main(): x = random.random() y = random.random() print("X={}".format(x)) print("Y={}".format(y)) print("X+Y={}".format(mypackage.mymodule.add(x, y)))if __name__ == '__main__': main() サンプルテストコード(test/test_mypackage.py)test/test_mypackage.pyにテストコードを置く。pytestはファイル名にtestを含むものを処理していく。 1234import mypackage.mymoduledef test_mypackage(): assert mypackage.mymodule.add(1,1) == 2 パッケージ作成と実行例dev指定でインストールしてpytestを実行する[dev]オプション付きでインストールすると、指定したpytestパッケージもインストールされる。 1234567891011121314151617181920212223242526$ pip install -e .[dev]Obtaining file:///work/setuptools/min_packageCollecting pytest Downloading pytest-5.4.1-py3-none-any.whl (246 kB) |████████████████████████████████| 246 kB 3.2 MB/sCollecting more-itertools>=4.0.0 Downloading more_itertools-8.2.0-py3-none-any.whl (43 kB) |████████████████████████████████| 43 kB 2.1 MB/sCollecting wcwidth Downloading wcwidth-0.1.9-py2.py3-none-any.whl (19 kB)Collecting pluggy<1.0,>=0.12 Downloading pluggy-0.13.1-py2.py3-none-any.whl (18 kB)Collecting attrs>=17.4.0 Downloading attrs-19.3.0-py2.py3-none-any.whl (39 kB)Collecting py>=1.5.0 Downloading py-1.8.1-py2.py3-none-any.whl (83 kB) |████████████████████████████████| 83 kB 2.2 MB/sCollecting packaging Downloading packaging-20.3-py2.py3-none-any.whl (37 kB)Requirement already satisfied: six in /usr/local/lib/python3.8/site-packages (from packaging->pytest->console-scripts==0.0.1) (1.14.0)Collecting pyparsing>=2.0.2 Downloading pyparsing-2.4.7-py2.py3-none-any.whl (67 kB) |████████████████████████████████| 67 kB 5.1 MB/sInstalling collected packages: more-itertools, wcwidth, pluggy, attrs, py, pyparsing, packaging, pytest, console-scripts Running setup.py develop for console-scriptsSuccessfully installed attrs-19.3.0 console-scripts more-itertools-8.2.0 packaging-20.3 pluggy-0.13.1 py-1.8.1 pyparsing-2.4.7 pytest-5.4.1 wcwidth-0.1.9 pytestでテスト実行。以下はキャッシュを残さないオプション付きで実行している。 123456789$ pytest -p no:cacheprovider================================ test session starts ================================platform linux -- Python 3.8.2, pytest-5.4.1, py-1.8.1, pluggy-0.13.1rootdir: /work/setuptools/min_packagecollected 1 itemtest/test_mypackage.py [100%]================================= 1 passed in 0.07s ================================= インストールしてコマンドラインツールを実行するインストールすると作成したPythonパッケージとconsappコマンドがインストールされる。 12345$ pip install -e .Obtaining file:///work/setuptools/min_packageInstalling collected packages: console-scripts Running setup.py develop for console-scriptsSuccessfully installed console-scripts /usr/local/bin/にインストールされパスも通った状態になっている。 1234$ consappX=0.8166454250641093Y=0.9771692906142968X+Y=1.7938147156784061 GitHubからインストールするHTTPでインストールする場合 1pip install git+https://github.com/xxxxxxxxxxx/xxxxxx.git SSHでインストールする場合 1pip install git+ssh://git@github.com/xxxxxxxxxxx/xxxxxx.git 参考 Configuring setup() using setup.cfg files