排查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
验证步骤
- 优先尝试添加
threaded=True参数,观察是否还会出现间歇性异常; - 若问题依旧,切换为上下文管理器的实现方式;
- 检查代码中是否存在其他共享Responses mock实例的逻辑,确保模拟逻辑完全隔离在单个请求的生命周期内。
内容的提问来源于stack exchange,提问作者DaveWalker
相关产品推荐
相关产品推荐

