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

排查Python unittest/mock中Responses模块引发的间歇性AttributeError问题

排查Python多线程环境下Responses模拟请求时的AttributeError: '_patch' object has no attribute 'is_local'问题

问题根源

这个间歇性异常是多线程环境下Responses与unittest.mock的线程安全冲突导致的:

  • @responses.activate装饰器默认使用全局共享的mock patch实例,当多个线程同时调用被装饰的send_request方法时,会导致unittest.mock的_patch对象状态混乱。
  • unittest.mock的_patch对象本身不是线程安全的,跨线程共享时会出现属性访问异常(比如找不到is_local属性)。

解决方案

1. 启用Responses的线程隔离模式

给@responses.activate装饰器添加threaded=True参数,让每个线程拥有独立的Responses mock实例,避免跨线程状态干扰:

from responses import activate

class Device_Sim(Device):
    @activate(threaded=True)
    def send_request(self, target='query', data=None):
        # 添加你的模拟响应逻辑
        responses.add(
            responses.POST,
            "http://your-device-api-url",
            json={"result": "success"},
            status=200
        )
        return super().send_request(target=target, data=data)

2. 改用上下文管理器隔离mock环境

放弃装饰器,在每个send_request调用内部使用responses.RequestsMock()上下文管理器,确保每个请求都在独立的mock环境中执行:

import responses

class Device_Sim(Device):
    def send_request(self, target='query', data=None):
        with responses.RequestsMock() as rsps:
            rsps.add(
                responses.POST,
                "http://your-device-api-url",
                json={"result": "success"},
                status=200
            )
            return super().send_request(target=target, data=data)

3. 升级Responses到最新稳定版

你的当前版本是v0.23.3,后续发布的v0.24.x及以上版本可能修复了多线程下的patch对象冲突问题,执行升级命令:

pip install --upgrade responses

验证步骤

  1. 优先尝试添加threaded=True参数,观察是否还会出现间歇性异常;
  2. 若问题依旧,切换为上下文管理器的实现方式;
  3. 检查代码中是否存在其他共享Responses mock实例的逻辑,确保模拟逻辑完全隔离在单个请求的生命周期内。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.11 11:48:25