Skip to content

On Windows, renaming a directory that was just created can fail with PermissionError: [WinError 5] Access denied #1780

@rmartin16

Description

@rmartin16

Describe the bug

Using os.rename() (or pathlib.Path.rename()) can fail on Windows if Briefcase does not have exclusive access to all files in the directory.

A common pattern Briefcase uses is to run shutil.unpack_archive() and rename the unpacked directory; for instance, Android cmdline-tools and Java's JDK. In between these two operations, a background process may acquire a handle on a file; for instance, a Windows file indexer or an antivirus scanner.

Modern Linux file systems are much more resilient to these types of conflicts; so, I would only expect to see this on Windows.

Steps to reproduce

import os
from pathlib import Path

Path("orig-dir-1").mkdir()
Path("orig-dir-1/orig-file").touch()
Path("orig-dir-1").rename("new-dir-1")
os.listdir("new-dir-1")

Path("orig-dir-2").mkdir()
Path("orig-dir-2/orig-file").touch()
Path("orig-dir-2/orig-file").open()
Path("orig-dir-2").rename("new-dir-2")
python
Python 3.11.3 (tags/v3.11.3:f3909b8, Apr  4 2023, 23:49:59) [MSC v.1934 64 bit (AMD64)] on win32
Type "help", "copyright", "credits" or "license" for more information.
>>> import os
>>> from pathlib import Path
>>>
>>> Path("orig-dir-1").mkdir()
>>> Path("orig-dir-1/orig-file").touch()
>>> Path("orig-dir-1").rename("new-dir-1")
WindowsPath('new-dir-1')
>>> os.listdir("new-dir-1")
['orig-file']
>>>
>>> Path("orig-dir-2").mkdir()
>>> Path("orig-dir-2/orig-file").touch()
>>> Path("orig-dir-2/orig-file").open()
<_io.TextIOWrapper name='orig-dir-2\\orig-file' mode='r' encoding='cp1252'>
>>> Path("orig-dir-2").rename("new-dir-2")
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "C:\Users\user\.pyenv\pyenv-win\versions\3.11.3\Lib\pathlib.py", line 1175, in rename
    os.rename(self, target)
PermissionError: [WinError 5] Access is denied: 'orig-dir-2' -> 'new-dir-2'
>>>

Expected behavior

Renaming these directories in the Briefcase cache should be successful.

Screenshots

No response

Environment

  • Operating System: Windows 11
  • Python version: 3.11.3
  • Software versions:
    • Briefcase: 0.3.18

Logs

No response

Additional context

Origin: beeware/beeware#348

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugA crash or error in behavior.windowsThe issue relates to Microsoft Windows support.

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions