Skip to main content

Lib/unittest/mock.py

cpython 3.14 @ ab2d84fe1023/Lib/unittest/mock.py

unittest.mock is a pure-Python module that ships with CPython and provides configurable mock objects, a rich assertion API, and a family of patch helpers for temporarily replacing names in a module's namespace during tests.

The class hierarchy flows from NonCallableMock (attributes, spec enforcement, recording) through Mock (adds __call__) to MagicMock (adds magic method stubs). An independent branch handles async code: AsyncMockMixin and AsyncMock produce awaitables when called. patch and its variants are thin wrappers around _patch, which manages the save/restore lifecycle as both a decorator and a context manager.

Map

LinesSymbolRolegopy
1-100Module prologue, _all_magics, _non_defaults, _return_valuesSentinel values (DEFAULT, _missing), the set of all special method names that MagicMock stubs, and the mapping of magic names to sensible default return values.(stdlib pending)
100-400CallableMixin, NonCallableMockBase recording machinery: _mock_children dict (auto-child creation on __getattr__), _mock_calls list, configure_mock, reset_mock, attach_mock, assert_called_*.(stdlib pending)
400-600Mock, MagicMixin, MagicMock, NonCallableMagicMockMock adds __call__ that records to call_args and returns return_value. MagicMixin installs stubs for all magic methods. MagicMock combines both.(stdlib pending)
600-800_MockIter, _CallList, call, _Call_Call is a tuple subclass that compares equal to any call with the same args; _CallList uses it to implement assert_has_calls with optional any_order.(stdlib pending)
800-1100_patch, patch, patch.object, patch.dict, patch.multiple_patch stores the target object, attribute name, and new value; __enter__ replaces and __exit__ restores; decorate_callable wraps a function so entry/exit bracket each call.(stdlib pending)
1100-1400patch specialisations: patch.stopall, start/stop, _patch_dictpatch.dict saves a copy of the target mapping and restores on exit; patch.multiple creates a _patch per keyword argument; _patches registry enables stopall.(stdlib pending)
1400-1800assert_called_*, assert_any_call, assert_has_calls, call_args_listThe full assertion surface: assert_called_once_with, assert_any_call (scans call_args_list), assert_has_calls (subsequence or ordered match).(stdlib pending)
1800-2200create_autospec, _check_signature, SpecStateRecursively builds a MagicMock that mirrors the signature of the real object; uses inspect.signature to enforce argument counts on __call__.(stdlib pending)
2200-2700AsyncMockMixin, AsyncMock, _AwaitEventAsyncMock.__call__ returns a coroutine; assert_awaited_* mirrors the sync assertion API; _AwaitEvent records each await for later inspection.(stdlib pending)
2700-3200sentinel, ANY, PropertyMock, ThreadingMixin, _MockItersentinel manufactures unique attribute objects on demand; ANY compares equal to everything; PropertyMock is a MagicMock that also acts as a data descriptor.(stdlib pending)

Reading

NonCallableMock.__getattr__ auto-child creation (lines 100 to 400)

cpython 3.14 @ ab2d84fe1023/Lib/unittest/mock.py#L100-400

class NonCallableMock(Base):
def __getattr__(self, name):
if name in {'_mock_methods', '_mock_unsafe'}:
raise AttributeError(name)
elif self._mock_methods is not None:
if name not in self._mock_methods or name.startswith('_'):
raise AttributeError("Mock object has no attribute %r" % name)
elif _all_magics(name):
raise AttributeError(name)
if not self._mock_unsafe and (not self._mock_methods or
name not in self._mock_methods):
if name.startswith(('assert', 'assret', 'asert', 'aseert', 'assrt')):
raise AttributeError(
f"{name!r} is not a supported mock method."
)
result = self._mock_children[name]
if result is _deleted:
raise AttributeError(name)
elif result is None:
wraps = None
if self._mock_wraps is not None:
wraps = getattr(self._mock_wraps, name)
return self._get_child_mock(
parent=self, name=name, wraps=wraps, _new_name=name,
_new_parent=self
)
return result

Every attribute access on a NonCallableMock that hits __getattr__ either raises (if the spec prohibits it, or if the name looks like a misspelled assert_*) or auto-creates a child mock stored in self._mock_children[name]. Child mocks carry back-references (_new_parent, _new_name) used to build the dotted call path recorded in _mock_calls.

The guard against assert prefixes catches common typos such as mock.assert_called() (note: no parentheses on the wrong name). Previously these silently passed because __getattr__ returned a new child mock that was always truthy.

patch() decorator and context manager (lines 800 to 1100)

cpython 3.14 @ ab2d84fe1023/Lib/unittest/mock.py#L800-1100

class _patch:
def __enter__(self):
...
original, local = self.get_original()
if self.new is DEFAULT:
new = self.new_callable()
...
self.temp_original = original
self.is_local = local
setattr(self.getter(), self.attribute, new)
...
return new

def __exit__(self, *exc_info):
...
if self.is_local and self.temp_original is not DEFAULT:
setattr(self.getter(), self.attribute, self.temp_original)
elif not self.is_local:
delattr(self.getter(), self.attribute)
...

patch(target) splits the dotted target string into a module path and an attribute name, imports the module, and stores both in a _patch instance. get_original() looks up the current value via getattr and flags whether the attribute was defined locally on the object or inherited. On exit, __exit__ restores local attributes with setattr and removes temporarily injected attributes with delattr, preserving the exact pre-patch state.

As a decorator, decorate_callable wraps the test function so that __enter__ runs before the function and __exit__ runs after, with the new mock passed as an extra positional argument.

MagicMixin magic method table (lines 400 to 600)

cpython 3.14 @ ab2d84fe1023/Lib/unittest/mock.py#L400-600

_return_values = {
'__lt__': NotImplemented,
'__gt__': NotImplemented,
'__le__': NotImplemented,
'__ge__': NotImplemented,
'__int__': 1,
'__contains__': False,
'__len__': 0,
'__iter__': iter([]),
'__exit__': False,
'__complex__': 1j,
'__float__': 1.0,
'__bool__': True,
'__index__': 1,
}

class MagicMixin(Base):
def __init__(self, /, *args, **kw):
self._mock_set_magics()

def _mock_set_magics(self):
these_magics = self._mock_methods or magic_methods
remove_magics = set()
remove_magics = magic_methods - these_magics
for magic in these_magics:
klass = type(self)
current = klass.__dict__.get(magic)
if current is _get_method(magic, type(self)):
# Magics already set up.
continue
setattr(klass, magic, _get_method(magic, klass))
for magic in remove_magics:
if magic in type(self).__dict__:
delattr(type(self), magic)

Magic methods in Python are looked up on the type, not the instance. To support len(mock), mock + x, mock[key], and with mock:, MagicMixin installs stub methods directly on a per-instance subclass created by _MockIter. Each stub records the call like any other mock call and returns the value from _return_values (or a new child mock for methods not listed). The __iter__ default returns iter([]) so for x in mock: terminates immediately without raising.

gopy mirror

unittest.mock has no C accelerator and no FFI surface. The entire module is pure Python. A gopy port requires a working inspect.signature, functools.wraps, and the weakref machinery (used internally by NonCallableMock to clean up child mock references). The patch family also needs a functioning import system (importlib.import_module) to resolve dotted target strings.

The async surface (AsyncMock, _AwaitEvent) depends on the coroutine and asyncio event loop infrastructure and should be deferred until after the sync mock layer is complete.