How do I copy an entire directory of files into an existing directory using Python?

Here's a solution that's part of the standard library:

from distutils.dir_util import copy_tree
copy_tree("/a/b/c", "/x/y/z")

See this similar question.

Copy directory contents into a directory with python

  • Reference - https://docs.python.org/3/distutils/apiref.html#distutils.dir_util.copy_tree

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:

  • it doesn't honor symlinks and ignore parameters for the root directory of the src tree;
  • it doesn't raise shutil.Error for errors at the root level of src;
  • in case of errors during copying of a subtree, it will raise shutil.Error for that subtree instead of trying to copy other subtrees and raising single combined shutil.Error.

In slight improvement on atzz's answer to the function where the above function always tries to copy the files from source to destination.

def copytree(src, dst, symlinks=False, ignore=None):
    if not os.path.exists(dst):
        os.makedirs(dst)
    for item in os.listdir(src):
        s = os.path.join(src, item)
        d = os.path.join(dst, item)
        if os.path.isdir(s):
            copytree(s, d, symlinks, ignore)
        else:
            if not os.path.exists(d) or os.stat(s).st_mtime - os.stat(d).st_mtime > 1:
                shutil.copy2(s, d)

In my above implementation

  • Creating the output directory if not already exists
  • Doing the copy directory by recursively calling my own method.
  • When we come to actually copying the file I check if the file is modified then only we should copy.

I am using above function along with scons build. It helped me a lot as every time when I compile I may not need to copy entire set of files.. but only the files which are modified.