From 090fc15ee4fddfcd20729e8dc1292f5dd7da1c4d Mon Sep 17 00:00:00 2001 From: factnn <166481866+factnn@users.noreply.github.com> Date: Thu, 28 May 2026 00:17:34 +0800 Subject: [PATCH 1/2] gh-150484: Fix mock_open __exit__ with contextlib.ExitStack mock_open's _exit_side_effect had a fixed 3-arg signature, but contextlib.ExitStack calls __exit__ with 4 args (self + 3 exc info). Use *args to accept any number of arguments. Fixes #150484 --- Lib/test/test_unittest/testmock/testmock.py | 9 +++++++++ Lib/unittest/mock.py | 2 +- 2 files changed, 10 insertions(+), 1 deletion(-) diff --git a/Lib/test/test_unittest/testmock/testmock.py b/Lib/test/test_unittest/testmock/testmock.py index 764585ec5d54688..ef69f060886d0a4 100644 --- a/Lib/test/test_unittest/testmock/testmock.py +++ b/Lib/test/test_unittest/testmock/testmock.py @@ -2108,6 +2108,15 @@ def test_mock_open_after_eof(self): self.assertEqual([], h.readlines()) self.assertEqual([], h.readlines()) + def test_mock_open_exit_with_contextlib_exit_stack(self): + # gh-150484: mock_open's __exit__ should work when called from + # contextlib.ExitStack, which passes (exctype, excinst, exctb). + from contextlib import ExitStack + with mock.patch('builtins.open', mock.mock_open()) as m: + with ExitStack() as exit_stack: + with exit_stack.enter_context(open('/tmp/test.txt', 'w')): + pass + def test_mock_parents(self): for Klass in Mock, MagicMock: m = Klass() diff --git a/Lib/unittest/mock.py b/Lib/unittest/mock.py index 56cdc37942d65d8..10d6a428e1fa56b 100644 --- a/Lib/unittest/mock.py +++ b/Lib/unittest/mock.py @@ -3002,7 +3002,7 @@ def _next_side_effect(): return handle.readline.return_value return next(_state[0]) - def _exit_side_effect(exctype, excinst, exctb): + def _exit_side_effect(*args): handle.close() global file_spec From 27616f2875540e6e6034a647fcbe1b560b837b9b Mon Sep 17 00:00:00 2001 From: factnn <166481866+factnn@users.noreply.github.com> Date: Thu, 28 May 2026 02:15:04 +0800 Subject: [PATCH 2/2] Add news entry for gh-150484 --- .../next/Library/2026-05-28-00-00-00.gh-issue-150484.XxYyZz.rst | 1 + 1 file changed, 1 insertion(+) create mode 100644 Misc/NEWS.d/next/Library/2026-05-28-00-00-00.gh-issue-150484.XxYyZz.rst diff --git a/Misc/NEWS.d/next/Library/2026-05-28-00-00-00.gh-issue-150484.XxYyZz.rst b/Misc/NEWS.d/next/Library/2026-05-28-00-00-00.gh-issue-150484.XxYyZz.rst new file mode 100644 index 000000000000000..522c70058ed29d7 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2026-05-28-00-00-00.gh-issue-150484.XxYyZz.rst @@ -0,0 +1 @@ +Fix :func:`unittest.mock.mock_open` ``__exit__`` raising ``TypeError`` when used with :class:`contextlib.ExitStack`.