pre-commit-config.yaml + poetry + mypy環境でエラーが発生し、納得はしていませんが解決方法を見つけたので紹介します。
なお、スクリプト内のupdate_pyproject_version.pyについては別記事で紹介予定のため割愛します。
コードについて
コードは下記リポジトリにコミットしています。
github.com
注意点
リポジトリは実験用のため非定期で更新します。コードは投稿内容と異なる可能性があるのでご注意ください。
本コードを実行したこと、参考にしたことによって被るあらゆる損害について責任を負いかねますのでご注意ください。
現象
poetryで管理するプロジェクトにGitフック(pre-commit フック)で静的解析ツールを実行するために、pre-commitをpoetry add pre-commitで追加しました。
poetry pre-commit installでgit/hooks/pre-commitを作成し、.pre-commit-config.yamlに各種ツールの設定をしたところ、mypy実行時に下記エラーとなりました。
poetry run pre-commit run --all-filesの実行結果
$ poetry run pre-commit run --all-files trim trailing whitespace.................................................Passed fix end of files.........................................................Passed mixed line ending........................................................Passed check toml...............................................................Passed check yaml...............................................................Passed poetry-check.............................................................Passed poetry-lock..............................................................Passed poetry-export............................................................Passed isort....................................................................Passed black....................................................................Passed flake8...................................................................Passed mypy.....................................................................Failed - hook id: mypy - exit code: 2 calculator/__init__.py: error: Duplicate module named "calculator" (also at "calculator/__init__.py") calculator/__init__.py: note: See https://mypy.readthedocs.io/en/stable/running_mypy.html#mapping-file-paths-to-modules for more info calculator/__init__.py: note: Common resolutions include: a) using `--exclude` to avoid checking one of them, b) adding `__init__.py` somewhere, c) using `--explicit-package-bases` or adjusting MYPYPATH Found 1 error in 1 file (errors prevented further checking) ci/update_pyproject_version.py: error: Duplicate module named "update_pyproject_version" (also at "ci/update_pyproject_version.py") ci/update_pyproject_version.py: note: See https://mypy.readthedocs.io/en/stable/running_mypy.html#mapping-file-paths-to-modules for more info ci/update_pyproject_version.py: note: Common resolutions include: a) using `--exclude` to avoid checking one of them, b) adding `__init__.py` somewhere, c) using `--explicit-package-bases` or adjusting MYPYPATH Found 1 error in 1 file (errors prevented further checking) Update pyproject.toml version............................................Passed
.pre-commit-config.yaml抜粋
補足
各種静的解析ツールはpoetryでローカルに追加したものを使用します。
主な理由はpyproject.tomlでバージョン管理しているためです。
- repo: local hooks: - id: mypy name: mypy stages: [commit] language: system entry: poetry run mypy ci tests calculator types: [python]
pyproject.toml抜粋
[tool.mypy] python_version = "3.10" strict = true warn_return_any = false ignore_missing_imports = true scripts_are_modules = true
ツリー構成
trial-test$ tree -L 2
.
├── LICENSE
├── README.md
├── calculator
│ ├── __init__.py
│ ├── __pycache__
│ └── operations.py
├── ci
│ ├── run_git_tag_base_pyproject.py
│ └── update_pyproject_version.py
├── poetry.lock
├── pyproject.toml
├── requirements.txt
└── tests
├── __init__.py
├── __pycache__
└── test_operations.py
calculator/__init__.py と ci/update_pyproject_version.py の両方に重複したモジュールが存在するというエラーメッセージが表示されているという指摘ですが__init.py__は空であり、重複したモジュールはありませんでした。また、poetryでの実行では指摘はありませんでした。
$ poetry run mypy ci tests calculator Success: no issues found in 6 source files
解決方法
理解できていないのですが、pyproject.tomlの[tool.mypy]にfilesを指定するとエラーは発生せずにPassedしました。
.pre-commit-config.yaml抜粋
- id: mypy name: mypy stages: [commit] language: system entry: poetry run mypy types: [python]
pyproject.toml抜粋
[tool.mypy] files = ["calculator","tests","ci"] #ファイル指定を追加 python_version = "3.10" strict = true warn_return_any = false ignore_missing_imports = true scripts_are_modules = true
その他
.git/hooks/pre-commitによる確認
.git/hooks/pre-commitにmypyを記入して実行したところ、エラーにはなりませんでした。
.git/hooks/pre-commit
#!/usr/bin/env bash
# File generated by pre-commit: https://pre-commit.com
# ID: ここは伏せます。
# start templated
INSTALL_PYTHON=$HOME/develop/git/trial-test/.venv/bin/python
ARGS=(hook-impl --config=.pre-commit-config.yaml --hook-type=pre-commit)
# end templated
source $HOME/develop/git/trial-test/.venv/bin/activate
poetry run mypy ci tests calculator
printf ".git/hooks/pre-commit end\n"
HERE="$(cd "$(dirname "$0")" && pwd)"
ARGS+=(--hook-dir "$HERE" -- "$@")
if [ -x "$INSTALL_PYTHON" ]; then
exec "$INSTALL_PYTHON" -mpre_commit "${ARGS[@]}"
elif command -v pre-commit > /dev/null; then
exec pre-commit "${ARGS[@]}"
else
echo '`pre-commit` not found. Did you forget to activate your virtualenv?' 1>&2
exit 1
fi
実行結果
$ .git/hooks/pre-commit Success: no issues found in 6 source files .git/hooks/pre-commit end # ↑.git/hooks/pre-commitが表示されエラーはなく正常終了していることがわかります。 trim trailing whitespace.................................................Passed fix end of files.........................................................Passed mixed line ending........................................................Passed check toml...............................................................Passed check yaml...............................................................Passed poetry-check.............................................................Passed poetry-lock..............................................................Passed poetry-export........................................(no files to check)Skipped isort....................................................................Passed black....................................................................Passed flake8...................................................................Passed mypy.....................................................................Passed # ↑ここはentry: poetry run mypyの指定です。 Update pyproject.toml version............................................Passed
まとめ
pre-commit-config.yaml + poetry + mypy環境でエラーと解決方法を紹介しました。 .git/hooks/pre-commitではエラーになっていないので、もしかすると、pre-commit、またはmypy側のバグの可能性もあるかと思います。
また、mirrors-mypyでは確認していないのでこちらではエラーにならないかもしれません。 もし、同様のエラーが発生した場合は、ファイルの指定か、フォルダ構成を見直したほうが良いかもしれません。
参考記事
以下の記事を参考にさせていただきました。
以上です。