[英]Does python's `unittest.mock.patch` mutate global state?
我試圖確定Python的mock.patch
(Py3中的unittest.mock.patch
)上下文管理器是否會改變全局狀態,即它是否是線程安全的。
例如:讓我們假設一個線程在函數foo
使用上下文管理器修補函數bar
,然后在上下文管理器中,解釋器暫停該線程(因為GIL等)並恢復另一個線程,該線程在所述上下文管理器之外運行foo
。 如果patch
是線程安全的,我會期望函數foo
和bar
的全局狀態是未修改的,因此第二個線程將獲得foo
的正常行為。 但是如果patch
修改了全局狀態,第二個線程將獲得foo
的修改行為,即使它不在上下文管理器中。
我提到了源代碼,但僅通過查看它就無法清楚地說出來。
mock.patch
上不是線程安全的或不是線程安全的。 它修改了一個對象。 它只不過是一開始的賦值語句,最后是一個撤消賦值語句。
如果被修補的對象被多個線程訪問,那么所有線程都將看到更改。 通常,它用於修改模塊的屬性,這些屬性是全局狀態。 以這種方式使用時,它不是線程安全的。
我繼續使用Python 3.4上的multiprocessing.dummy.Pool
進行粗略的實驗。 實驗使用線程池映射了一個針對range(100)輸入的函數,如果函數的輸入正好是10,它修補了一個內部函數來調用time.sleep()。 如果補丁是線程安全的,結果將立即顯示,除了10的結果,這將顯示為晚; 如果它不是線程安全的,那么會立即顯示一些結果,而其他許多結果會顯示得很晚。
結果表明unittest.mock.patch
確實改變了全局狀態 。 很高興知道!
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.