Skip to content

Commit a18201b

Browse files
[3.11] gh-79325: Fix recursion error in TemporaryDirectory cleanup on Windows (GH-112762) (GH-112848)
(cherry picked from commit b2923a6)
1 parent 5585334 commit a18201b

File tree

3 files changed

+21
-2
lines changed

3 files changed

+21
-2
lines changed

Lib/tempfile.py

+8-2
Original file line numberDiff line numberDiff line change
@@ -876,9 +876,14 @@ def __init__(self, suffix=None, prefix=None, dir=None,
876876
ignore_errors=self._ignore_cleanup_errors)
877877

878878
@classmethod
879-
def _rmtree(cls, name, ignore_errors=False):
879+
def _rmtree(cls, name, ignore_errors=False, repeated=False):
880880
def onerror(func, path, exc_info):
881881
if issubclass(exc_info[0], PermissionError):
882+
if repeated and path == name:
883+
if ignore_errors:
884+
return
885+
raise
886+
882887
try:
883888
if path != name:
884889
_resetperms(_os.path.dirname(path))
@@ -911,7 +916,8 @@ def onerror(func, path, exc_info):
911916
if ignore_errors:
912917
return
913918
raise
914-
cls._rmtree(path, ignore_errors=ignore_errors)
919+
cls._rmtree(path, ignore_errors=ignore_errors,
920+
repeated=(path == name))
915921
except FileNotFoundError:
916922
pass
917923
elif issubclass(exc_info[0], FileNotFoundError):

Lib/test/test_tempfile.py

+11
Original file line numberDiff line numberDiff line change
@@ -1543,6 +1543,17 @@ def test_explicit_cleanup_correct_error(self):
15431543
with self.assertRaises(PermissionError):
15441544
temp_dir.cleanup()
15451545

1546+
@unittest.skipUnless(os.name == "nt", "Only on Windows.")
1547+
def test_cleanup_with_used_directory(self):
1548+
with tempfile.TemporaryDirectory() as working_dir:
1549+
temp_dir = self.do_create(dir=working_dir)
1550+
subdir = os.path.join(temp_dir.name, "subdir")
1551+
os.mkdir(subdir)
1552+
with os_helper.change_cwd(subdir):
1553+
# Previously raised RecursionError on some OSes
1554+
# (e.g. Windows). See bpo-35144.
1555+
with self.assertRaises(PermissionError):
1556+
temp_dir.cleanup()
15461557

15471558
@os_helper.skip_unless_symlink
15481559
def test_cleanup_with_symlink_to_a_directory(self):
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
Fix an infinite recursion error in :func:`tempfile.TemporaryDirectory`
2+
cleanup on Windows.

0 commit comments

Comments
 (0)