pytest_mock.plugin

  1import builtins
  2import functools
  3import inspect
  4import itertools
  5import unittest.mock
  6import warnings
  7from collections.abc import Generator
  8from collections.abc import Iterable
  9from collections.abc import Iterator
 10from collections.abc import Mapping
 11from dataclasses import dataclass
 12from dataclasses import field
 13from typing import Any
 14from typing import Callable
 15from typing import Optional
 16from typing import TypeVar
 17from typing import Union
 18from typing import cast
 19from typing import overload
 20
 21import pytest
 22
 23from ._util import get_mock_module
 24from ._util import parse_ini_boolean
 25
 26_T = TypeVar("_T")
 27
 28AsyncMockType = unittest.mock.AsyncMock
 29MockType = Union[
 30    unittest.mock.MagicMock,
 31    unittest.mock.AsyncMock,
 32    unittest.mock.NonCallableMagicMock,
 33]
 34
 35
 36class PytestMockWarning(UserWarning):
 37    """Base class for all warnings emitted by pytest-mock."""
 38
 39
 40@dataclass
 41class MockCacheItem:
 42    mock: MockType
 43    patch: Optional[Any] = None
 44
 45
 46@dataclass
 47class MockCache:
 48    """
 49    Cache MagicMock and Patcher instances so we can undo them later.
 50    """
 51
 52    cache: list[MockCacheItem] = field(default_factory=list)
 53
 54    def _find(self, mock: MockType) -> MockCacheItem:
 55        for mock_item in self.cache:
 56            if mock_item.mock is mock:
 57                return mock_item
 58        raise ValueError("This mock object is not registered")
 59
 60    def add(self, mock: MockType, **kwargs: Any) -> MockCacheItem:
 61        self.cache.append(MockCacheItem(mock=mock, **kwargs))
 62        return self.cache[-1]
 63
 64    def remove(self, mock: MockType) -> None:
 65        mock_item = self._find(mock)
 66        if mock_item.patch:
 67            mock_item.patch.stop()
 68        self.cache.remove(mock_item)
 69
 70    def clear(self) -> None:
 71        for mock_item in reversed(self.cache):
 72            if mock_item.patch is not None:
 73                mock_item.patch.stop()
 74        self.cache.clear()
 75
 76    def __iter__(self) -> Iterator[MockCacheItem]:
 77        return iter(self.cache)
 78
 79
 80class MockerFixture:
 81    """
 82    Fixture that provides the same interface to functions in the mock module,
 83    ensuring that they are uninstalled at the end of each test.
 84    """
 85
 86    def __init__(self, config: Any) -> None:
 87        self._mock_cache: MockCache = MockCache()
 88        self.mock_module = mock_module = get_mock_module(config)
 89        self.patch = self._Patcher(self._mock_cache, mock_module)  # type: MockerFixture._Patcher
 90        # aliases for convenience
 91        self.Mock = mock_module.Mock
 92        self.MagicMock = mock_module.MagicMock
 93        self.NonCallableMock = mock_module.NonCallableMock
 94        self.NonCallableMagicMock = mock_module.NonCallableMagicMock
 95        self.PropertyMock = mock_module.PropertyMock
 96        if hasattr(mock_module, "AsyncMock"):
 97            self.AsyncMock = mock_module.AsyncMock
 98        self.call = mock_module.call
 99        self.ANY = mock_module.ANY
