pytest-cov 默认扫描 sortedcontainers 等第三方库,是因为 coverage.py 默认追踪所有已导入模块;要仅统计自身代码,必须显式配置 source(如 source = ["src"])作为白名单,路径须与项目结构严格一致,且优先级高于 omit。

为什么 pytest-cov 默认会扫到 sortedcontainers 这类第三方库?
因为 coverage.py 的默认行为是「追踪所有被导入的模块」,不管它装在 /usr/lib/python3/dist-packages/ 还是 venv/lib/python3.x/site-packages/。只要你测试里 import 了用到 sortedlist 的代码(比如 from sortedcontainers import SortedList),它就被纳入统计——哪怕你根本没写任何针对它的测试。
怎么只统计自己写的代码?必须靠 source 配置
不能指望 --cov=myproject 自动排除第三方;它只是指定“从哪个包开始找”,但不阻止 coverage 扫描已加载的其他包。真正起作用的是 source 参数,它是白名单机制:
-
coverage run --source=src/ -m pytest:只统计src/下的 .py 文件 - 在
pyproject.toml里写:[tool.coverage.run] source = ["src"]
- 在
.coveragerc里写:[run] source = src
source 优先级高于 omit,哪怕你写了 omit = */site-packages/*,只要第三方模块被 source 漏掉、又被 import 过,它仍可能混进来。
快速生成专业的 Python 脚本和应用代码。一键创建完整项目结构,支持CLI、API、爬虫、Bot、Django等多种项目类型,包含完整的项目结构、配置文件、依赖管理、测试、README和文档。
常见配置陷阱:路径写错或结构不匹配
项目结构和 source 值必须严格一致:
- 如果你的代码在
src/myapp/,source = ["src"]是对的;但source = ["myapp"]就无效——因为myapp不在 Python 路径根目录下 - 用
setup.py或pyproject.toml声明了packages = ["myapp"],那source = ["myapp"]才有效,前提是myapp/在当前工作目录或PYTHONPATH中 - 运行命令时工作目录不是项目根目录,
source = .就会失效——它指向的是你 cd 进去的那个目录
HTML 报告里看到第三方文件,说明 source 没生效
这不是工具 bug,而是配置未命中。检查三件事:
- 运行命令是否用了
pytest而不是python -m pytest?后者会干扰sys.path,导致source匹配失败 -
htmlcov/目录下打开报告,点进那个第三方文件,看顶部路径是否真属于你本地项目(比如/home/user/myproj/src/...);如果是/venv/lib/...,说明source完全没拦住 - 有没有多个配置文件冲突?比如
.coveragerc和pyproject.toml同时存在,coverage.py 默认只读.coveragerc,除非显式指定--config=pyproject.toml
最稳妥的做法:删掉所有配置文件,先跑一次 coverage run --source=src/ -m pytest && coverage report,确认输出里只有你的源码文件,再逐步加回过滤规则。
Python免费学习笔记(深入):立即使用
在学习笔记中,你将探索 Python 的核心概念和高级技巧!










