22from contextlib import ExitStack , contextmanager
33from errno import EACCES
44from gc import collect
5+ from inspect import signature
56from os import name as os_name
67from pathlib import Path
78from stat import S_IEXEC , S_IREAD , S_IWRITE
@@ -610,14 +611,21 @@ def test_temp_delete_stdlib_temp_manager(tmp_path, monkeypatch):
610611
611612
612613@pytest .mark .skipif (os_name == 'nt' , reason = 'POSIX parent directory permission semantics do not apply on Windows' )
614+ @pytest .mark .skipif (
615+ 'repeated' not in signature (TemporaryDirectory ._rmtree ).parameters , # type: ignore[attr-defined] # private stdlib method is not present in typeshed.
616+ reason = 'Affected CPython tempfile cleanup retries this natural permission denial recursively' ,
617+ )
613618def test_temp_delete_stdlib_temp_manager_failure_is_logged_and_retryable_on_posix (tmp_path , monkeypatch , request ):
614619 """
615620 Verify that a real POSIX failure in ``TemporaryDirectory.cleanup()`` is logged and retryable.
616621
617622 The stdlib cleanup implementation may repair permissions on the temporary
618623 directory it owns before retrying deletion. Placing it in a separate
619624 read-only parent reliably blocks removal of that owned child without
620- asking the implementation under test to fake a cleanup failure.
625+ asking the implementation under test to fake a cleanup failure. Older
626+ CPython implementations recursively retry this exact denial until they
627+ raise ``RecursionError``; the accompanying decorator keeps this natural
628+ scenario on versions whose stdlib returns the filesystem error to throng.
621629 """
622630 temporary_root = tmp_path / 'stdlib-temporary-root'
623631 temporary_root .mkdir ()
@@ -644,13 +652,19 @@ def test_temp_delete_stdlib_temp_manager_failure_is_logged_and_retryable_on_posi
644652
645653
646654@pytest .mark .skipif (os_name != 'nt' , reason = 'Windows sharing violations are not available on POSIX' )
655+ @pytest .mark .skipif (
656+ 'repeated' not in signature (TemporaryDirectory ._rmtree ).parameters , # type: ignore[attr-defined] # private stdlib method is not present in typeshed.
657+ reason = 'Affected CPython tempfile cleanup retries this natural permission denial recursively' ,
658+ )
647659def test_temp_delete_stdlib_temp_manager_locked_windows_directory_raises_and_can_be_retried ():
648660 """
649661 Verify that a real Windows failure in ``TemporaryDirectory.cleanup()`` is logged and retryable.
650662
651663 An open directory handle without delete sharing prevents stdlib cleanup
652664 from removing its managed directory. Closing that handle makes the same
653- isolate deletable on a later attempt.
665+ isolate deletable on a later attempt. Older CPython implementations
666+ cannot be used for this natural failure test because their stdlib cleanup
667+ recursively retries the denial instead of returning it to throng.
654668 """
655669 logger = MemoryLogger ()
656670 isolate = TemporaryDirectoryThrong (logger = logger ).get_isolate ()
0 commit comments