100        self.DEFAULT = mock_module.DEFAULT
101        self.sentinel = mock_module.sentinel
102        self.mock_open = mock_module.mock_open
103        if hasattr(mock_module, "seal"):
104            self.seal = mock_module.seal
105
106    def create_autospec(
107        self, spec: Any, spec_set: bool = False, instance: bool = False, **kwargs: Any
108    ) -> MockType:
109        m: MockType = self.mock_module.create_autospec(
110            spec, spec_set, instance, **kwargs
111        )
112        self._mock_cache.add(m)
113        return m
114
115    def resetall(
116        self, *, return_value: bool = False, side_effect: bool = False
117    ) -> None:
118        """
119        Call reset_mock() on all patchers started by this fixture.
120
121        :param bool return_value: Reset the return_value of mocks.
122        :param bool side_effect: Reset the side_effect of mocks.
123        """
124        supports_reset_mock_with_args: tuple[type[Any], ...]
125        if hasattr(self, "AsyncMock"):
126            supports_reset_mock_with_args = (self.Mock, self.AsyncMock)
127        else:
128            supports_reset_mock_with_args = (self.Mock,)
129
130        for mock_item in self._mock_cache:
131            # See issue #237.
132            if not hasattr(mock_item.mock, "reset_mock"):
133                continue
134            # NOTE: The mock may be a dictionary
135            if hasattr(mock_item.mock, "spy_return_list"):
136                mock_item.mock.spy_return_list = []
137            if hasattr(mock_item.mock, "spy_return_iter"):
138                mock_item.mock.spy_return_iter = None
139            if isinstance(mock_item.mock, supports_reset_mock_with_args):
140                mock_item.mock.reset_mock(
141                    return_value=return_value, side_effect=side_effect
142                )
143            else:
144                mock_item.mock.reset_mock()
145
146    def stopall(self) -> None:
147        """
148        Stop all patchers started by this fixture. Can be safely called multiple
149        times.
150        """
151        self._mock_cache.clear()
152
153    def stop(self, mock: unittest.mock.MagicMock) -> None:
154        """
155        Stops a previous patch or spy call by passing the ``MagicMock`` object
156        returned by it.
157        """
158        self._mock_cache.remove(mock)
159
160    def spy(
161        self, obj: object, name: str, duplicate_iterators: bool = False
162    ) -> MockType:
163        """
164        Create a spy of method. It will run method normally, but it is now
165        possible to use `mock` call features with it, like call count.
166
167        :param obj: An object.
168        :param name: A method in object.
169        :param duplicate_iterators: Whether to keep a copy of the returned iterator in `spy_return_iter`.
170        :return: Spy object.
171        """
172        method = getattr(obj, name)
173
174        def wrapper(*args, **kwargs):
175            spy_obj.spy_return = None
176            spy_obj.spy_exception = None
177            try:
178                r = method(*args, **kwargs)
179            except BaseException as e:
180                spy_obj.spy_exception = e
181                raise
182            else:
183                if duplicate_iterators and isinstance(r, Iterator):
184                    r, duplicated_iterator = itertools.tee(r, 2)
185                    spy_obj.spy_return_iter = duplicated_iterator
186                else:
187                    spy_obj.spy_return_iter = None
188
189                spy_obj.spy_return = r
190                spy_obj.spy_return_list.append(r)
191            return r
192
193        async def async_wrapper(*args, **kwargs):
194            spy_obj.spy_return = None
195            spy_obj.spy_exception = None
196            try:
197                r = await method(*args, **kwargs)
198            except BaseException as e:
199                spy_obj.spy_exception = e
200                raise
201            else:
202                spy_obj.spy_return = r
203                spy_obj.spy_return_list.append(r)
204            return r
205
206        if inspect.iscoroutinefunction(method):
207            wrapped = functools.update_wrapper(async_wrapper, method)
208        else:
209            wrapped = functools.update_wrapper(wrapper, method)
210
211        autospec = inspect.ismethod(method) or inspect.isfunction(method)
212
213        spy_obj = self.patch.object(obj, name, side_effect=wrapped, autospec=autospec)
214        spy_obj.spy_return = None
215        spy_obj.spy_return_iter = None
216        spy_obj.spy_return_list = []
217        spy_obj.spy_exception = None
218        return spy_obj
219
220    def stub(self, name: Optional[str] = None) -> unittest.mock.MagicMock:
221        """
222        Create a stub method. It accepts any arguments. Ideal to register to
223        callbacks in tests.
224
225        :param name: the constructed stub's name as used in repr
226        :return: Stub object.
227        """
228        return cast(
229            unittest.mock.MagicMock,
230            self.mock_module.MagicMock(spec=lambda *args, **kwargs: None, name=name),
231        )
232
233    def async_stub(self, name: Optional[str] = None) -> AsyncMockType:
234        """
235        Create a async stub method. It accepts any arguments. Ideal to register to
236        callbacks in tests.
237
238        :param name: the constructed stub's name as used in repr
239        :return: Stub object.
240        """
241        return cast(
242            AsyncMockType,
243            self.mock_module.AsyncMock(spec=lambda *args, **kwargs: None, name=name),
244        )
245
246    class _Patcher:
247        """
248        Object to provide the same interface as mock.patch, mock.patch.object,
249        etc. We need this indirection to keep the same API of the mock package.
250        """
251
252        DEFAULT = object()
253
254        def __init__(self, mock_cache, mock_module):
255            self.__mock_cache = mock_cache
256            self.mock_module = mock_module
257
258        def _start_patch(
259            self, mock_func: Any, warn_on_mock_enter: bool, *args: Any, **kwargs: Any
260        ) -> MockType:
261            """Patches something by calling the given function from the mock
262            module, registering the patch to stop it later and returns the
263            mock object resulting from the mock call.
264            """
265            p = mock_func(*args, **kwargs)
266            mocked: MockType = p.start()
267            self.__mock_cache.add(mock=mocked, patch=p)
268            if hasattr(mocked, "reset_mock"):
269                # check if `mocked` is actually a mock object, as depending on autospec or target
270                # parameters `mocked` can be anything
271                if hasattr(mocked, "__enter__") and warn_on_mock_enter:
272                    mocked.__enter__.side_effect = lambda: warnings.warn(
273                        "Mocks returned by pytest-mock do not need to be used as context managers. "
274                        "The mocker fixture automatically undoes mocking at the end of a test. "
275                        "This warning can be ignored if it was triggered by mocking a context manager. "
276                        "https://pytest-mock.readthedocs.io/en/latest/usage.html#usage-as-context-manager",
277                        PytestMockWarning,
278                        stacklevel=5,
279                    )
280            return mocked
281
282        def object(
283            self,
284            target: object,
285            attribute: str,
286            new: object = DEFAULT,
287            spec: Optional[object] = None,
288            create: bool = False,
289            spec_set: Optional[object] = None,
290            autospec: Optional[object] = None,
291            new_callable: object = None,
292            **kwargs: Any,
293        ) -> MockType:
294            """API to mock.patch.object"""
295            if new is self.DEFAULT:
296                new = self.mock_module.DEFAULT
297            return self._start_patch(
298                self.mock_module.patch.object,
299                True,
300                target,
301                attribute,
302                new=new,
303                spec=spec,
304                create=create,
305                spec_set=spec_set,
306                autospec=autospec,
307                new_callable=new_callable,
308                **kwargs,
309            )
310
311        def context_manager(
312            self,
313            target: builtins.object,
314            attribute: str,
315            new: builtins.object = DEFAULT,
316            spec: Optional[builtins.object] = None,
317            create: bool = False,
318            spec_set: Optional[builtins.object] = None,
319            autospec: Optional[builtins.object] = None,
320            new_callable: builtins.object = None,
321            **kwargs: Any,
322        ) -> MockType:
323            """This is equivalent to mock.patch.object except that the returned mock
324            does not issue a warning when used as a context manager."""
325            if new is self.DEFAULT:
326                new = self.mock_module.DEFAULT
327            return self._start_patch(
328                self.mock_module.patch.object,
329                False,
330                target,
331                attribute,
332                new=new,
333                spec=spec,
334                create=create,
335                spec_set=spec_set,
336                autospec=autospec,
337                new_callable=new_callable,
338                **kwargs,
339            )
340
341        def multiple(
342            self,
343            target: builtins.object,
344            spec: Optional[builtins.object] = None,
345            create: bool = False,
346            spec_set: Optional[builtins.object] = None,
347            autospec: Optional[builtins.object] = None,
348            new_callable: Optional[builtins.object] = None,
349            **kwargs: Any,
350        ) -> dict[str, MockType]:
351            """API to mock.patch.multiple"""
352            return self._start_patch(
353                self.mock_module.patch.multiple,
354                True,
355                target,
356                spec=spec,
357                create=create,
358                spec_set=spec_set,
359                autospec=autospec,
360                new_callable=new_callable,
361                **kwargs,
362            )
363
364        def dict(
365            self,
366            in_dict: Union[Mapping[Any, Any], str],
367            values: Union[Mapping[Any, Any], Iterable[tuple[Any, Any]]] = (),
368            clear: bool = False,
369            **kwargs: Any,
370        ) -> Any:
371            """API to mock.patch.dict"""
372            return self._start_patch(
373                self.mock_module.patch.dict,
374                True,
375                in_dict,
376                values=values,
377                clear=clear,
378                **kwargs,
379            )
380
381        @overload
382        def __call__(
383            self,
384            target: str,
385            new: None = ...,
386            spec: Optional[builtins.object] = ...,
387            create: bool = ...,
388            spec_set: Optional[builtins.object] = ...,
389            autospec: Optional[builtins.object] = ...,
390            new_callable: None = ...,
391            **kwargs: Any,
392        ) -> MockType: ...
393
394        @overload
395        def __call__(
396            self,
397            target: str,
398            new: _T,
399            spec: Optional[builtins.object] = ...,
400            create: bool = ...,
401            spec_set: Optional[builtins.object] = ...,
402            autospec: Optional[builtins.object] = ...,
403            new_callable: None = ...,
404            **kwargs: Any,
405        ) -> _T: ...
406
407        @overload
408        def __call__(
409            self,
410            target: str,
411            new: None,
412            spec: Optional[builtins.object],
413            create: bool,
414            spec_set: Optional[builtins.object],
415            autospec: Optional[builtins.object],
416            new_callable: Callable[[], _T],
417            **kwargs: Any,
418        ) -> _T: ...
419
420        @overload
421        def __call__(
422            self,
423            target: str,
424            new: None = ...,
425            spec: Optional[builtins.object] = ...,
426            create: bool = ...,
427            spec_set: Optional[builtins.object] = ...,
428            autospec: Optional[builtins.object] = ...,
429            *,
430            new_callable: Callable[[], _T],
431            **kwargs: Any,
432        ) -> _T: ...
433
434        def __call__(
435            self,
436            target: str,
437            new: builtins.object = DEFAULT,
438            spec: Optional[builtins.object] = None,
439            create: bool = False,
440            spec_set: Optional[builtins.object] = None,
441            autospec: Optional[builtins.object] = None,
442            new_callable: Optional[Callable[[], Any]] = None,
443            **kwargs: Any,
444        ) -> Any:
445            """API to mock.patch"""
446            if new is self.DEFAULT:
447                new = self.mock_module.DEFAULT
448            return self._start_patch(
449                self.mock_module.patch,
450                True,
451                target,
452                new=new,
453                spec=spec,
454                create=create,
455                spec_set=spec_set,
456                autospec=autospec,
457                new_callable=new_callable,
458                **kwargs,
459            )
460
461
462def _mocker(pytestconfig: Any) -> Generator[MockerFixture, None, None]:
463    """
464    Return an object that has the same interface to the `mock` module, but
465    takes care of automatically undoing all patches after each test method.
466    """
467    result = MockerFixture(pytestconfig)
468    yield result
469    result.stopall()
470
471
472mocker = pytest.fixture()(_mocker)  # default scope is function
473class_mocker = pytest.fixture(scope="class")(_mocker)
474module_mocker = pytest.fixture(scope="module")(_mocker)
475package_mocker = pytest.fixture(scope="package")(_mocker)
476session_mocker = pytest.fixture(scope="session")(_mocker)
477
478
479_mock_module_patches: list[Any] = []
480_mock_module_originals: dict[str, Any] = {}
481
482
483def assert_wrapper(
484    __wrapped_mock_method__: Callable[..., Any], *args: Any, **kwargs: Any
485) -> None:
486    __tracebackhide__ = True
487    try:
488        __wrapped_mock_method__(*args, **kwargs)
489        return
490    except AssertionError as e:
491        if getattr(e, "_mock_introspection_applied", 0):
492            msg = str(e)
493        else:
494            __mock_self = args[0]
495            msg = str(e)
496            if __mock_self.call_args is not None:
497                actual_args, actual_kwargs = __mock_self.call_args
498                introspection = ""
499                try:
500                    assert actual_args == args[1:]
501                except AssertionError as e_args:
502                    introspection += "\nArgs:\n" + str(e_args)
503                try:
504                    assert actual_kwargs == kwargs
505                except AssertionError as e_kwargs:
506                    introspection += "\nKwargs:\n" + str(e_kwargs)
507                if introspection:
508                    msg += "\n\npytest introspection follows:\n" + introspection
509        e = AssertionError(msg)
510        e._mock_introspection_applied = True  # type:ignore[attr-defined]
511        raise e
512
513
514def assert_has_calls_wrapper(
515    __wrapped_mock_method__: Callable[..., Any], *args: Any, **kwargs: Any
516) -> None:
517    __tracebackhide__ = True
518    try:
519        __wrapped_mock_method__(*args, **kwargs)
520        return
521    except AssertionError as e:
522        any_order = kwargs.get("any_order", False)
523        if getattr(e, "_mock_introspection_applied", 0) or any_order:
524            msg = str(e)
525        else:
526            __mock_self = args[0]
527            msg = str(e)
528            if __mock_self.call_args_list is not None:
529                actual_calls = list(__mock_self.call_args_list)
530                expect_calls = args[1]
531                introspection = ""
532                from itertools import zip_longest
533
534                for actual_call, expect_call in zip_longest(actual_calls, expect_calls):
535                    if actual_call is not None:
536                        actual_args, actual_kwargs = actual_call
537                    else:
538                        actual_args = tuple()
539                        actual_kwargs = {}
540
541                    if expect_call is not None:
542                        _, expect_args, expect_kwargs = expect_call
543                    else:
544                        expect_args = tuple()
545                        expect_kwargs = {}
546
547                    try:
548                        assert actual_args == expect_args
549                    except AssertionError as e_args:
550                        introspection += "\nArgs:\n" + str(e_args)
551                    try:
552                        assert actual_kwargs == expect_kwargs
553                    except AssertionError as e_kwargs:
554                        introspection += "\nKwargs:\n" + str(e_kwargs)
555                if introspection:
556                    msg += "\n\npytest introspection follows:\n" + introspection
557        e = AssertionError(msg)
558        e._mock_introspection_applied = True  # type:ignore[attr-defined]
559        raise e
560
561
562def wrap_assert_not_called(*args: Any, **kwargs: Any) -> None:
563    __tracebackhide__ = True
564    assert_wrapper(_mock_module_originals["assert_not_called"], *args, **kwargs)
565
566
567def wrap_assert_called_with(*args: Any, **kwargs: Any) -> None:
568    __tracebackhide__ = True
569    assert_wrapper(_mock_module_originals["assert_called_with"], *args, **kwargs)
570
571
572def wrap_assert_called_once(*args: Any, **kwargs: Any) -> None:
573    __tracebackhide__ = True
574    assert_wrapper(_mock_module_originals["assert_called_once"], *args, **kwargs)
575
576
577def wrap_assert_called_once_with(*args: Any, **kwargs: Any) -> None:
578    __tracebackhide__ = True
579    assert_wrapper(_mock_module_originals["assert_called_once_with"], *args, **kwargs)
580
581
582def wrap_assert_has_calls(*args: Any, **kwargs: Any) -> None:
583    __tracebackhide__ = True
584    assert_has_calls_wrapper(
585        _mock_module_originals["assert_has_calls"], *args, **kwargs
586    )
587
588
589def wrap_assert_any_call(*args: Any, **kwargs: Any) -> None:
590    __tracebackhide__ = True
591    assert_wrapper(_mock_module_originals["assert_any_call"], *args, **kwargs)
592
593
594def wrap_assert_called(*args: Any, **kwargs: Any) -> None:
595    __tracebackhide__ = True
596    assert_wrapper(_mock_module_originals["assert_called"], *args, **kwargs)
597
598
599def wrap_assert_not_awaited(*args: Any, **kwargs: Any) -> None:
600    __tracebackhide__ = True
601    assert_wrapper(_mock_module_originals["assert_not_awaited"], *args, **kwargs)
602
603
604def wrap_assert_awaited_with(*args: Any, **kwargs: Any) -> None:
605    __tracebackhide__ = True
606    assert_wrapper(_mock_module_originals["assert_awaited_with"], *args, **kwargs)
607
608
609def wrap_assert_awaited_once(*args: Any, **kwargs: Any) -> None:
610    __tracebackhide__ = True
611    assert_wrapper(_mock_module_originals["assert_awaited_once"], *args, **kwargs)
612
613
614def wrap_assert_awaited_once_with(*args: Any, **kwargs: Any) -> None:
615    __tracebackhide__ = True
616    assert_wrapper(_mock_module_originals["assert_awaited_once_with"], *args, **kwargs)
617
618
619def wrap_assert_has_awaits(*args: Any, **kwargs: Any) -> None:
620    __tracebackhide__ = True
621    assert_wrapper(_mock_module_originals["assert_has_awaits"], *args, **kwargs)
622
623
624def wrap_assert_any_await(*args: Any, **kwargs: Any) -> None:
625    __tracebackhide__ = True
626    assert_wrapper(_mock_module_originals["assert_any_await"], *args, **kwargs)
627
628
629def wrap_assert_awaited(*args: Any, **kwargs: Any) -> None:
630    __tracebackhide__ = True
631    assert_wrapper(_mock_module_originals["assert_awaited"], *args, **kwargs)
632
633
634def wrap_assert_methods(config: Any) -> None:
635    """
636    Wrap assert methods of mock module so we can hide their traceback and
637    add introspection information to specified argument asserts.
638    """
639    # Make sure we only do this once
640    if _mock_module_originals:
641        return
642
643    mock_module = get_mock_module(config)
644
645    wrappers = {
646        "assert_called": wrap_assert_called,
647        "assert_called_once": wrap_assert_called_once,
648        "assert_called_with": wrap_assert_called_with,
649        "assert_called_once_with": wrap_assert_called_once_with,
650        "assert_any_call": wrap_assert_any_call,
651        "assert_has_calls": wrap_assert_has_calls,
652        "assert_not_called": wrap_assert_not_called,
653    }
654    for method, wrapper in wrappers.items():
655        try:
656            original = getattr(mock_module.NonCallableMock, method)
657        except AttributeError:  # pragma: no cover
658            continue
659        _mock_module_originals[method] = original
660        patcher = mock_module.patch.object(mock_module.NonCallableMock, method, wrapper)
661        patcher.start()
662        _mock_module_patches.append(patcher)
663
664    if hasattr(mock_module, "AsyncMock"):
665        async_wrappers = {
666            "assert_awaited": wrap_assert_awaited,
667            "assert_awaited_once": wrap_assert_awaited_once,
668            "assert_awaited_with": wrap_assert_awaited_with,
669            "assert_awaited_once_with": wrap_assert_awaited_once_with,
670            "assert_any_await": wrap_assert_any_await,
671            "assert_has_awaits": wrap_assert_has_awaits,
672            "assert_not_awaited": wrap_assert_not_awaited,
673        }
674        for method, wrapper in async_wrappers.items():
675            try:
676                original = getattr(mock_module.AsyncMock, method)
677            except AttributeError:  # pragma: no cover
678                continue
679            _mock_module_originals[method] = original
680            patcher = mock_module.patch.object(mock_module.AsyncMock, method, wrapper)
681            patcher.start()
682            _mock_module_patches.append(patcher)
683
684    config.add_cleanup(unwrap_assert_methods)
685
686
687def unwrap_assert_methods() -> None:
688    for patcher in _mock_module_patches:
689        try:
690            patcher.stop()
691        except RuntimeError as e:
692            # a patcher might have been stopped by user code (#137)
693            # so we need to catch this error here and ignore it;
694            # unfortunately there's no public API to check if a patch
695            # has been started, so catching the error it is
696            if str(e) == "stop called on unstarted patcher":
697                pass
698            else:
699                raise
700    _mock_module_patches[:] = []
701    _mock_module_originals.clear()
702
703
704def pytest_addoption(parser: Any) -> None:
705    parser.addini(
706        "mock_traceback_monkeypatch",
707        "Monkeypatch the mock library to improve reporting of the "
708        "assert_called_... methods",
709        default=True,
710    )
711    parser.addini(
712        "mock_use_standalone_module",
713        'Use standalone "mock" (from PyPI) instead of builtin "unittest.mock" '
714        "on Python 3",
715        default=False,
716    )
717
718
719def pytest_configure(config: Any) -> None:
720    tb = config.getoption("--tb", default="auto")
721    if (
722        parse_ini_boolean(config.getini("mock_traceback_monkeypatch"))
723        and tb != "native"
724    ):
725        wrap_assert_methods(config)
AsyncMockType = <class 'unittest.mock.AsyncMock'>
MockType = typing.Union[unittest.mock.MagicMock, unittest.mock.AsyncMock, unittest.mock.NonCallableMagicMock]
class PytestMockWarning(builtins.UserWarning):
37class PytestMockWarning(UserWarning):
38    """Base class for all warnings emitted by pytest-mock."""

