Pulimon
Pulimon

Reputation: 1816

Handling exception while using shutil.copytree to copy a file where permission is denied

Consider the following directory tree

Work--->subdir1--->File1
    |         |
    |         ---->File2
    |
    -->subdir2--->File3

There exists another similar directory tree

Gold--->subdir1--->File1
    |         |
    |         ---->File2
    |
    -->subdir2--->File3

I have to write a script to copy the Work directory to another location. I have been using shutil.copytree for the same.

The problem is, at times (but not always) I may not have permission to access some files, say, File2 in the Work directory, and will get the following error:

Traceback (most recent call last):
File "C:\Script.py", line 81, in <module>
shutil.copytree(source_loc,dest_loc)
File "C:\Python32\lib\shutil.py", line 239, in copytree
   raise Error(errors)
   shutil.Error: [('C:\\Work\\subdir1\\File2', 
   'C:\\Dest\\subdir1\\File2', 
"[Errno 13] Permission denied: 'C:\\Work\\subdir1\\File2'")]

In such situations, I will have to copy those corresponding files from the Gold directory. Is there a way in which I can automate the copying of the corresponding files from Gold directory through an exception? Say something like:

try:
   shutil.copytree(r'C:\Work',r'C:\Dest')
except:
   << Copy Inaccessible Files from Gold >>

I was initially thinking about using os.walk, to copy files individually. This way whenever I encounter an exception for a particular file, I will be able to copy that corresponding file from Gold. Is there a better way?

Upvotes: 2

Views: 12362

Answers (2)

mata
mata

Reputation: 69042

Yes, using os.walk would be the correct way to go.

copytree is limited. It's not designed as a sophisticated copy tool, and it also says so in its docstring:

XXX Consider this example code rather than the ultimate tool.

(This note was removed in Python 3)

Upvotes: 1

spinlok
spinlok

Reputation: 3661

You can get the list of files that failed to copy from shutil.Error. From reading the source, shutil.Error contains (src, dst, why) triplets. You can do something like:

try:
    shutil.copytree(srcdir, dstdir)
except shutil.Error, exc:
    errors = exc.args[0]
    for error in errors:
        src, dst, msg = error
        # Get the path to the file in Gold dir here from src
        shutil.copy2(goldsrc, dst)

Upvotes: 3

Related Questions