You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Pytest中mock sys.version_info触发MagicMock转换报错如何解决

问题根源

你遇到的报错本质是默认生成的MagicMock对象没有实现sys.version_info的核心行为:sys.version_info是namedtuple类型的实例,既支持下标索引访问、也支持直接和元组做大小比较、还支持major/minor属性访问,默认的MagicMock没有实现这些逻辑,所以会触发类型错误。

解决方案

不需要用默认的MagicMock实例,直接在patch的时候通过new参数传入你需要模拟的版本值即可,分两种场景处理:


场景1:你的版本判断只用了下标访问或者直接和元组比较

如果代码里是sys.version_info < (3,7)或者sys.version_info[0]/sys.version_info[1],直接传入普通元组即可:

def test_bad_python_version(capsys) -> None:
    import sys
    import mock
    import pytest
    from quendor.__main__ import main

    # 直接将version_info替换为代表3.5版本的元组
    with mock.patch.object(sys, "version_info", new=(3, 5)):
        # 捕获低版本触发的SystemExit异常
        with pytest.raises(SystemExit) as pytest_wrapped_e:
            main()
        # 可选校验退出码为1
        assert pytest_wrapped_e.value.code == 1

    terminal_text = capsys.readouterr()
    assert "Quendor requires Python 3.7 or later" in terminal_text.err

场景2:你的版本判断用到了major/minor属性访问

如果代码里有sys.version_info.major/sys.version_info.minor的写法,普通元组没有对应的属性,传入符合version_info结构的namedtuple即可:

from collections import namedtuple
# 构造和sys.version_info结构一致的namedtuple
VersionInfo = namedtuple('VersionInfo', ['major', 'minor', 'micro', 'releaselevel', 'serial'])

def test_bad_python_version(capsys) -> None:
    import sys
    import mock
    import pytest
    from quendor.__main__ import main

    # 模拟3.5版本的version_info对象
    mock_version = VersionInfo(3, 5, 0, 'final', 0)
    with mock.patch.object(sys, "version_info", new=mock_version):
        with pytest.raises(SystemExit):
            main()

    terminal_text = capsys.readouterr()
    assert "Quendor requires Python 3.7 or later" in terminal_text.err

补充说明

你之前mockplatform.python_version用return_value是因为python_version是可调用的方法,而sys.version_info是属性,不需要return_value参数,直接用new指定替换值即可。

内容的提问来源于stack exchange,提问作者Jeff Nyman

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.02 22:36:00