pytest_mock.plugin

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

Base class for all warnings emitted by pytest-mock.

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

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)
 91    def __init__(self, config: Any) -> None:
 92        self._mock_cache: MockCache = MockCache()
 93        self.mock_module = mock_module = get_mock_module(config)
 94        self.patch = self._Patcher(self._mock_cache, mock_module)  # type: MockerFixture._Patcher
 95        # aliases for convenience
 96        self.Mock = mock_module.Mock
 97        self.MagicMock = mock_module.MagicMock
 98        self.NonCallableMock = mock_module.NonCallableMock
 99        self.NonCallableMagicMock = mock_module.NonCallableMagicMock
100        self.PropertyMock = mock_module.PropertyMock
101        if hasattr(mock_module, "AsyncMock"):
102            self.AsyncMock = mock_module.AsyncMock
103        self.call = mock_module.call
104        self.ANY = mock_module.ANY
105        self.DEFAULT = mock_module.DEFAULT
106        self.sentinel = mock_module.sentinel
107        self.mock_open = mock_module.mock_open
108        if hasattr(mock_module, "seal"):
109            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]:
111    def create_autospec(
112        self, spec: Any, spec_set: bool = False, instance: bool = False, **kwargs: Any
113    ) -> MockType:
114        m: MockType = self.mock_module.create_autospec(
115            spec, spec_set, instance, **kwargs
116        )
117        self._mock_cache.add(m)
118        return m
def resetall(self, *, return_value: bool = False, side_effect: bool = False) -> None:
120    def resetall(
121        self, *, return_value: bool = False, side_effect: bool = False
122    ) -> None:
123        """
124        Call reset_mock() on all patchers started by this fixture.
125
126        :param bool return_value: Reset the return_value of mocks.
127        :param bool side_effect: Reset the side_effect of mocks.
128        """
129        supports_reset_mock_with_args: Tuple[Type[Any], ...]
130        if hasattr(self, "AsyncMock"):
131            supports_reset_mock_with_args = (self.Mock, self.AsyncMock)
132        else:
133            supports_reset_mock_with_args = (self.Mock,)
134
135        for mock_item in self._mock_cache:
136            # See issue #237.
137            if not hasattr(mock_item.mock, "reset_mock"):
138                continue
139            # NOTE: The mock may be a dictionary
140            if hasattr(mock_item.mock, "spy_return_list"):
141                mock_item.mock.spy_return_list = []
142            if isinstance(mock_item.mock, supports_reset_mock_with_args):
143                mock_item.mock.reset_mock(
144                    return_value=return_value, side_effect=side_effect
145                )
146            else:
147                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:
149    def stopall(self) -> None:
150        """
151        Stop all patchers started by this fixture. Can be safely called multiple
152        times.
153        """
154        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:
156    def stop(self, mock: unittest.mock.MagicMock) -> None:
157        """
158        Stops a previous patch or spy call by passing the ``MagicMock`` object
159        returned by it.
160        """
161        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) -> Union[unittest.mock.MagicMock, unittest.mock.AsyncMock, unittest.mock.NonCallableMagicMock]:
163    def spy(self, obj: object, name: str) -> 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        :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                spy_obj.spy_return = r
184                spy_obj.spy_return_list.append(r)
185            return r
186
187        async def async_wrapper(*args, **kwargs):
188            spy_obj.spy_return = None
189            spy_obj.spy_exception = None
190            try:
191                r = await method(*args, **kwargs)
192            except BaseException as e:
193                spy_obj.spy_exception = e
194                raise
195            else:
196                spy_obj.spy_return = r
197                spy_obj.spy_return_list.append(r)
198            return r
199
200        if asyncio.iscoroutinefunction(method):
201            wrapped = functools.update_wrapper(async_wrapper, method)
202        else:
203            wrapped = functools.update_wrapper(wrapper, method)
204
205        autospec = inspect.ismethod(method) or inspect.isfunction(method)
206
207        spy_obj = self.patch.object(obj, name, side_effect=wrapped, autospec=autospec)
208        spy_obj.spy_return = None
209        spy_obj.spy_return_list = []
210        spy_obj.spy_exception = None
211        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.
Returns

Spy object.