Base class for all warnings emitted by pytest-mock.

@dataclass
class MockCacheItem:
41@dataclass
42class MockCacheItem:
43    mock: MockType
44    patch: Optional[Any] = None
MockCacheItem( mock: Union[unittest.mock.MagicMock, unittest.mock.AsyncMock, unittest.mock.NonCallableMagicMock], patch: Optional[Any] = None)
mock: Union[unittest.mock.MagicMock, unittest.mock.AsyncMock, unittest.mock.NonCallableMagicMock]
patch: Optional[Any] = None
@dataclass
class MockCache:
47@dataclass
48class MockCache:
49    """
50    Cache MagicMock and Patcher instances so we can undo them later.
51    """
52
53    cache: list[MockCacheItem] = field(default_factory=list)
54
55    def _find(self, mock: MockType) -> MockCacheItem:
56        for mock_item in self.cache:
57            if mock_item.mock is mock:
58                return mock_item
59        raise ValueError("This mock object is not registered")
60
61    def add(self, mock: MockType, **kwargs: Any) -> MockCacheItem:
62        self.cache.append(MockCacheItem(mock=mock, **kwargs))
63        return self.cache[-1]
64
65    def remove(self, mock: MockType) -> None:
66        mock_item = self._find(mock)
67        if mock_item.patch:
68            mock_item.patch.stop()
69        self.cache.remove(mock_item)
70
71    def clear(self) -> None:
72        for mock_item in reversed(self.cache):
73            if mock_item.patch is not None:
74                mock_item.patch.stop()
75        self.cache.clear()
76
77    def __iter__(self) -> Iterator[MockCacheItem]:
78        return iter(self.cache)

