🧐

python アプリケーション開発中、 git submodule で取り込んだパッケージ内の依存解決に躓いた

2022/10/02に公開

問題

  • 複数のアプリケーションで共通のビジネスルールを利用したい
  • ビジネスルールを公開したくはない
  • 個人開発なのでチーム開発ほどのコストをかけたくない
  • pythonのアプリケーションである
  • どうするか?

対応

共通のビジネスルールを切り出す。
それを単一のprivate repositoryとして管理する。
このrepositoryをsubmoduleとして取り込む。

取り込むことは簡単にできた。
だが、取り込んだパッケージの作りが悪く、そのまま使うことができなかった。
具体的には、取り込んだパッケージ内での依存解決ができない状態になった。

共通ビジネスルールパッケージのディレクトリ構造は下記のようになっていた。

├─domains
│  ├─bar
│  └─foo

また、fooはbarに依存している。
下記の類の依存がある。

# domains/bar/domain.py
class Domain:
    def __init__(self, prefix: str):
        self.__prefix = prefix

    def dummy(self) -> str:
        return "{}: bar".format(self.__prefix)
# domains/foo/domain.py
from domains.bar.domain import Domain as Bar


class Domain:
    def __init__(self, bar: Bar):
        self.__bar = bar

    def dummy(self):
        print("foo, {}".format(self.__bar.dummy()))

あるアプリケーションでgit submoduleを使ってパッケージを取り込んだところ、下記の構造になった。

├─py_hoge_domain
│  └─domains
│      ├─bar
│      └─foo

py_hoge_domainは、共通ビジネスルールのパッケージ名。
この状態で下記を実行すると、エラーになる。

if __name__ == '__main__':
    from py_hoge_domain.domains.bar.domain import Domain as Bar
    from py_hoge_domain.domains.foo.domain import Domain as Foo

    Foo(Bar("sandbox")).dummy()

ModuleNotFoundError: No module named 'domains'

なので、相対パスでimportする形に変更した。

from ..bar.domain import Domain as Bar

上の Foo(Bar("sandbox")).dummy() を実行したところ、

foo, sandbox: bar

と、期待通りの出力が出た。
問題は解消された。
但し、pycharmでは警告が出ている。

domains下に __init__.py を配置すると警告が解消した。

余談

Discussion