I was in the middle of migrating some code and associated tests from python 2 to python 3 (specifically 2.7 to 3.7) and I came across this weird behavior that I'd like to understand:
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)
Here I use a mock.Mock
or mock.MagicMock
as a signal handler, and I print out the number of times the mock was called after sending the signal to the current process.
In python 2.7 this prints out:
Called for Mock
1
Called for MagicMock
1
But for python3.7 it prints out:
Called for Mock
1
0
For python 3 the MagicMock doesn't seem to be called at all. Reversing the order of the do_signal
calls doesn't change this.
What behavior differences between Mock
and MagicMock
could explain this, and why would the behavior change from python 2 to 3? I know that mock
was added to the standard library in python 3 as unittest.mock
, so I'm curious whether something changed there.