【Python】pytestで同じディレクトリのモジュールをimportして、"ModuleNotFoundError: No module named"を出さなくする
367 語
2 分
【Python】pytestで同じディレクトリのモジュールをimportして、"ModuleNotFoundError: No module named"を出さなくする
はじまり

リサちゃん
あー、`ModuleNotFoundError: No module named`だぁぁー!!

135ml
importするときによく出るやつか。これがめんどいよな。
今回のディレクトリ構成
今回、紹介するimport方法におけるディレクトリ構成は、以下になっています。
├── src│ └── landmasterlibrarylocal│ ├── file_list_getter.py│ ├── input_controller.py├── test│ ├── __init__.py│ ├── test_file_list_getter.py│ ├── test_input_controller.py失敗するパターン
上記のディレクトリ構成の場合に、__init__.pyとfile_list_getter.pyのコードがこんな状態だったとします。__init__.pyには何も記述しません。
__init__.py:
# Nothingfile_list_getter.py:
# Library by defaultimport os, sys, platformimport time# Library by third partyimport glob2# Library by landmasterlibraryfrom input_controller import repeat_input_with_multi_choices
# ・・・以下略・・・この状態では、普通に.pyファイルを実行する分には問題ないのですが、pytestを実行すると以下のエラーが出ます。
実行:
pytest出力:
====================================================================================================== ERRORS =======================================================================================================__________________________________________________________________________________ ERROR collecting test/test_file_list_getter.py ___________________________________________________________________________________ImportError while importing test module '/Users/landmaster/Downloads/landmasterlibrarylocal/test/test_file_list_getter.py'.Hint: make sure your test modules/packages have valid Python names.Traceback:../../opt/anaconda3/lib/python3.9/importlib/__init__.py:127: in import_module return _bootstrap._gcd_import(name[level:], package, level)test/test_file_list_getter.py:5: in <module> from src.landmasterlibrarylocal.file_list_getter import *src/landmasterlibrarylocal/file_list_getter.py:10: in <module> from input_controller import repeat_input_with_multi_choicesE ModuleNotFoundError: No module named 'input_controller'成功するパターン
この"ModuleNotFoundError: No module named"が起きないようにするために、以下のように__init__.pyで記述します。
こうすることで、'../src/landmasterlibrarylocal'がモジュールの参照先に追加されます。
__init__.py:
import osimport syssys.path.append((os.path.join(os.path.dirname(__file__), '../src/landmasterlibrarylocal')))そうすると、以下のように、”ModuleNotFoundError: No module named”が起きなくなりました。
出力:
================================================================================================ test session starts ================================================================================================platform darwin -- Python 3.9.7, pytest-7.1.1, pluggy-0.13.1rootdir: /Users/landmaster/Downloads/landmasterlibrarylocalplugins: freezegun-0.4.2, anyio-2.2.0, mock-3.7.0, cov-3.0.0collected 1 item
test/test_input_controller.py . [100%]
================================================================================================= 1 passed in 1.73s =================================================================================================おしまい

リサちゃん
やったあ〜、`ModuleNotFoundError: No module named`が起きなくなったあ〜。

135ml
困った時、解決法の一つとして検討してみてください。
以上になります!
記事を共有
この記事が役に立ったなら、ぜひ他の人と共有してください!
【Python】pytestで同じディレクトリのモジュールをimportして、"ModuleNotFoundError: No module named"を出さなくする
https://endorphinbath.com/posts/python-pytest-importing-same-dir-modules/ 関連記事 スマート
1
【Python】複数の区切り文字を指定して文字列を配列に分割する
Code Pythonで文字列を配列に分割するスクリプトを掲載します。分割文字は配列で指定するように作っています。
2
【Python】inputを使った処理をpytestでunittestしたい(monkeypatchでmockする)
Code Pythonスクリプトをpytestする時に、input()のようなビルトイン関数が入っている時にmockする方法を紹介します。monkeypatchを使用します。
3
【Python】1つのファイル内における関数の依存関係をMermaidの書式で出力する
Code 1つのファイル内のクラス図の依存関係を描画するために、MarkdownのMermaid書式で出力するPythonスクリプトを作りました。
4
【Python】cronを生成するモジュールを作った
Code Pythonでcron時間を生成するモジュールを作りました。タイムゾーンを引数にして生成できます。
5
【Python】Pydanticのvalidatorが非推奨だからfield_validatorを使って2段階バリデーションを実装する
Code @validatorはdeprecatedになってるし、@field_validatorにはpreとかalwaysフラグが無いから、from pydantic.functional_validators import field_validatorでインポートしたfield_validatorを使用する方法と、BeforeValidatorとAfterValidatorをAnnotateの中に入れる実装方法を試した。
ランダム記事 ランダム