Cache MagicMock and Patcher instances so we can undo them later.

MockCache(cache: list[MockCacheItem] = <factory>)
cache: list[MockCacheItem]
def add( self, mock: Union[unittest.mock.MagicMock, unittest.mock.AsyncMock, unittest.mock.NonCallableMagicMock], **kwargs: Any) -> MockCacheItem:
61    def add(self, mock: MockType, **kwargs: Any) -> MockCacheItem:
62        self.cache.append(MockCacheItem(mock=mock, **kwargs))
63        return self.cache[-1]
def remove( self, mock: Union[unittest.mock.MagicMock, unittest.mock.AsyncMock, unittest.mock.NonCallableMagicMock]) -> None:
65    def remove(self, mock: MockType) -> None:
66        mock_item = self._find(mock)
67        if mock_item.patch:
68            mock_item.patch.stop()
69        self.cache.remove(mock_item)
def clear(self) -> None:
71    def clear(self) -> None:
72        for mock_item in reversed(self.cache):
73            if mock_item.patch is not None:
74                mock_item.patch.stop()
75        self.cache.clear()
class MockerFixture:
 81class MockerFixture:
 82    """
 83    Fixture that provides the same interface to functions in the mock module,
 84    ensuring that they are uninstalled at the end of each test.
 85    """
 86
 87    def __init__(self, config: Any) -> None:
 88        self._mock_cache: MockCache = MockCache()
 89        self.mock_module = mock_module = get_mock_module(config)
 90        self.patch = self._Patcher(self._mock_cache, mock_module)  # type: MockerFixture._Patcher
 91        # aliases for convenience
 92        self.Mock = mock_module.Mock
 93        self.MagicMock = mock_module.MagicMock
 94        self.NonCallableMock = mock_module.NonCallableMock
 95        self.NonCallableMagicMock = mock_module.NonCallableMagicMock
 96        self.PropertyMock = mock_module.PropertyMock
 97        if hasattr(mock_module, "AsyncMock"):
 98            self.AsyncMock = mock_module.AsyncMock
 99        self.call = mock_module.call
