Run the following code from a directory that contains a directory named bar
(containing one or more files) and a directory named baz
(also containing one or more files). Make sure there is not a directory named foo
.
import shutil
shutil.copytree('bar', 'foo')
shutil.copytree('baz', 'foo')
It will fail with:
$ python copytree_test.py
Traceback (most recent call last):
File "copytree_test.py", line 5, in <module>
shutil.copytree('baz', 'foo')
File "/System/Library/Frameworks/Python.framework/Versions/2.5/lib/python2.5/shutil.py", line 110, in copytree
File "/System/Library/Frameworks/Python.framework/Versions/2.5/lib/python2.5/os.py", line 172, in makedirs
OSError: [Errno 17] File exists: 'foo'
I want this to work the same way as if I had typed:
$ mkdir foo
$ cp bar/* foo/
$ cp baz/* foo/
Do I need to use shutil.copy()
to copy each file in baz
into foo
? (After I've already copied the contents of 'bar' into 'foo' with shutil.copytree()
?) Or is there an easier/better way?
This limitation of the standard shutil.copytree
seems arbitrary and annoying. Workaround:
import os, shutil
def copytree(src, dst, symlinks=False, ignore=None):
for item in os.listdir(src):
s = os.path.join(src, item)
d = os.path.join(dst, item)
if os.path.isdir(s):
shutil.copytree(s, d, symlinks, ignore)
else:
shutil.copy2(s, d)
Note that it's not entirely consistent with the standard copytree
:
symlinks
and ignore
parameters for the root directory of the src
tree;shutil.Error
for errors at the root level of src
;shutil.Error
for that subtree instead of trying to copy other subtrees and raising single combined shutil.Error
.