python'`unittest.mock.patch`是否会改变全局状态?

时间:2014-11-11 23:18:03

标签: python multithreading python-mock global-state

我试图确定Python的mock.patch(Py3中的unittest.mock.patch)上下文管理器是否会改变全局状态,即它是否是线程安全的。

例如:让我们假设一个线程在函数bar中使用上下文管理器修补函数foo,然后在上下文管理器中,解释器暂停该线程(因为GIL等) 。)并恢复另一个线程,该线程在所述上下文管理器之外运行foo。如果patch是线程安全的,我会期望函数foobar的全局状态未被修改,因此第二个线程将获得foo的正常行为。但是如果patch修改了全局状态,则第二个线程将获得foo的修改行为,即使它不在上下文管理器中。

我提到了源代码,但仅仅通过查看它就无法清楚地说明。

2 个答案:

答案 0 :(得分:6)

mock.patch本质上不是线程安全的,也不是线程安全的。它修改了一个对象。它只不过是一开始的赋值语句,最后是一个撤消赋值语句。

如果被修补的对象被多个线程访问,那么所有线程都将看到更改。通常,它用于修改模块的属性,这些属性是全局状态。以这种方式使用时,它不是线程安全的。

答案 1 :(得分:4)

我继续在Python 3.4上使用multiprocessing.dummy.Pool进行粗略的实验。实验使用线程池映射了一个针对range(100)输入的函数,如果函数的输入正好是10,它修补了一个内部函数来调用time.sleep()。如果补丁是线程安全的,结果将立即显示,除了10的结果,这将显示为晚;如果它不是线程安全的,那么会立即显示一些结果,而其他许多结果会显示得很晚。

结果表明unittest.mock.patch 确实会改变全局状态。很高兴知道!