100        self.ANY = mock_module.ANY
101        self.DEFAULT = mock_module.DEFAULT
102        self.sentinel = mock_module.sentinel
103        self.mock_open = mock_module.mock_open
104        if hasattr(mock_module, "seal"):
105            self.seal = mock_module.seal
106
107    def create_autospec(
108        self, spec: Any, spec_set: bool = False, instance: bool = False, **kwargs: Any
109    ) -> MockType:
110        m: MockType = self.mock_module.create_autospec(
111            spec, spec_set, instance, **kwargs
112        )
113        self._mock_cache.add(m)
114        return m
115
116    def resetall(
117        self, *, return_value: bool = False, side_effect: bool = False
118    ) -> None:
119        """
120        Call reset_mock() on all patchers started by this fixture.
121
122        :param bool return_value: Reset the return_value of mocks.
123        :param bool side_effect: Reset the side_effect of mocks.
124        """
125        supports_reset_mock_with_args: tuple[type[Any], ...]
126        if hasattr(self, "AsyncMock"):
127            supports_reset_mock_with_args = (self.Mock, self.AsyncMock)
128        else:
129            supports_reset_mock_with_args = (self.Mock,)
130
131        for mock_item in self._mock_cache:
132            # See issue #237.
133            if not hasattr(mock_item.mock, "reset_mock"):
134                continue
135            # NOTE: The mock may be a dictionary
136            if hasattr(mock_item.mock, "spy_return_list"):
137                mock_item.mock.spy_return_list = []
138            if hasattr(mock_item.mock, "spy_return_iter"):
139                mock_item.mock.spy_return_iter = None
140            if isinstance(mock_item.mock, supports_reset_mock_with_args):
141                mock_item.mock.reset_mock(
142                    return_value=return_value, side_effect=side_effect
143                )
144            else:
145                mock_item.mock.reset_mock()
146
147    def stopall(self) -> None:
148        """
149        Stop all patchers started by this fixture. Can be safely called multiple
150        times.
151        """
152        self._mock_cache.clear()
153
154    def stop(self, mock: unittest.mock.MagicMock) -> None:
155        """
156        Stops a previous patch or spy call by passing the ``MagicMock`` object
157        returned by it.
158        """
159        self._mock_cache.remove(mock)
160
161    def spy(
162        self, obj: object, name: str, duplicate_iterators: bool = False
163    ) -> MockType:
164        """
165        Create a spy of method. It will run method normally, but it is now
166        possible to use `mock` call features with it, like call count.
167
168        :param obj: An object.
169        :param name: A method in object.
170        :param duplicate_iterators: Whether to keep a copy of the returned iterator in `spy_return_iter`.
171        :return: Spy object.
172        """
173        method = getattr(obj, name)
174
175        def wrapper(*args, **kwargs):
176            spy_obj.spy_return = None
177            spy_obj.spy_exception = None
178            try:
179                r = method(*args, **kwargs)
180            except BaseException as e:
181                spy_obj.spy_exception = e
182                raise
183            else:
184                if duplicate_iterators and isinstance(r, Iterator):
185                    r, duplicated_iterator = itertools.tee(r, 2)
186                    spy_obj.spy_return_iter = duplicated_iterator
187                else:
188                    spy_obj.spy_return_iter = None
189
190                spy_obj.spy_return = r
191                spy_obj.spy_return_list.append(r)
192            return r
193
194        async def async_wrapper(*args, **kwargs):
195            spy_obj.spy_return = None
196            spy_obj.spy_exception = None
197            try:
198                r = await method(*args, **kwargs)
199            except BaseException as e:
200                spy_obj.spy_exception = e
201                raise
202            else:
203                spy_obj.spy_return = r
204                spy_obj.spy_return_list.append(r)
205            return r
206
207        if inspect.iscoroutinefunction(method):
208            wrapped = functools.update_wrapper(async_wrapper, method)
209        else:
210            wrapped = functools.update_wrapper(wrapper, method)
211
212        autospec = inspect.ismethod(method) or inspect.isfunction(method)
213
214        spy_obj = self.patch.object(obj, name, side_effect=wrapped, autospec=autospec)
215        spy_obj.spy_return = None
216        spy_obj.spy_return_iter = None
217        spy_obj.spy_return_list = []
218        spy_obj.spy_exception = None
219        return spy_obj
220
221    def stub(self, name: Optional[str] = None) -> unittest.mock.MagicMock:
222        """
223        Create a stub method. It accepts any arguments. Ideal to register to
224        callbacks in tests.
225
226        :param name: the constructed stub's name as used in repr
227        :return: Stub object.
228        """
229        return cast(
230            unittest.mock.MagicMock,
231            self.mock_module.MagicMock(spec=lambda *args, **kwargs: None, name=name),
232        )
233
234    def async_stub(self, name: Optional[str] = None) -> AsyncMockType:
235        """
236        Create a async stub method. It accepts any arguments. Ideal to register to
237        callbacks in tests.
238
239        :param name: the constructed stub's name as used in repr
240        :return: Stub object.
241        """
242        return cast(
243            AsyncMockType,
244            self.mock_module.AsyncMock(spec=lambda *args, **kwargs: None, name=name),
245        )
246
247    class _Patcher:
248        """
249        Object to provide the same interface as mock.patch, mock.patch.object,
250        etc. We need this indirection to keep the same API of the mock package.
251        """
252
253        DEFAULT = object()
254
255        def __init__(self, mock_cache, mock_module):
256            self.__mock_cache = mock_cache
257            self.mock_module = mock_module
258
259        def _start_patch(
260            self, mock_func: Any, warn_on_mock_enter: bool, *args: Any, **kwargs: Any
261        ) -> MockType:
262            """Patches something by calling the given function from the mock
263            module, registering the patch to stop it later and returns the
264            mock object resulting from the mock call.
265            """
266            p = mock_func(*args, **kwargs)
267            mocked: MockType = p.start()
268            self.__mock_cache.add(mock=mocked, patch=p)
269            if hasattr(mocked, "reset_mock"):
270                # check if `mocked` is actually a mock object, as depending on autospec or target
271                # parameters `mocked` can be anything
272                if hasattr(mocked, "__enter__") and warn_on_mock_enter:
273                    mocked.__enter__.side_effect = lambda: warnings.warn(
274                        "Mocks returned by pytest-mock do not need to be used as context managers. "
275                        "The mocker fixture automatically undoes mocking at the end of a test. "
276                        "This warning can be ignored if it was triggered by mocking a context manager. "
277                        "https://pytest-mock.readthedocs.io/en/latest/usage.html#usage-as-context-manager",
278                        PytestMockWarning,
279                        stacklevel=5,
280                    )
281            return mocked
282
283        def object(
284            self,
285            target: object,
286            attribute: str,
287            new: object = DEFAULT,
288            spec: Optional[object] = None,
289            create: bool = False,
290            spec_set: Optional[object] = None,
291            autospec: Optional[object] = None,
292            new_callable: object = None,
293            **kwargs: Any,
294        ) -> MockType:
295            """API to mock.patch.object"""
296            if new is self.DEFAULT:
297                new = self.mock_module.DEFAULT
298            return self._start_patch(
299                self.mock_module.patch.object,
300                True,
301                target,
302                attribute,
303                new=new,
304                spec=spec,
305                create=create,
306                spec_set=spec_set,
307                autospec=autospec,
308                new_callable=new_callable,
309                **kwargs,
310            )
311
312        def context_manager(
313            self,
314            target: builtins.object,
315            attribute: str,
316            new: builtins.object = DEFAULT,
317            spec: Optional[builtins.object] = None,
318            create: bool = False,
319            spec_set: Optional[builtins.object] = None,
320            autospec: Optional[builtins.object] = None,
321            new_callable: builtins.object = None,
322            **kwargs: Any,
323        ) -> MockType:
324            """This is equivalent to mock.patch.object except that the returned mock
325            does not issue a warning when used as a context manager."""
326            if new is self.DEFAULT:
327                new = self.mock_module.DEFAULT
328            return self._start_patch(
329                self.mock_module.patch.object,
330                False,
331                target,
332                attribute,
333                new=new,
334                spec=spec,
335                create=create,
336                spec_set=spec_set,
337                autospec=autospec,
338                new_callable=new_callable,
339                **kwargs,
340            )
341
342        def multiple(
343            self,
344            target: builtins.object,
345            spec: Optional[builtins.object] = None,
346            create: bool = False,
347            spec_set: Optional[builtins.object] = None,
348            autospec: Optional[builtins.object] = None,
349            new_callable: Optional[builtins.object] = None,
350            **kwargs: Any,
351        ) -> dict[str, MockType]:
352            """API to mock.patch.multiple"""
353            return self._start_patch(
354                self.mock_module.patch.multiple,
355                True,
356                target,
357                spec=spec,
358                create=create,
359                spec_set=spec_set,
360                autospec=autospec,
361                new_callable=new_callable,
362                **kwargs,
363            )
364
365        def dict(
366            self,
367            in_dict: Union[Mapping[Any, Any], str],
368            values: Union[Mapping[Any, Any], Iterable[tuple[Any, Any]]] = (),
369            clear: bool = False,
370            **kwargs: Any,
371        ) -> Any:
372            """API to mock.patch.dict"""
373            return self._start_patch(
374                self.mock_module.patch.dict,
375                True,
376                in_dict,
377                values=values,
378                clear=clear,
379                **kwargs,
380            )
381
382        @overload
383        def __call__(
384            self,
385            target: str,
386            new: None = ...,
387            spec: Optional[builtins.object] = ...,
388            create: bool = ...,
389            spec_set: Optional[builtins.object] = ...,
390            autospec: Optional[builtins.object] = ...,
391            new_callable: None = ...,
392            **kwargs: Any,
393        ) -> MockType: ...
394
395        @overload
396        def __call__(
397            self,
398            target: str,
399            new: _T,
400            spec: Optional[builtins.object] = ...,
401            create: bool = ...,
402            spec_set: Optional[builtins.object] = ...,
403            autospec: Optional[builtins.object] = ...,
404            new_callable: None = ...,
405            **kwargs: Any,
406        ) -> _T: ...
407
408        @overload
409        def __call__(
410            self,
411            target: str,
412            new: None,
413            spec: Optional[builtins.object],
414            create: bool,
415            spec_set: Optional[builtins.object],
416            autospec: Optional[builtins.object],
417            new_callable: Callable[[], _T],
418            **kwargs: Any,
419        ) -> _T: ...
420
421        @overload
422        def __call__(
423            self,
424            target: str,
425            new: None = ...,
426            spec: Optional[builtins.object] = ...,
427            create: bool = ...,
428            spec_set: Optional[builtins.object] = ...,
429            autospec: Optional[builtins.object] = ...,
430            *,
431            new_callable: Callable[[], _T],
432            **kwargs: Any,
433        ) -> _T: ...
434
435        def __call__(
436            self,
437            target: str,
438            new: builtins.object = DEFAULT,
439            spec: Optional[builtins.object] = None,
440            create: bool = False,
441            spec_set: Optional[builtins.object] = None,
442            autospec: Optional[builtins.object] = None,
443            new_callable: Optional[Callable[[], Any]] = None,
444            **kwargs: Any,
445        ) -> Any:
446            """API to mock.patch"""
447            if new is self.DEFAULT:
448                new = self.mock_module.DEFAULT
449            return self._start_patch(
450                self.mock_module.patch,
451                True,
452                target,
453                new=new,
454                spec=spec,
455                create=create,
456                spec_set=spec_set,
457                autospec=autospec,
458                new_callable=new_callable,
459                **kwargs,
460            )

