如何为Python项目中所有相关文件应用MonkeyType生成的存根?
项目背景
项目名为projectname,目录结构如下:
projectname/ |-- src/ | |-- projectname/__main__.py | |-- projectname/some_folder/some_script.py |-- tests/ | |-- projectname/test_something.py | |-- projectname/another_folder/test_another_thing.py | |-- setup.py |-- README.md
主代码执行命令:
python -m src.projectname
测试执行命令:
python -m pytest
已尝试的操作及问题
尝试一
执行monkeytype run src/projectname/__main__.py生成了monkeytype.sqlite3,但后续执行以下命令均报错:
monkeytype stub src.projectname.__main__.py monkeytype apply src.projectname.__main__.py # 或 monkeytype stub src.projectname.__main__ monkeytype apply src.projectname.__main__
错误信息:
No traces found for module src.projectname.__main__ No traces found for module src.projectname.__main__.py
执行monkeytype apply src.projectname时也提示:
No traces found for module src.projectname
尝试二
尝试多种monkeytype run命令格式均报错,且无法确定正确的项目模块名:
monkeytype run src/projectname/some_folder/some_script.py monkeytype run src.projectname.some_folder.some_script.py monkeytype run src.projectname.some_folder.some_script monkeytype run some_script.py monkeytype run some_script
尝试三
考虑创建额外文件调用__main__.py,但担心会收集main的轨迹导致后续混淆。
解决方案
1. 先确保项目可被正确导入
在项目根目录执行开发模式安装,让Python能直接识别projectname模块:
pip install -e .
这一步会把src目录加入Python的模块搜索路径,后续可以直接用projectname作为模块名,无需带src前缀。
2. 正确运行MonkeyType追踪代码
用模块方式启动MonkeyType,这样它会正确追踪projectname下所有被调用的代码:
# 追踪主程序运行 monkeytype run -m projectname # 如果需要追踪测试中的代码执行 monkeytype run -m pytest
3. 查看已追踪的模块
确认MonkeyType已经收集到项目模块的轨迹:
monkeytype list-modules
输出应该包含projectname、projectname.some_folder.some_script等子模块。
4. 应用类型提示到所有模块
- 直接将类型提示写入原代码文件:
monkeytype apply projectname
这会自动修改projectname包下所有被追踪过的.py文件,添加类型提示。
- 生成存根文件(
.pyi)而不修改原代码:
monkeytype stub projectname > projectname.pyi # 或按子模块单独生成 monkeytype stub projectname.some_folder.some_script > src/projectname/some_folder/some_script.pyi
关键说明
之前失败的核心原因是:MonkeyType追踪的是Python导入时的模块名(即projectname),而不是文件路径(src.projectname)。通过开发模式安装后,模块名变为projectname,MonkeyType就能正确匹配轨迹和模块。
内容的提问来源于stack exchange,提问作者a.t.

