The Python datamodel documents a hook, __getattr__
, which shall be called when attribute access fails to resolve in the usual ways. Mocks use it to return a new mock instance - i.e. mocks define unknown attributes as factories.
Reproducing mock's implementation in a simpler way, you would just turn __getattr__
and __call__
into factory functions:
class M:
def __call__(self):
return M()
def __getattr__(self, name):
return M()
Example usage:
>>> mock = M()
>>> mock.potato
<__main__.M at 0xdeadbeef>
>>> mock.potato()
<__main__.M at 0xcafef00d>
How is MagicMock able to do this?
This part is not specific to MagicMock
, an ordinary Mock
will do the same (the "magic" in the name is just referring to additional features allowing better mocking of magic methods). MagicMock
inherits such behavior from one of the base classes:
>>> MagicMock.mro()
[unittest.mock.MagicMock,
unittest.mock.MagicMixin,
unittest.mock.Mock,
unittest.mock.CallableMixin,
unittest.mock.NonCallableMock, # <--- this one overrides __getattr__!
unittest.mock.Base,
object]
How can I create a class that can perform an action when any method (which might not be defined) is called on it?
It depends if you want to be in front of, or behind, a normal attribute access. If you want to get in front, you should define __getattribute__
, it's called unconditionally to implement attribute accesses before searching the class/instance namespaces. However, if you want to take a lower precedence to normal attributes (i.e. those living in the object __dict__
) and to descriptors, then you should define __getattr__
as previously discussed.