Skip to content

TemporaryDirectory.__exit__ sometimes raises bad PermissionError #113009

Closed
@kfrydel

Description

@kfrydel

Bug report

TemporaryDirectory.__exit__ usually raises PermissionError if another process keeping a handle to a file in the tmp directory has just finished its execution.

Bug description:

Please consider the following block of code:

import multiprocessing
import os
import tempfile
import time


def _open_func(file_path):
    with open(file_path, "w"):
        time.sleep(1000)


def test():
    with tempfile.TemporaryDirectory(suffix="used_by_another_process") as dir_path:
        file_path = os.path.join(dir_path, "file_being_used")
        proc = multiprocessing.Process(target=_open_func, args=(file_path,))
        proc.start()
        while not os.path.exists(file_path):
            time.sleep(0.1)
        proc.terminate()
        proc.join()


if __name__ == "__main__":
    test()

Despite the child process being terminated and joined, the __exit__ method of TemporaryDirectory sometimes raises PermissionError:

Traceback (most recent call last):
  File "C:\Python\python.3.12.1\tools\Lib\shutil.py", line 634, in _rmtree_unsafe
    os.unlink(fullname)
PermissionError: [WinError 32] The process cannot access the file because it is being used by another process: 'C:\\Users\\kamil\\AppData\\Local\\Temp\\tmpvaou_oibused_by_another_process\\file_being_used'

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "C:\Users\kamil\tmp_test\tmpdir.py", line 24, in <module>
    test()
  File "C:\Users\kamil\tmp_test\tmpdir.py", line 13, in test
    with tempfile.TemporaryDirectory(suffix="used_by_another_process") as dir_path:
  File "C:\Python\python.3.12.1\tools\Lib\tempfile.py", line 946, in __exit__
    self.cleanup()
  File "C:\Python\python.3.12.1\tools\Lib\tempfile.py", line 950, in cleanup
    self._rmtree(self.name, ignore_errors=self._ignore_cleanup_errors)
  File "C:\Python\python.3.12.1\tools\Lib\tempfile.py", line 930, in _rmtree
    _shutil.rmtree(name, onexc=onexc)
  File "C:\Python\python.3.12.1\tools\Lib\shutil.py", line 808, in rmtree
    return _rmtree_unsafe(path, onexc)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "C:\Python\python.3.12.1\tools\Lib\shutil.py", line 636, in _rmtree_unsafe
    onexc(os.unlink, fullname, err)
  File "C:\Python\python.3.12.1\tools\Lib\tempfile.py", line 905, in onexc
    _os.unlink(path)
PermissionError: [WinError 32] The process cannot access the file because it is being used by another process: 'C:\\Users\\kamil\\AppData\\Local\\Temp\\tmpvaou_oibused_by_another_process\\file_being_used'

It does not reproduce in 100% but most executions fail. I can reproduce it only using Python 3.12.1. It does not happen to me on 3.12.0 or 3.11. It seems to be a regression in the last release.
With some small sleep after the proc.join() it stops reproducing so it looks like a kind of race condition.

The Windows version I use is:
Edition: Windows 10 Enterprise
Version: 21H2
OS build: 19044.3693

CPython versions tested on:

3.12

Operating systems tested on:

Windows

Linked PRs

Metadata

Metadata

Assignees

No one assigned

    Labels

    3.11only security fixes3.12only security fixes3.13bugs and security fixesOS-windowsstdlibPython modules in the Lib dirtype-bugAn unexpected behavior, bug, or error

    Projects

    Status

    Done

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions