Eryk Sun <[email protected]> added the comment:
The directory probably has the "readonly" attribute set. The documentation
includes a basic remove_readonly error handler for rmtree [1]:
import os, stat
import shutil
def remove_readonly(func, path, _):
"Clear the readonly bit and reattempt the removal"
os.chmod(path, stat.S_IWRITE)
func(path)
shutil.rmtree(directory, onerror=remove_readonly)
That the readonly attribute prevents unlinking a directory is not particularly
useful because a directory has to be empty anyway in order to unlink it. This
is in contrast to the "immutable" file attribute in Linux, which prevents any
modification of a directory, such as linking or unlinking files in it. Windows
inherits its comparatively simplistic behavior for readonly directories from
MS-DOS.
Since setting a directory as readonly is practically useless, the Windows shell
reuses this attribute to indicate a customized folder [2]. If a directory is
flagged readonly, the shell checks for and reads a "desktop.ini" file in it
that can set a custom name, icon, tooltip, etc. Given you're copying a folder
that contains a desktop.ini file, it's very likely that the readonly attribute
is set.
shutil.copytree will copy the readonly attribute to the destination directory
via os.chmod. This is the only file attribute that gets copied (e.g. hidden and
system aren't handled), due to a hack in the Windows CRT that conflates the
readonly file attribute as a write 'permission' for chmod() and stat(). (Being
readonly is an attribute of the file or directory, not a granted permission.
os.access is the correct function to take both attributes and permissions into
account, not os.stat.) Python inherits the CRT behavior in its own
implementation of os.chmod and os.stat in Windows. It does so as an accident of
history, not because it's justified.
[1] https://docs.python.org/3/library/shutil.html#rmtree-example
[2]
https://docs.microsoft.com/en-us/windows/win32/shell/how-to-customize-folders-with-desktop-ini
----------
_______________________________________
Python tracker <[email protected]>
<https://bugs.python.org/issue38868>
_______________________________________
_______________________________________________
Python-bugs-list mailing list
Unsubscribe:
https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com