Fixture that provides the same interface to functions in the mock module, ensuring that they are uninstalled at the end of each test.

MockerFixture(config: Any)
 87    def __init__(self, config: Any) -> None:
 88        self._mock_cache: MockCache = MockCache()
 89        self.mock_module = mock_module = get_mock_module(config)
 90        self.patch = self._Patcher(self._mock_cache, mock_module)  # type: MockerFixture._Patcher
 91        # aliases for convenience
 92        self.Mock = mock_module.Mock
 93        self.MagicMock = mock_module.MagicMock
 94        self.NonCallableMock = mock_module.NonCallableMock
 95        self.NonCallableMagicMock = mock_module.NonCallableMagicMock
 96        self.PropertyMock = mock_module.PropertyMock
 97        if hasattr(mock_module, "AsyncMock"):
 98            self.AsyncMock = mock_module.AsyncMock
 99        self.call = mock_module.call
100        self.ANY = mock_module.ANY
101        self.DEFAULT = mock_module.DEFAULT
102        self.sentinel = mock_module.sentinel
103        self.mock_open = mock_module.mock_open
104        if hasattr(mock_module, "seal"):
105            self.seal = mock_module.seal
patch
Mock
MagicMock
NonCallableMock
NonCallableMagicMock
PropertyMock
call
ANY
DEFAULT
sentinel
mock_open
def create_autospec( self, spec: Any, spec_set: bool = False, instance: bool = False, **kwargs: Any) -> Union[unittest.mock.MagicMock, unittest.mock.AsyncMock, unittest.mock.NonCallableMagicMock]:
107    def create_autospec(
108        self, spec: Any, spec_set: bool = False, instance: bool = False, **kwargs: Any
109    ) -> MockType:
110        m: MockType = self.mock_module.create_autospec(
111            spec, spec_set, instance, **kwargs
112        )
113        self._mock_cache.add(m)
114        return m
def resetall(self, *, return_value: bool = False, side_effect: bool = False) -> None:
116    def resetall(
117        self, *, return_value: bool = False, side_effect: bool = False
118    ) -> None:
119        """
120        Call reset_mock() on all patchers started by this fixture.
121
122        :param bool return_value: Reset the return_value of mocks.
123        :param bool side_effect: Reset the side_effect of mocks.
124        """
125        supports_reset_mock_with_args: tuple[type[Any], ...]
126        if hasattr(self, "AsyncMock"):
127            supports_reset_mock_with_args = (self.Mock, self.AsyncMock)
128        else:
129            supports_reset_mock_with_args = (self.Mock,)
130
131        for mock_item in self._mock_cache:
132            # See issue #237.
133            if not hasattr(mock_item.mock, "reset_mock"):
134                continue
135            # NOTE: The mock may be a dictionary
136            if hasattr(mock_item.mock, "spy_return_list"):
137                mock_item.mock.spy_return_list = []
138            if hasattr(mock_item.mock, "spy_return_iter"):
139                mock_item.mock.spy_return_iter = None
140            if isinstance(mock_item.mock, supports_reset_mock_with_args):
141                mock_item.mock.reset_mock(
142                    return_value=return_value, side_effect=side_effect
143                )
144            else:
145                mock_item.mock.reset_mock()

Call reset_mock() on all patchers started by this fixture.

Parameters
  • bool return_value: Reset the return_value of mocks.
  • bool side_effect: Reset the side_effect of mocks.
def stopall(self) -> None:
147    def stopall(self) -> None:
148        """
149        Stop all patchers started by this fixture. Can be safely called multiple
150        times.
151        """
152        self._mock_cache.clear()

Stop all patchers started by this fixture. Can be safely called multiple times.

def stop(self, mock: unittest.mock.MagicMock) -> None:
154    def stop(self, mock: unittest.mock.MagicMock) -> None:
155        """
156        Stops a previous patch or spy call by passing the ``MagicMock`` object
157        returned by it.
158        """
159        self._mock_cache.remove(mock)

Stops a previous patch or spy call by passing the MagicMock object returned by it.

def spy( self, obj: object, name: str, duplicate_iterators: bool = False) -> Union[unittest.mock.MagicMock, unittest.mock.AsyncMock, unittest.mock.NonCallableMagicMock]:
161    def spy(
162        self, obj: object, name: str, duplicate_iterators: bool = False
163    ) -> MockType:
164        """
165        Create a spy of method. It will run method normally, but it is now
166        possible to use `mock` call features with it, like call count.
167
168        :param obj: An object.
169        :param name: A method in object.
170        :param duplicate_iterators: Whether to keep a copy of the returned iterator in `spy_return_iter`.
171        :return: Spy object.
172        """
173        method = getattr(obj, name)
174
175        def wrapper(*args, **kwargs):
176            spy_obj.spy_return = None
177            spy_obj.spy_exception = None
178            try:
179                r = method(*args, **kwargs)
180            except BaseException as e:
181                spy_obj.spy_exception = e
182                raise
183            else:
184                if duplicate_iterators and isinstance(r, Iterator):
185                    r, duplicated_iterator = itertools.tee(r, 2)
186                    spy_obj.spy_return_iter = duplicated_iterator
187                else:
188                    spy_obj.spy_return_iter = None
189
190                spy_obj.spy_return = r
191                spy_obj.spy_return_list.append(r)
192            return r
193
194        async def async_wrapper(*args, **kwargs):
195            spy_obj.spy_return = None
196            spy_obj.spy_exception = None
197            try:
198                r = await method(*args, **kwargs)
199            except BaseException as e:
200                spy_obj.spy_exception = e
201                raise
202            else:
203                spy_obj.spy_return = r
204                spy_obj.spy_return_list.append(r)
205            return r
206
207        if inspect.iscoroutinefunction(method):
208            wrapped = functools.update_wrapper(async_wrapper, method)
209        else:
210            wrapped = functools.update_wrapper(wrapper, method)
211
212        autospec = inspect.ismethod(method) or inspect.isfunction(method)
213
214        spy_obj = self.patch.object(obj, name, side_effect=wrapped, autospec=autospec)
215        spy_obj.spy_return = None
216        spy_obj.spy_return_iter = None
217        spy_obj.spy_return_list = []
218        spy_obj.spy_exception = None
219        return spy_obj

