diff --git a/Lib/test/test_unittest/testmock/testpatch.py b/Lib/test/test_unittest/testmock/testpatch.py index bd85fdcfc472a61..c41c70bc89baa63 100644 --- a/Lib/test/test_unittest/testmock/testpatch.py +++ b/Lib/test/test_unittest/testmock/testpatch.py @@ -13,6 +13,7 @@ from test.support.import_helper import DirsOnSysPath from test.test_importlib.util import uncache +lazy from json import dumps as lazy_dumps # noqa: F401 from unittest.mock import ( NonCallableMock, CallableMixin, sentinel, MagicMock, Mock, NonCallableMagicMock, patch, _patch, @@ -2101,5 +2102,12 @@ def test(_): test() + def test_patch_autospec_lazy_import(self): + self.assertIn("lazy_dumps", globals()) + + with patch(f"{__name__}.lazy_dumps", autospec=True) as mock_dumps: + mock_dumps({}) + mock_dumps.assert_called_once_with({}) + if __name__ == '__main__': unittest.main() diff --git a/Lib/unittest/mock.py b/Lib/unittest/mock.py index 49011faaa51eaed..5f270e7a5ea804f 100644 --- a/Lib/unittest/mock.py +++ b/Lib/unittest/mock.py @@ -31,6 +31,7 @@ import sys import builtins import pkgutil +import types from inspect import iscoroutinefunction import threading from annotationlib import Format @@ -1470,6 +1471,8 @@ def get_original(self): original = getattr(target, name, DEFAULT) else: local = True + if isinstance(original, types.LazyImportType): + original = original.resolve() if name in _builtins and isinstance(target, ModuleType): self.create = True diff --git a/Misc/NEWS.d/next/Library/2026-07-18-14-20-13.gh-issue-153888.K9Otcl.rst b/Misc/NEWS.d/next/Library/2026-07-18-14-20-13.gh-issue-153888.K9Otcl.rst new file mode 100644 index 000000000000000..278c9560cec216e --- /dev/null +++ b/Misc/NEWS.d/next/Library/2026-07-18-14-20-13.gh-issue-153888.K9Otcl.rst @@ -0,0 +1,2 @@ +Fix :func:`unittest.mock.patch` with ``autospec``, ``spec``, or ``spec_set`` +when used with lazy-imported objects.