Pytest运行报ModuleNotFoundError,删除__init__.py后正常是什么原因?
pytest 模块导入异常底层原理
核心触发逻辑
该现象是Python导入规则和pytest默认sys.path处理逻辑共同作用的结果,具体分两种场景拆解:
场景1:api目录存在__init__.py时导入失败
- 存在
__init__.py的目录会被Python识别为正规的命名空间包,此时你在src目录执行pytest,pytest默认仅会将**执行命令的工作目录(也就是src目录)**加入sys.path。 - 当你在test_app.py中导入app模块时,app的全限定名为
api.app,Python会按绝对导入规则解析app.py内的导入语句:from document import Document会被判定为寻找顶层document模块,去sys.path中的src目录下查找document.py,找不到就抛出ModuleNotFoundError。
场景2:删除api目录下__init__.py后导入正常
- 删除
__init__.py后,api目录不再被识别为Python包,仅作为普通文件目录处理。 - pytest处理普通目录下的测试文件时,会自动将测试文件所在的上级目录(也就是
src/api)加入sys.path,此时app.py内的from document import Document可以直接在sys.path中的src/api目录下找到对应文件,因此运行正常。
兼容解决方案
如果需要保留api目录的__init__.py,可任选一种方式修复:
- 将app.py内的导入改为相对导入:
from .document import Document - 执行pytest时改用
python -m pytest命令,该命令会自动将当前工作目录的模块查找规则适配为包导入模式 - 在pytest配置文件(pytest.ini/pyproject.toml)中添加pythonpath配置,将
src/api加入模块查找路径
内容的提问来源于stack exchange,提问作者erni
相关产品推荐
相关产品推荐