Create a spy of method. It will run method normally, but it is now possible to use mock call features with it, like call count.

Parameters
  • obj: An object.
  • name: A method in object.
  • duplicate_iterators: Whether to keep a copy of the returned iterator in spy_return_iter.
Returns

Spy object.

def stub(self, name: Optional[str] = None) -> unittest.mock.MagicMock:
221    def stub(self, name: Optional[str] = None) -> unittest.mock.MagicMock:
222        """
223        Create a stub method. It accepts any arguments. Ideal to register to
224        callbacks in tests.
225
226        :param name: the constructed stub's name as used in repr
227        :return: Stub object.
228        """
229        return cast(
230            unittest.mock.MagicMock,
231            self.mock_module.MagicMock(spec=lambda *args, **kwargs: None, name=name),
232        )

Create a stub method. It accepts any arguments. Ideal to register to callbacks in tests.

Parameters
  • name: the constructed stub's name as used in repr
Returns

Stub object.

def async_stub(self, name: Optional[str] = None) -> unittest.mock.AsyncMock:
234    def async_stub(self, name: Optional[str] = None) -> AsyncMockType:
235        """
236        Create a async stub method. It accepts any arguments. Ideal to register to
237        callbacks in tests.
238
239        :param name: the constructed stub's name as used in repr
240        :return: Stub object.
241        """
242        return cast(
243            AsyncMockType,
244            self.mock_module.AsyncMock(spec=lambda *args, **kwargs: None, name=name),
245        )

Create a async stub method. It accepts any arguments. Ideal to register to callbacks in tests.

Parameters
  • name: the constructed stub's name as used in repr
Returns

Stub object.

def mocker( pytestconfig: Any) -> Generator[MockerFixture, None, None]:
463def _mocker(pytestconfig: Any) -> Generator[MockerFixture, None, None]:
464    """
465    Return an object that has the same interface to the `mock` module, but
466    takes care of automatically undoing all patches after each test method.
467    """
468    result = MockerFixture(pytestconfig)
469    yield result
470    result.stopall()

Return an object that has the same interface to the mock module, but takes care of automatically undoing all patches after each test method.

def class_mocker( pytestconfig: Any) -> Generator[MockerFixture, None, None]:
463def _mocker(pytestconfig: Any) -> Generator[MockerFixture, None, None]:
464    """
465    Return an object that has the same interface to the `mock` module, but
466    takes care of automatically undoing all patches after each test method.
467    """
468    result = MockerFixture(pytestconfig)
469    yield result
470    result.stopall()

Return an object that has the same interface to the mock module, but takes care of automatically undoing all patches after each test method.

def module_mocker( pytestconfig: Any) -> Generator[MockerFixture, None, None]:
463def _mocker(pytestconfig: Any) -> Generator[MockerFixture, None, None]:
464    """
465    Return an object that has the same interface to the `mock` module, but
466    takes care of automatically undoing all patches after each test method.
467    """
468    result = MockerFixture(pytestconfig)
469    yield result
470    result.stopall()

Return an object that has the same interface to the mock module, but takes care of automatically undoing all patches after each test method.

def package_mocker( pytestconfig: Any) -> Generator[MockerFixture, None, None]:
463def _mocker(pytestconfig: Any) -> Generator[MockerFixture, None, None]:
464    """
465    Return an object that has the same interface to the `mock` module, but
466    takes care of automatically undoing all patches after each test method.
467    """
468    result = MockerFixture(pytestconfig)
469    yield result
470    result.stopall()

Return an object that has the same interface to the mock module, but takes care of automatically undoing all patches after each test method.

def session_mocker( pytestconfig: Any) -> Generator[MockerFixture, None, None]:
463def _mocker(pytestconfig: Any) -> Generator[MockerFixture, None, None]:
464    """
465    Return an object that has the same interface to the `mock` module, but
466    takes care of automatically undoing all patches after each test method.
467    """
468    result = MockerFixture(pytestconfig)
469    yield result
470    result.stopall()

Return an object that has the same interface to the mock module, but takes care of automatically undoing all patches after each test method.

