shutil.rmtree doesn't work with Windows Library
file, python, shutil, windows
Solution
That's a cross-platform consistency issue. You've copied files/dirs with `readonly` attribute. On the first time "`dest`" not exists, thus rmtree method is not performed. However, when you try run "overwrite" function we can notice that "dest" location exists (and its subtree) but it was copied with readonly access. So here we got a problem. In order to "fix" issue, you must provide a handler for onerror parameter of shutil.rmtree. As long as your problem is regarding readonly issues the workaround is somewhat like this:
def readonly_handler(func, path, execinfo):
os.chmod(path, 128) #or os.chmod(path, stat.S_IWRITE) from "stat" module
func(path)
As you can see in the python doc onerror must be a callable that accepts three parameters: function, path, and excinfo. For further info, read the docs.
def overwrite(src, dest):
if(not os.path.exists(src)):
print(src, "does not exist, so nothing may be copied.")
return
if(os.path.exists(dest)):
shutil.rmtree(dest, onerror=readonly_handler)
shutil.copytree(src, dest)
print(dest, "overwritten with data from", src)
print("")
Of course, this handler is simple and specific but if other errors occur, new exceptions will be raised and this handler may not be able to fix them!
Note: Tim Golden (Python for windows contributor) has been patching the shutil.rmtree issue and it seems it will be resolved in Python 3.5 (see issue 19643).
Problem
So I'm building a simple script that backs up certain documents to my second hard-drive (you never know what could happen!). So, I used the `shutil.copytree` function to replicate my data on the second drive. It works beautifully, and that is not the problem. I use the `shutil.rmtree` function to remove the tree if the destination already exists. I'll show you my code: ``` import shutil import os def overwrite(src, dest): if(not os.path.exists(src)): print(src, "does not exist, so nothing may be copied.") return if(os.path.exists(dest)): shutil.rmtree(dest) shutil.copytree(src, dest) print(dest, "overwritten with data from", src) print("") overwrite(r"C:\Users\Centurion\Dropbox\Documents", r"D:\Backup\Dropbox Documents") overwrite(r"C:\Users\Centurion\Pictures", r"D:\Backup\All Pictures") print("Press ENTER to continue...") input() ``` As you can see, a simple script. Now, when I run the script for the first time, everything is fine. Pictures and Documents copy over to my `D:` drive just fine. However, when I run for the second time, this is my output: ``` C:\Users\Centurion\Programming\Python>python cpdocsnpics.py D:\Backup\Dropbox Documents overwritten with data from C:\Users\Centurion\Dropbox\Documents Traceback (most recent call last): File "cpdocsnpics.py", line 17, in <module> overwrite(r"C:\Users\Centurion\Pictures", r"D:\Backup\All Pictures") File "cpdocsnpics.py", line 10, in overwrite shutil.rmtree(dest) File "C:\Python34\lib\shutil.py", line 477, in rmtree return _rmtree_unsafe(path, onerror) File "C:\Python34\lib\shutil.py", line 376, in _rmtree_unsafe onerror(os.rmdir, path, sys.exc_info()) File "C:\Python34\lib\shutil.py", line 374, in _rmtree_unsafe os.rmdir(path) PermissionError: [WinError 5] Access is denied: 'D:\\Backup\\All Pictures' ``` The error only happens when I copy `Pictures` after the first time; I'm assuming it has something to do with being a Library. What should I do?