tl;dr
で普段他の言語でやってる感じのディレクトリ構成がことごとくアンチパターンになっていたし実際動かないので色々調べてどうやらこの構成ならうまくいきそうだというのの健忘です。
結論
project/
+ project/
| + __init__.py
| + __main__.py
| + module.py
| + subpackage1/
| | + __init__.py
| | + submodule1.py
| + subpackage2/
| + __init__.py
| + submodule2_1.py
| + sunmodule2_2.py
+ tests/
+ __init__.py
+ test_module.py
+ test_submodule1.py
+ ...
__init__.py
tests
以外のこれは全部中身を書く。
project/__init__.py
from . import module
from . import subpackage1
from . import subpackage2
poject/subpackage2/__init__.py
from . import submodule2_1
from . import submodule2_2
各モジュールからのインポートのしかた
基本的には相対インポートを使う。
__main__.py
__main__.py
from . import module
moduile.function()
テストのために __main__.py
の中身はできるだけ簡素にしておくのが良さそう。
module.py
module.py
from . import subpackage1
subpackage1.submodule1.function()
隣のサブバッケージの呼び方
submodule2_1
from .. import subpackage1
subpackage1.submodule1.function()
呼び出しの度にパッケージ名書くのが面倒ならこれでもいける
submodule2_1
from ..subpackage1 import submodule1
submodule1.function()
テストコード
import 元に自身のパッケージを指定する. ただしトップレベルのモジュールが VSCode ではコード補完が効かない。 何故かサブバッケージにはコード補完が効くのでこの構成にするならもう全部サブバッケージにいれるのがいいかもしれない。
tests/test_module.py
import project
def test_module():
assert project.module.function() == 'hoge'
tests/test_submodule1.py
from project.subpackage1 import submodule1
def test_submodule1():
assert submodule1.function() == 'huga'
__main__.py
実行時
cd /path/to/project
python3 -m project
テスト実行時
cd /path/to/project
pytest tests