def stub(self, name: Optional[str] = None) -> unittest.mock.MagicMock:
213    def stub(self, name: Optional[str] = None) -> unittest.mock.MagicMock:
214        """
215        Create a stub method. It accepts any arguments. Ideal to register to
216        callbacks in tests.
217
218        :param name: the constructed stub's name as used in repr
219        :return: Stub object.
220        """
221        return cast(
222            unittest.mock.MagicMock,
223            self.mock_module.MagicMock(spec=lambda *args, **kwargs: None, name=name),
224        )

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:
226    def async_stub(self, name: Optional[str] = None) -> AsyncMockType:
227        """
228        Create a async stub method. It accepts any arguments. Ideal to register to
229        callbacks in tests.
230
231        :param name: the constructed stub's name as used in repr
232        :return: Stub object.
233        """
234        return cast(
235            AsyncMockType,
236            self.mock_module.AsyncMock(spec=lambda *args, **kwargs: None, name=name),
237        )

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, NoneType, NoneType]:
455def _mocker(pytestconfig: Any) -> Generator[MockerFixture, None, None]:
456    """
457    Return an object that has the same interface to the `mock` module, but
458    takes care of automatically undoing all patches after each test method.
459    """
460    result = MockerFixture(pytestconfig)
461    yield result
462    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, NoneType, NoneType]:
455def _mocker(pytestconfig: Any) -> Generator[MockerFixture, None, None]:
456    """
457    Return an object that has the same interface to the `mock` module, but
458    takes care of automatically undoing all patches after each test method.
459    """
460    result = MockerFixture(pytestconfig)
461    yield result
462    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, NoneType, NoneType]:
455def _mocker(pytestconfig: Any) -> Generator[MockerFixture, None, None]:
456    """
457    Return an object that has the same interface to the `mock` module, but
458    takes care of automatically undoing all patches after each test method.
459    """
460    result = MockerFixture(pytestconfig)
461    yield result
462    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, NoneType, NoneType]:
455def _mocker(pytestconfig: Any) -> Generator[MockerFixture, None, None]:
456    """
457    Return an object that has the same interface to the `mock` module, but
458    takes care of automatically undoing all patches after each test method.
459    """
460    result = MockerFixture(pytestconfig)
461    yield result
462    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, NoneType, NoneType]:
455def _mocker(pytestconfig: Any) -> Generator[MockerFixture, None, None]:
456    """
457    Return an object that has the same interface to the `mock` module, but
458    takes care of automatically undoing all patches after each test method.
459    """
460    result = MockerFixture(pytestconfig)
461    yield result
462    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:
476def assert_wrapper(
477    __wrapped_mock_method__: Callable[..., Any], *args: Any, **kwargs: Any
478) -> None:
479    __tracebackhide__ = True
480    try:
481        __wrapped_mock_method__(*args, **kwargs)
482        return
483    except AssertionError as e:
484        if getattr(e, "_mock_introspection_applied", 0):
485            msg = str(e)
486        else:
487            __mock_self = args[0]
488            msg = str(e)
489            if __mock_self.call_args is not None:
490                actual_args, actual_kwargs = __mock_self.call_args
491                introspection = ""
492                try:
493                    assert actual_args == args[1:]
494                except AssertionError as e_args:
495                    introspection += "\nArgs:\n" + str(e_args)
496                try:
497                    assert actual_kwargs == kwargs
498                except AssertionError as e_kwargs:
499                    introspection += "\nKwargs:\n" + str(e_kwargs)
500                if introspection:
501                    msg += "\n\npytest introspection follows:\n" + introspection
502        e = AssertionError(msg)
503        e._mock_introspection_applied = True  # type:ignore[attr-defined]
504        raise e
def assert_has_calls_wrapper( __wrapped_mock_method__: Callable[..., Any], *args: Any, **kwargs: Any) -> None:
507def assert_has_calls_wrapper(
508    __wrapped_mock_method__: Callable[..., Any], *args: Any, **kwargs: Any
509) -> None:
510    __tracebackhide__ = True
511    try:
512        __wrapped_mock_method__(*args, **kwargs)
513        return
514    except AssertionError as e:
515        any_order = kwargs.get("any_order", False)
516        if getattr(e, "_mock_introspection_applied", 0) or any_order:
517            msg = str(e)
518        else:
519            __mock_self = args[0]
520            msg = str(e)
521            if __mock_self.call_args_list is not None:
522                actual_calls = list(__mock_self.call_args_list)
523                expect_calls = args[1]
524                introspection = ""
525                from itertools import zip_longest
526
527                for actual_call, expect_call in zip_longest(actual_calls, expect_calls):
528                    if actual_call is not None:
529                        actual_args, actual_kwargs = actual_call
530                    else:
531                        actual_args = tuple()
532                        actual_kwargs = {}
533
534                    if expect_call is not None:
535                        _, expect_args, expect_kwargs = expect_call
536                    else:
537                        expect_args = tuple()
538                        expect_kwargs = {}
539
540                    try:
541                        assert actual_args == expect_args
542                    except AssertionError as e_args:
543                        introspection += "\nArgs:\n" + str(e_args)
544                    try:
545                        assert actual_kwargs == expect_kwargs
546                    except AssertionError as e_kwargs:
547                        introspection += "\nKwargs:\n" + str(e_kwargs)
548                if introspection:
549                    msg += "\n\npytest introspection follows:\n" + introspection
550        e = AssertionError(msg)
551        e._mock_introspection_applied = True  # type:ignore[attr-defined]
552        raise e
def wrap_assert_not_called(*args: Any, **kwargs: Any) -> None:
555def wrap_assert_not_called(*args: Any, **kwargs: Any) -> None:
556    __tracebackhide__ = True
557    assert_wrapper(_mock_module_originals["assert_not_called"], *args, **kwargs)
def wrap_assert_called_with(*args: Any, **kwargs: Any) -> None:
560def wrap_assert_called_with(*args: Any, **kwargs: Any) -> None:
561    __tracebackhide__ = True
562    assert_wrapper(_mock_module_originals["assert_called_with"], *args, **kwargs)
def wrap_assert_called_once(*args: Any, **kwargs: Any) -> None:
565def wrap_assert_called_once(*args: Any, **kwargs: Any) -> None:
566    __tracebackhide__ = True
567    assert_wrapper(_mock_module_originals["assert_called_once"], *args, **kwargs)
def wrap_assert_called_once_with(*args: Any, **kwargs: Any) -> None:
570def wrap_assert_called_once_with(*args: Any, **kwargs: Any) -> None:
571    __tracebackhide__ = True
572    assert_wrapper(_mock_module_originals["assert_called_once_with"], *args, **kwargs)
def wrap_assert_has_calls(*args: Any, **kwargs: Any) -> None:
575def wrap_assert_has_calls(*args: Any, **kwargs: Any) -> None:
576    __tracebackhide__ = True
577    assert_has_calls_wrapper(
578        _mock_module_originals["assert_has_calls"], *args, **kwargs
579    )
def wrap_assert_any_call(*args: Any, **kwargs: Any) -> None:
582def wrap_assert_any_call(*args: Any, **kwargs: Any) -> None:
583    __tracebackhide__ = True
584    assert_wrapper(_mock_module_originals["assert_any_call"], *args, **kwargs)
def wrap_assert_called(*args: Any, **kwargs: Any) -> None:
587def wrap_assert_called(*args: Any, **kwargs: Any) -> None:
588    __tracebackhide__ = True
589    assert_wrapper(_mock_module_originals["assert_called"], *args, **kwargs)
def wrap_assert_not_awaited(*args: Any, **kwargs: Any) -> None:
592def wrap_assert_not_awaited(*args: Any, **kwargs: Any) -> None:
593    __tracebackhide__ = True
594    assert_wrapper(_mock_module_originals["assert_not_awaited"], *args, **kwargs)
def wrap_assert_awaited_with(*args: Any, **kwargs: Any) -> None:
597def wrap_assert_awaited_with(*args: Any, **kwargs: Any) -> None:
598    __tracebackhide__ = True
599    assert_wrapper(_mock_module_originals["assert_awaited_with"], *args, **kwargs)
def wrap_assert_awaited_once(*args: Any, **kwargs: Any) -> None:
602def wrap_assert_awaited_once(*args: Any, **kwargs: Any) -> None:
603    __tracebackhide__ = True
604    assert_wrapper(_mock_module_originals["assert_awaited_once"], *args, **kwargs)
def wrap_assert_awaited_once_with(*args: Any, **kwargs: Any) -> None:
607def wrap_assert_awaited_once_with(*args: Any, **kwargs: Any) -> None:
608    __tracebackhide__ = True
609    assert_wrapper(_mock_module_originals["assert_awaited_once_with"], *args, **kwargs)
def wrap_assert_has_awaits(*args: Any, **kwargs: Any) -> None:
612def wrap_assert_has_awaits(*args: Any, **kwargs: Any) -> None:
613    __tracebackhide__ = True
614    assert_wrapper(_mock_module_originals["assert_has_awaits"], *args, **kwargs)
def wrap_assert_any_await(*args: Any, **kwargs: Any) -> None:
617def wrap_assert_any_await(*args: Any, **kwargs: Any) -> None:
618    __tracebackhide__ = True
619    assert_wrapper(_mock_module_originals["assert_any_await"], *args, **kwargs)
def wrap_assert_awaited(*args: Any, **kwargs: Any) -> None:
622def wrap_assert_awaited(*args: Any, **kwargs: Any) -> None:
623    __tracebackhide__ = True
624    assert_wrapper(_mock_module_originals["assert_awaited"], *args, **kwargs)
def wrap_assert_methods(config: Any) -> None:
627def wrap_assert_methods(config: Any) -> None:
628    """
629    Wrap assert methods of mock module so we can hide their traceback and
630    add introspection information to specified argument asserts.
631    """
632    # Make sure we only do this once
633    if _mock_module_originals:
634        return
635
636    mock_module = get_mock_module(config)
637
638    wrappers = {
639        "assert_called": wrap_assert_called,
640        "assert_called_once": wrap_assert_called_once,
641        "assert_called_with": wrap_assert_called_with,
642        "assert_called_once_with": wrap_assert_called_once_with,
643        "assert_any_call": wrap_assert_any_call,
644        "assert_has_calls": wrap_assert_has_calls,
645        "assert_not_called": wrap_assert_not_called,
646    }
647    for method, wrapper in wrappers.items():
648        try:
649            original = getattr(mock_module.NonCallableMock, method)
650        except AttributeError:  # pragma: no cover
651            continue
652        _mock_module_originals[method] = original
653        patcher = mock_module.patch.object(mock_module.NonCallableMock, method, wrapper)
654        patcher.start()
655        _mock_module_patches.append(patcher)
656
657    if hasattr(mock_module, "AsyncMock"):
658        async_wrappers = {
659            "assert_awaited": wrap_assert_awaited,
660            "assert_awaited_once": wrap_assert_awaited_once,
661            "assert_awaited_with": wrap_assert_awaited_with,
662            "assert_awaited_once_with": wrap_assert_awaited_once_with,
663            "assert_any_await": wrap_assert_any_await,
664            "assert_has_awaits": wrap_assert_has_awaits,
665            "assert_not_awaited": wrap_assert_not_awaited,
666        }
667        for method, wrapper in async_wrappers.items():
668            try:
669                original = getattr(mock_module.AsyncMock, method)
670            except AttributeError:  # pragma: no cover
671                continue
672            _mock_module_originals[method] = original
673            patcher = mock_module.patch.object(mock_module.AsyncMock, method, wrapper)
674            patcher.start()
675            _mock_module_patches.append(patcher)
676
677    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:
680def unwrap_assert_methods() -> None:
681    for patcher in _mock_module_patches:
682        try:
683            patcher.stop()
684        except RuntimeError as e:
685            # a patcher might have been stopped by user code (#137)
686            # so we need to catch this error here and ignore it;
687            # unfortunately there's no public API to check if a patch
688            # has been started, so catching the error it is
689            if str(e) == "stop called on unstarted patcher":
690                pass
691            else:
692                raise
693    _mock_module_patches[:] = []
694    _mock_module_originals.clear()
def pytest_addoption(parser: Any) -> None:
697def pytest_addoption(parser: Any) -> None:
698    parser.addini(
699        "mock_traceback_monkeypatch",
700        "Monkeypatch the mock library to improve reporting of the "
701        "assert_called_... methods",
702        default=True,
703    )
704    parser.addini(
705        "mock_use_standalone_module",
706        'Use standalone "mock" (from PyPI) instead of builtin "unittest.mock" '
707        "on Python 3",
708        default=False,
709    )
def pytest_configure(config: Any) -> None:
712def pytest_configure(config: Any) -> None:
713    tb = config.getoption("--tb", default="auto")
714    if (
715        parse_ini_boolean(config.getini("mock_traceback_monkeypatch"))
716        and tb != "native"
717    ):
718        wrap_assert_methods(config)