From 03fbd1a323d85a59ef9adc18128dadfe78db6c58 Mon Sep 17 00:00:00 2001 From: Serhiy Storchaka Date: Tue, 21 Jul 2026 01:46:59 +0300 Subject: [PATCH] gh-154307: Fix TemporaryDirectory cleanup on DragonFly BSD (GH-154309) On DragonFly BSD, removing a file or directory with the UF_NOUNLINK flag fails with EISDIR (IsADirectoryError) instead of EPERM, so the cleanup did not reset the flags. Handle IsADirectoryError the same as PermissionError. (cherry picked from commit 1c1088b1da5a7484b7b04e90ccc47aa362e709eb) Co-authored-by: Serhiy Storchaka Co-authored-by: Claude Opus 4.8 (1M context) --- Lib/tempfile.py | 3 ++- .../Library/2026-07-21-01-13-39.gh-issue-154307.UNFKL4.rst | 3 +++ 2 files changed, 5 insertions(+), 1 deletion(-) create mode 100644 Misc/NEWS.d/next/Library/2026-07-21-01-13-39.gh-issue-154307.UNFKL4.rst diff --git a/Lib/tempfile.py b/Lib/tempfile.py index 609ef4877d18e2..cc9833125d2816 100644 --- a/Lib/tempfile.py +++ b/Lib/tempfile.py @@ -895,7 +895,8 @@ def __init__(self, suffix=None, prefix=None, dir=None, @classmethod def _rmtree(cls, name, ignore_errors=False, repeated=False): def onexc(func, path, exc): - if isinstance(exc, PermissionError): + # On DragonFly BSD, UF_NOUNLINK removal fails with EISDIR, not EPERM. + if isinstance(exc, (PermissionError, IsADirectoryError)): if repeated and path == name: if ignore_errors: return diff --git a/Misc/NEWS.d/next/Library/2026-07-21-01-13-39.gh-issue-154307.UNFKL4.rst b/Misc/NEWS.d/next/Library/2026-07-21-01-13-39.gh-issue-154307.UNFKL4.rst new file mode 100644 index 00000000000000..fdba0c2940f005 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2026-07-21-01-13-39.gh-issue-154307.UNFKL4.rst @@ -0,0 +1,3 @@ +Fix :meth:`tempfile.TemporaryDirectory.cleanup` on DragonFly BSD, where removing +a file with the ``UF_NOUNLINK`` flag failed with ``EISDIR`` instead of +``EPERM``.