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

如何通过pytest与__instancecheck__修复datetime.now补丁后的isinstance校验问题

问题解决:Mock datetime.now后isinstance校验失败

问题场景

在使用pytest测试Python项目时:

  • 代码中用到了datetime.datetime类、datetime.datetime.now()函数
  • 存在isinstance(time, datetime.datetime)的校验逻辑,其中time是未被Mock的真实DateTime对象
  • 补丁now()函数后,isinstance(time, datetime.datetime)返回False,打印type(time)显示为:
    <class 'test_Itinerarios.patch_datetime_now.<locals>.mydatetime'>
    

要求通过pytest与__instancecheck__实现正确校验,且不能引入其他测试库。

解决方案

问题核心:替换datetime.datetime为自定义子类mydatetime后,真实DateTime实例并非mydatetime的实例,导致isinstance校验失败。需通过**元类重写__instancecheck__**修正校验逻辑,具体代码如下:

import datetime
import pytest

Fake_time = datetime.datetime(2024, 3, 7, 18, 00)
real_datetime_class = datetime.datetime
# 获取datetime.datetime的原始元类
real_datetime_meta = type(datetime.datetime)

@pytest.fixture
def patch_datetime_now(monkeypatch):
    # 自定义元类,重写__instancecheck__
    class MyDateTimeMeta(real_datetime_meta):
        def __instancecheck__(cls, obj):
            # 同时识别原始datetime实例和自定义mydatetime实例
            return isinstance(obj, real_datetime_class) or super().__instancecheck__(obj)

    class mydatetime(datetime.datetime, metaclass=MyDateTimeMeta):
        @classmethod
        def now(cls):
            return Fake_time

    monkeypatch.setattr(datetime, 'datetime', mydatetime)

原理说明

  1. __instancecheck__是元类的方法,负责处理isinstance(obj, cls)的校验逻辑
  2. 自定义元类MyDateTimeMeta继承自datetime.datetime的原始元类,重写__instancecheck__后,既会检查对象是否是原始datetime.datetime的实例,也保留了子类实例的正常校验逻辑
  3. 无论time是原始DateTime对象还是Mock后的mydatetime对象,isinstance(time, datetime.datetime)都会返回True

内容的提问来源于stack exchange,提问作者Daniel Baquero

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.28 12:25:09