diff -r c829ad672920 Doc/library/shutil.rst --- a/Doc/library/shutil.rst Mon Mar 03 20:06:37 2014 -0800 +++ b/Doc/library/shutil.rst Mon Mar 03 21:18:13 2014 -0800 @@ -191,14 +191,13 @@ match one of the glob-style *patterns* provided. See the example below. -.. function:: copytree(src, dst, symlinks=False, ignore=None, copy_function=copy2, ignore_dangling_symlinks=False) +.. function:: copytree(src, dst, symlinks=False, ignore=None, copy_function=copy2, ignore_dangling_symlinks=False, exist_ok=False) Recursively copy an entire directory tree rooted at *src*, returning the destination directory. The destination - directory, named by *dst*, must not already exist; it will be created as - well as missing parent directories. Permissions and times of directories - are copied with :func:`copystat`, individual files are copied using - :func:`shutil.copy2`. + directory will be created as well as missing parent directories. Permissions + and times of directories are copied with :func:`copystat`, individual files + are copied using :func:`shutil.copy2`. If *symlinks* is true, symbolic links in the source tree are represented as symbolic links in the new tree and the metadata of the original links will @@ -229,6 +228,12 @@ as arguments. By default, :func:`shutil.copy2` is used, but any function that supports the same signature (like :func:`shutil.copy`) can be used. + If *exist_ok* is ``False`` (the default), an :exc:`OSError` is raised if + the target directory already exists. If *exist_ok* is ``True`` an + :exc:`OSError` is still raised if the umask-masked *mode* is different from + the existing mode, on systems where the mode is used. :exc:`OSError` will + also be raised if the directory creation fails. + .. versionchanged:: 3.3 Copy metadata when *symlinks* is false. Now returns *dst*. diff -r c829ad672920 Lib/shutil.py --- a/Lib/shutil.py Mon Mar 03 20:06:37 2014 -0800 +++ b/Lib/shutil.py Mon Mar 03 21:18:13 2014 -0800 @@ -258,7 +258,7 @@ return _ignore_patterns def copytree(src, dst, symlinks=False, ignore=None, copy_function=copy2, - ignore_dangling_symlinks=False): + ignore_dangling_symlinks=False, exist_ok=False): """Recursively copy a directory tree. The destination directory must not already exist. @@ -299,7 +299,7 @@ else: ignored_names = set() - os.makedirs(dst) + os.makedirs(dst, exist_ok=exist_ok) errors = [] for name in names: if name in ignored_names: