如何针对多Python版本测试待上传至PyPI的Wheel包?
我正在开发一个纯Python库,计划将sdist(.tar.gz)和Wheel包上传至PyPI。根据build文档,执行python -m build可以从源码生成sdist,再基于该sdist生成Wheel包,这样能顺带完成sdist的测试。现在我希望在多个Python版本下,用pytest对这个Wheel包进行测试,请问最简单的实现方式是什么?
我之前一直在用tox,注意到可以设置package = wheel配置:
[testenv] description = run the tests with pytest package = wheel wheel_build_env = .pkg
但这个配置没说明Wheel包的生成方式,我不确定它属于哪种情况:
- a) 直接从源码生成Wheel包;
- b) 和
python -m build完全一致,先从源码生成sdist,再基于sdist生成Wheel包; - c) 从源码生成sdist,但用和
python -m build不同的方式生成Wheel包。
哪怕是c的情况,tox测试的Wheel包也和我要上传的不一致,没法完成正确测试。我觉得可能需要把Wheel包作为参数传入tox或测试运行器。
我的核心需求是:从源码生成sdist,再基于该sdist生成Wheel包,然后在多个Python版本下对这个同一Wheel包运行单元测试。因为是纯Python项目,每个版本对应同一个Wheel包。请问针对待上传至PyPI的同一Wheel包,进行测试的惯用方法是什么?能用tox实现吗?
惯用实现方案:预构建统一Wheel包,再用tox测试
针对你的需求,最稳妥的方式是先在本地用python -m build生成和待上传完全一致的sdist与Wheel包,再让tox直接使用这个预构建好的Wheel包进行多版本测试,确保测试的就是你要上传的那个文件。
具体步骤
预构建统一的sdist和Wheel包
执行标准build命令生成包,这一步和你上传PyPI前的操作完全一致:python -m build执行后,包文件会生成在
dist/目录下,比如your-package-1.0.0.tar.gz和your_package-1.0.0-py3-none-any.whl(纯Python项目的Wheel是跨版本的py3-none-any类型)。配置tox直接使用预构建的Wheel包
修改tox.ini,让testenv跳过自构建流程,直接安装本地预生成的Wheel:[tox] envlist = py38, py39, py310, py311 # 替换为你需要测试的Python版本 skipsdist = true # 禁止tox自行构建sdist require = tox>=4.0 # 确保tox版本支持相关配置 [testenv] description = 用pytest测试预构建的Wheel包 deps = pytest # 声明测试依赖 commands = pytest tests/ # 执行测试命令 install_command = pip install --no-index --find-links=dist/ your-package # 从本地dist目录安装预构建的Wheelskipsdist = true:告诉tox不要自行构建包,完全使用你预先生成的文件。install_command:指定pip从本地dist/目录安装包,优先选择预构建的Wheel,而非重新编译。
关于你之前的tox配置疑问
你提到的package = wheel配置,tox的实际行为是直接从源码构建Wheel包(对应你说的选项a),不会先生成sdist再基于sdist构建Wheel,这和python -m build的流程不一致,所以测试的Wheel和你要上传的不是同一个文件,这也是推荐预构建后再测试的核心原因。
可选验证步骤
如果想确认tox安装的是正确的Wheel包,可以在testenv中添加验证命令:
[testenv] # ... 其他配置 ... commands = pip show your-package # 查看安装的包信息,确认是目标Wheel pytest tests/
内容的提问来源于stack exchange,提问作者Niko Fohr

