使用__future__.annotations的模块运行pytest doctest报compile flags错误
差异原因
- Ubuntu 20.04官方软件源提供的Python 3.8版本经过发行方补丁修改:为了提前适配更高版本的注解特性,发行方修改了
__future__.annotations对应的编译flag值,从官方原版Python 3.8的1048576(即220)改为了`16777216`(即224)。 - 你直接映射了宿主机Ubuntu 18.04环境下生成的
.venv目录到容器内,虚拟环境中缓存的模块导入逻辑适配的是宿主机原版Python的flag规则,和容器内打了补丁的Python解释器不匹配:doctest收集到的flag值是容器内补丁版的2^24,但实际编译执行时解释器的底层逻辑并没有完整兼容这个自定义flag,因此抛出compile(): unrecognised flags错误。 - 你对比标准库文件没有差异是因为补丁修改的是Python解释器的底层实现,而非
__future__.py这类公开的标准库文本文件。
解决方案
- 方案1:更换Docker基础镜像为官方Python镜像,例如
python:3.8.0-slim,该镜像使用无自定义补丁的官方Python版本,和你宿主机的Python行为完全一致,不会出现flag不匹配问题。 - 方案2:如果必须使用
ubuntu:20.04作为基础镜像,不要直接映射宿主机的.venv目录到容器内,在容器构建阶段单独执行依赖安装命令,生成适配容器内Python版本的虚拟环境。 - 方案3:临时规避:在项目根目录的
conftest.py中添加钩子修改doctest的编译参数,清除无效flag位,示例代码如下:
import pytest from _pytest.doctest import DoctestItem @pytest.hookimpl(tryfirst=True) def pytest_runtest_call(item): if isinstance(item, DoctestItem): # 清除无效的2^24位flag item.dtest.compileflags = item.dtest.compileflags & ~16777216 | 1048576
内容的提问来源于stack exchange,提问作者frans
相关产品推荐
相关产品推荐

