From a7b706abf3aea1dd1d61ca7035e76b022eea5102 Mon Sep 17 00:00:00 2001 From: ImFeH2 Date: Mon, 1 Jun 2026 16:20:51 +0800 Subject: [PATCH] fix: respect ignored tempfile cleanup errors --- Lib/tempfile.py | 11 +++++-- Lib/test/test_tempfile.py | 31 +++++++++++++++++++ ...-00.gh-issue-135812.TemporaryDirectory.rst | 3 ++ 3 files changed, 42 insertions(+), 3 deletions(-) create mode 100644 Misc/NEWS.d/next/Library/2026-06-01-16-05-00.gh-issue-135812.TemporaryDirectory.rst diff --git a/Lib/tempfile.py b/Lib/tempfile.py index 6dac9ab3c41717..7b85cd74d1e92c 100644 --- a/Lib/tempfile.py +++ b/Lib/tempfile.py @@ -922,9 +922,14 @@ def onexc(func, path, exc): raise try: - if path != name: - _resetperms(_os.path.dirname(path)) - _resetperms(path) + try: + if path != name: + _resetperms(_os.path.dirname(path)) + _resetperms(path) + except PermissionError: + if ignore_errors: + return + raise try: _os.unlink(path) diff --git a/Lib/test/test_tempfile.py b/Lib/test/test_tempfile.py index 0e00ff1d0cc366..6912d3196cc9fc 100644 --- a/Lib/test/test_tempfile.py +++ b/Lib/test/test_tempfile.py @@ -1705,6 +1705,37 @@ def test_explicit_cleanup_ignore_errors(self): temp_path.exists(), f"TemporaryDirectory {temp_path!s} exists after cleanup") + def test_explicit_cleanup_ignore_errors_resetperms(self): + with tempfile.TemporaryDirectory() as working_dir: + temp_dir = self.do_create( + dir=working_dir, ignore_cleanup_errors=True) + + def fake_rmtree(path, onexc): + onexc(os.open, path, PermissionError()) + + def fake_resetperms(path): + raise PermissionError(path) + + with support.swap_attr(tempfile._shutil, "rmtree", fake_rmtree), \ + support.swap_attr(tempfile, "_resetperms", fake_resetperms): + temp_dir.cleanup() + + def test_explicit_cleanup_resetperms_error(self): + with tempfile.TemporaryDirectory() as working_dir: + temp_dir = self.do_create(dir=working_dir) + self.addCleanup(temp_dir.cleanup) + + def fake_rmtree(path, onexc): + onexc(os.open, path, PermissionError()) + + def fake_resetperms(path): + raise PermissionError(path) + + with support.swap_attr(tempfile._shutil, "rmtree", fake_rmtree), \ + support.swap_attr(tempfile, "_resetperms", fake_resetperms): + with self.assertRaises(PermissionError): + temp_dir.cleanup() + @unittest.skipUnless(os.name == "nt", "Only on Windows.") def test_explicit_cleanup_correct_error(self): with tempfile.TemporaryDirectory() as working_dir: diff --git a/Misc/NEWS.d/next/Library/2026-06-01-16-05-00.gh-issue-135812.TemporaryDirectory.rst b/Misc/NEWS.d/next/Library/2026-06-01-16-05-00.gh-issue-135812.TemporaryDirectory.rst new file mode 100644 index 00000000000000..e519834423f5e2 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2026-06-01-16-05-00.gh-issue-135812.TemporaryDirectory.rst @@ -0,0 +1,3 @@ +Fix :class:`tempfile.TemporaryDirectory` so that +``ignore_cleanup_errors=True`` also ignores cleanup errors raised while +resetting permissions.