Python 3 中未为信号处理程序调用 MagicMock
MagicMock not called for signal handler in Python 3
我正在将一些代码和相关测试从 python 2 迁移到 python 3(特别是 2.7 到 3.7),我遇到了我想要的这种奇怪的行为了解:
try:
from unittest import mock # python 3
except ImportError:
import mock # python 2
import os
import signal
def do_signal(mock_type):
def side_effect(signum, frame):
print('Called for ' + mock_type.__name__)
handler = mock_type(side_effect=side_effect)
signal.signal(signal.SIGTERM, handler)
os.kill(os.getpid(), signal.SIGTERM)
print(handler.call_count)
do_signal(mock.Mock)
do_signal(mock.MagicMock)
这里我使用了一个mock.Mock
或mock.MagicMock
作为信号处理程序,并且在向当前进程发送信号后打印出mock被调用的次数。
在 python 2.7 中打印出:
Called for Mock
1
Called for MagicMock
1
但是对于 python3.7,它打印出:
Called for Mock
1
0
对于 python 3,似乎根本没有调用 MagicMock。颠倒 do_signal
调用的顺序不会改变这一点。
Mock
和 MagicMock
之间的哪些行为差异可以解释这一点,为什么行为会从 python 2 变为 3?我知道 mock
在 python 3 中作为 unittest.mock
添加到标准库中,所以我很好奇那里是否发生了某些变化。
在python 3中,为信号添加了枚举
例如,您可以调用:
signal.signal(signal.SIGINT, signal.SIG_IGN)
signal.signal
尝试做的第一件事是通过调用 int(...)
将句柄从枚举转换为整数
因为MagicMock
支持所有的魔法方法,它也支持__int__
如果你偷看神奇的方法调用,你可以看到这一点:
# ...
try:
print(handler.__int__.call_count)
except AttributeError:
print('__int__ not called')
因为 MagicMock 有 __int__
:
>>> mock.MagicMock().__int__()
1
将 SIGTERM
处理程序重新分配给信号 1(SIGHUP
在我的平台上)
我正在将一些代码和相关测试从 python 2 迁移到 python 3(特别是 2.7 到 3.7),我遇到了我想要的这种奇怪的行为了解:
try:
from unittest import mock # python 3
except ImportError:
import mock # python 2
import os
import signal
def do_signal(mock_type):
def side_effect(signum, frame):
print('Called for ' + mock_type.__name__)
handler = mock_type(side_effect=side_effect)
signal.signal(signal.SIGTERM, handler)
os.kill(os.getpid(), signal.SIGTERM)
print(handler.call_count)
do_signal(mock.Mock)
do_signal(mock.MagicMock)
这里我使用了一个mock.Mock
或mock.MagicMock
作为信号处理程序,并且在向当前进程发送信号后打印出mock被调用的次数。
在 python 2.7 中打印出:
Called for Mock
1
Called for MagicMock
1
但是对于 python3.7,它打印出:
Called for Mock
1
0
对于 python 3,似乎根本没有调用 MagicMock。颠倒 do_signal
调用的顺序不会改变这一点。
Mock
和 MagicMock
之间的哪些行为差异可以解释这一点,为什么行为会从 python 2 变为 3?我知道 mock
在 python 3 中作为 unittest.mock
添加到标准库中,所以我很好奇那里是否发生了某些变化。
在python 3中,为信号添加了枚举
例如,您可以调用:
signal.signal(signal.SIGINT, signal.SIG_IGN)
signal.signal
尝试做的第一件事是通过调用 int(...)
因为MagicMock
支持所有的魔法方法,它也支持__int__
如果你偷看神奇的方法调用,你可以看到这一点:
# ...
try:
print(handler.__int__.call_count)
except AttributeError:
print('__int__ not called')
因为 MagicMock 有 __int__
:
>>> mock.MagicMock().__int__()
1
将 SIGTERM
处理程序重新分配给信号 1(SIGHUP
在我的平台上)