Skip to content

Commit

Permalink
[3.11] pythongh-79325: Fix recursion error in TemporaryDirectory clea…
Browse files Browse the repository at this point in the history
…nup on Windows (pythonGH-112762)

(cherry picked from commit b2923a6)

Co-authored-by: Serhiy Storchaka <storchaka@gmail.com>
  • Loading branch information
serhiy-storchaka committed Dec 7, 2023
1 parent 5585334 commit bd58973
Show file tree
Hide file tree
Showing 3 changed files with 21 additions and 2 deletions.
10 changes: 8 additions & 2 deletions Lib/tempfile.py
Original file line number Diff line number Diff line change
Expand Up @@ -876,9 +876,14 @@ def __init__(self, suffix=None, prefix=None, dir=None,
ignore_errors=self._ignore_cleanup_errors)

@classmethod
def _rmtree(cls, name, ignore_errors=False):
def _rmtree(cls, name, ignore_errors=False, repeated=False):
def onerror(func, path, exc_info):
if issubclass(exc_info[0], PermissionError):
if repeated and path == name:
if ignore_errors:
return
raise

try:
if path != name:
_resetperms(_os.path.dirname(path))
Expand Down Expand Up @@ -911,7 +916,8 @@ def onerror(func, path, exc_info):
if ignore_errors:
return
raise
cls._rmtree(path, ignore_errors=ignore_errors)
cls._rmtree(path, ignore_errors=ignore_errors,
repeated=(path == name))
except FileNotFoundError:
pass
elif issubclass(exc_info[0], FileNotFoundError):
Expand Down
11 changes: 11 additions & 0 deletions Lib/test/test_tempfile.py
Original file line number Diff line number Diff line change
Expand Up @@ -1543,6 +1543,17 @@ def test_explicit_cleanup_correct_error(self):
with self.assertRaises(PermissionError):
temp_dir.cleanup()

@unittest.skipUnless(os.name == "nt", "Only on Windows.")
def test_cleanup_with_used_directory(self):
with tempfile.TemporaryDirectory() as working_dir:
temp_dir = self.do_create(dir=working_dir)
subdir = os.path.join(temp_dir.name, "subdir")
os.mkdir(subdir)
with os_helper.change_cwd(subdir):
# Previously raised RecursionError on some OSes
# (e.g. Windows). See bpo-35144.
with self.assertRaises(PermissionError):
temp_dir.cleanup()

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

0 comments on commit bd58973

Please sign in to comment.