def assert_wrapper( __wrapped_mock_method__: Callable[..., Any], *args: Any, **kwargs: Any) -> None:
484def assert_wrapper(
485    __wrapped_mock_method__: Callable[..., Any], *args: Any, **kwargs: Any
486) -> None:
487    __tracebackhide__ = True
488    try:
489        __wrapped_mock_method__(*args, **kwargs)
490        return
491    except AssertionError as e:
492        if getattr(e, "_mock_introspection_applied", 0):
493            msg = str(e)
494        else:
495            __mock_self = args[0]
496            msg = str(e)
497            if __mock_self.call_args is not None:
498                actual_args, actual_kwargs = __mock_self.call_args
499                introspection = ""
500                try:
501                    assert actual_args == args[1:]
502                except AssertionError as e_args:
503                    introspection += "\nArgs:\n" + str(e_args)
504                try:
505                    assert actual_kwargs == kwargs
506                except AssertionError as e_kwargs:
507                    introspection += "\nKwargs:\n" + str(e_kwargs)
508                if introspection:
509                    msg += "\n\npytest introspection follows:\n" + introspection
510        e = AssertionError(msg)
511        e._mock_introspection_applied = True  # type:ignore[attr-defined]
512        raise e
def assert_has_calls_wrapper( __wrapped_mock_method__: Callable[..., Any], *args: Any, **kwargs: Any) -> None:
515def assert_has_calls_wrapper(
516    __wrapped_mock_method__: Callable[..., Any], *args: Any, **kwargs: Any
517) -> None:
518    __tracebackhide__ = True
519    try:
520        __wrapped_mock_method__(*args, **kwargs)
521        return
522    except AssertionError as e:
523        any_order = kwargs.get("any_order", False)
524        if getattr(e, "_mock_introspection_applied", 0) or any_order:
525            msg = str(e)
526        else:
527            __mock_self = args[0]
528            msg = str(e)
529            if __mock_self.call_args_list is not None:
530                actual_calls = list(__mock_self.call_args_list)
531                expect_calls = args[1]
532                introspection = ""
533                from itertools import zip_longest
534
535                for actual_call, expect_call in zip_longest(actual_calls, expect_calls):
536                    if actual_call is not None:
537                        actual_args, actual_kwargs = actual_call
538                    else:
539                        actual_args = tuple()
540                        actual_kwargs = {}
541
542                    if expect_call is not None:
543                        _, expect_args, expect_kwargs = expect_call
544                    else:
545                        expect_args = tuple()
546                        expect_kwargs = {}
547
548                    try:
549                        assert actual_args == expect_args
550                    except AssertionError as e_args:
551                        introspection += "\nArgs:\n" + str(e_args)
552                    try:
553                        assert actual_kwargs == expect_kwargs
554                    except AssertionError as e_kwargs:
555                        introspection += "\nKwargs:\n" + str(e_kwargs)
556                if introspection:
557                    msg += "\n\npytest introspection follows:\n" + introspection
558        e = AssertionError(msg)
559        e._mock_introspection_applied = True  # type:ignore[attr-defined]
560        raise e
def wrap_assert_not_called(*args: Any, **kwargs: Any) -> None:
563def wrap_assert_not_called(*args: Any, **kwargs: Any) -> None:
564    __tracebackhide__ = True
565    assert_wrapper(_mock_module_originals["assert_not_called"], *args, **kwargs)
def wrap_assert_called_with(*args: Any, **kwargs: Any) -> None:
568def wrap_assert_called_with(*args: Any, **kwargs: Any) -> None:
569    __tracebackhide__ = True
570    assert_wrapper(_mock_module_originals["assert_called_with"], *args, **kwargs)
def wrap_assert_called_once(*args: Any, **kwargs: Any) -> None:
573def wrap_assert_called_once(*args: Any, **kwargs: Any) -> None:
574    __tracebackhide__ = True
575    assert_wrapper(_mock_module_originals["assert_called_once"], *args, **kwargs)
def wrap_assert_called_once_with(*args: Any, **kwargs: Any) -> None:
578def wrap_assert_called_once_with(*args: Any, **kwargs: Any) -> None:
579    __tracebackhide__ = True
580    assert_wrapper(_mock_module_originals["assert_called_once_with"], *args, **kwargs)
def wrap_assert_has_calls(*args: Any, **kwargs: Any) -> None:
583def wrap_assert_has_calls(*args: Any, **kwargs: Any) -> None:
584    __tracebackhide__ = True
585    assert_has_calls_wrapper(
586        _mock_module_originals["assert_has_calls"], *args, **kwargs
587    )
def wrap_assert_any_call(*args: Any, **kwargs: Any) -> None:
590def wrap_assert_any_call(*args: Any, **kwargs: Any) -> None:
591    __tracebackhide__ = True
592    assert_wrapper(_mock_module_originals["assert_any_call"], *args, **kwargs)
def wrap_assert_called(*args: Any, **kwargs: Any) -> None:
595def wrap_assert_called(*args: Any, **kwargs: Any) -> None:
596    __tracebackhide__ = True
597    assert_wrapper(_mock_module_originals["assert_called"], *args, **kwargs)
def wrap_assert_not_awaited(*args: Any, **kwargs: Any) -> None:
600def wrap_assert_not_awaited(*args: Any, **kwargs: Any) -> None:
601    __tracebackhide__ = True
602    assert_wrapper(_mock_module_originals["assert_not_awaited"], *args, **kwargs)
def wrap_assert_awaited_with(*args: Any, **kwargs: Any) -> None:
605def wrap_assert_awaited_with(*args: Any, **kwargs: Any) -> None:
606    __tracebackhide__ = True
607    assert_wrapper(_mock_module_originals["assert_awaited_with"], *args, **kwargs)
def wrap_assert_awaited_once(*args: Any, **kwargs: Any) -> None:
610def wrap_assert_awaited_once(*args: Any, **kwargs: Any) -> None:
611    __tracebackhide__ = True
612    assert_wrapper(_mock_module_originals["assert_awaited_once"], *args, **kwargs)
def wrap_assert_awaited_once_with(*args: Any, **kwargs: Any) -> None:
615def wrap_assert_awaited_once_with(*args: Any, **kwargs: Any) -> None:
616    __tracebackhide__ = True
617    assert_wrapper(_mock_module_originals["assert_awaited_once_with"], *args, **kwargs)
def wrap_assert_has_awaits(*args: Any, **kwargs: Any) -> None:
620def wrap_assert_has_awaits(*args: Any, **kwargs: Any) -> None:
621    __tracebackhide__ = True
622    assert_wrapper(_mock_module_originals["assert_has_awaits"], *args, **kwargs)
def wrap_assert_any_await(*args: Any, **kwargs: Any) -> None:
625def wrap_assert_any_await(*args: Any, **kwargs: Any) -> None:
626    __tracebackhide__ = True
627    assert_wrapper(_mock_module_originals["assert_any_await"], *args, **kwargs)
def wrap_assert_awaited(*args: Any, **kwargs: Any) -> None:
630def wrap_assert_awaited(*args: Any, **kwargs: Any) -> None:
631    __tracebackhide__ = True
632    assert_wrapper(_mock_module_originals["assert_awaited"], *args, **kwargs)
def wrap_assert_methods(config: Any) -> None:
635def wrap_assert_methods(config: Any) -> None:
636    """
637    Wrap assert methods of mock module so we can hide their traceback and
638    add introspection information to specified argument asserts.
639    """
640    # Make sure we only do this once
641    if _mock_module_originals:
642        return
643
644    mock_module = get_mock_module(config)
645
646    wrappers = {
647        "assert_called": wrap_assert_called,
648        "assert_called_once": wrap_assert_called_once,
649        "assert_called_with": wrap_assert_called_with,
650        "assert_called_once_with": wrap_assert_called_once_with,
651        "assert_any_call": wrap_assert_any_call,
652        "assert_has_calls": wrap_assert_has_calls,
653        "assert_not_called": wrap_assert_not_called,
654    }
655    for method, wrapper in wrappers.items():
656        try:
657            original = getattr(mock_module.NonCallableMock, method)
658        except AttributeError:  # pragma: no cover
659            continue
660        _mock_module_originals[method] = original
661        patcher = mock_module.patch.object(mock_module.NonCallableMock, method, wrapper)
662        patcher.start()
663        _mock_module_patches.append(patcher)
664
665    if hasattr(mock_module, "AsyncMock"):
666        async_wrappers = {
667            "assert_awaited": wrap_assert_awaited,
668            "assert_awaited_once": wrap_assert_awaited_once,
669            "assert_awaited_with": wrap_assert_awaited_with,
670            "assert_awaited_once_with": wrap_assert_awaited_once_with,
671            "assert_any_await": wrap_assert_any_await,
672            "assert_has_awaits": wrap_assert_has_awaits,
673            "assert_not_awaited": wrap_assert_not_awaited,
674        }
675        for method, wrapper in async_wrappers.items():
676            try:
677                original = getattr(mock_module.AsyncMock, method)
678            except AttributeError:  # pragma: no cover
679                continue
680            _mock_module_originals[method] = original
681            patcher = mock_module.patch.object(mock_module.AsyncMock, method, wrapper)
682            patcher.start()
683            _mock_module_patches.append(patcher)
684
685    config.add_cleanup(unwrap_assert_methods)

Wrap assert methods of mock module so we can hide their traceback and add introspection information to specified argument asserts.

def unwrap_assert_methods() -> None:
688def unwrap_assert_methods() -> None:
689    for patcher in _mock_module_patches:
690        try:
691            patcher.stop()
692        except RuntimeError as e:
693            # a patcher might have been stopped by user code (#137)
694            # so we need to catch this error here and ignore it;
695            # unfortunately there's no public API to check if a patch
696            # has been started, so catching the error it is
697            if str(e) == "stop called on unstarted patcher":
698                pass
699            else:
700                raise
701    _mock_module_patches[:] = []
702    _mock_module_originals.clear()
def pytest_addoption(parser: Any) -> None:
705def pytest_addoption(parser: Any) -> None:
706    parser.addini(
707        "mock_traceback_monkeypatch",
708        "Monkeypatch the mock library to improve reporting of the "
709        "assert_called_... methods",
710        default=True,
711    )
712    parser.addini(
713        "mock_use_standalone_module",
714        'Use standalone "mock" (from PyPI) instead of builtin "unittest.mock" '
715        "on Python 3",
716        default=False,
717    )
def pytest_configure(config: Any) -> None:
720def pytest_configure(config: Any) -> None:
721    tb = config.getoption("--tb", default="auto")
722    if (
723        parse_ini_boolean(config.getini("mock_traceback_monkeypatch"))
724        and tb != "native"
725    ):
726        wrap_assert_methods(config)