quick question about Python on windows. I have a script that compiles a program (using an install rule), and then moves the build products to a remote destination over the network.
However, I keep getting WindowsError 5 Access Denied. All files are created from the script context, I have ownership and full control on all of them. The copy to the remote destination succeeds, but the failure is during the deletion process. If I try to delete or rename the file manually within windows, I get no errors. Just the shutil.move fails.
I'm thinking maybe the API is trying to delete the file when the network operation is not yet complete?
Any input is very appreciated.
try:
shutil.move(directory, destination)
except OSError:
print "Failed to move %s to %s." %(directory, destination)
raise
...
Traceback (most recent call last):
File "C:\WIP\BuildMachine\build_machine.py", line 176, in <module>
main()
File "C:\WIP\BuildMachine.hg\BuilderInstance.py", line 496, in deployVersion
shutil.move(directory, destination)
File "C:\Python27\lib\shutil.py", line 300, in move
rmtree(src)
File "C:\Python27\lib\shutil.py", line 252, in rmtree
onerror(os.remove, fullname, sys.exc_info())
File "C:\Python27\lib\shutil.py", line 250, in rmtree
os.remove(fullname)
WindowsError: [Error 5] Access is denied: '3_54_7__B_1\\Application_Release_Note.doc'
the problem with shutil.move
on windows is that it doesn't handle the case where:
If both conditions are met, shutil.move
cannot perform a os.rename
, it has to:
shutil
)To fix that, I made myself a copy of the shutil
module (under a different name) and added that line (for you it'll be right before line 250):
os.chmod(fullname,0o777) # <-- add that line
os.remove(fullname) # some versions have "unlink" instead
The rmtree
function has the same issue on Windows.
On Linux this doesn't happen because file delete permissions aren't handled at the file level but at the directory level. On windows, it doesn't work that way. Adding os.chmod
does the trick (even if it's a hack), and os.remove
succeeds (unless the file is open in Word or whatever)
Note that shutil
authors encourage you to copy & improve the functions. Also a note from the documentation of shutil.move
:
A lot more could be done here... A look at a mv.c shows a lot of the issues this implementation glosses over.
If you don't want to modify shutil
, you can run a recursive chmod
on the source files to make sure that shutil.move
will work, for instance like this:
for root, dirs, files in os.walk(path):
for f in dirs+files:
os.chmod(os.path.join(root, f), 0o777)
You could also use shutil.copytree
then a modified version of shutil.rmtree
(since you know that source & dest aren't on the same filesystem)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With