@@ -432,13 +432,13 @@ def _ignore_patterns(path, names):
432432 return _ignore_patterns
433433
434434def _copytree (entries , src , dst , symlinks , ignore , copy_function ,
435- ignore_dangling_symlinks ):
435+ ignore_dangling_symlinks , dirs_exist_ok = False ):
436436 if ignore is not None :
437437 ignored_names = ignore (src , set (os .listdir (src )))
438438 else :
439439 ignored_names = set ()
440440
441- os .makedirs (dst )
441+ os .makedirs (dst , exist_ok = dirs_exist_ok )
442442 errors = []
443443 use_srcentry = copy_function is copy2 or copy_function is copy
444444
@@ -461,14 +461,15 @@ def _copytree(entries, src, dst, symlinks, ignore, copy_function,
461461 # ignore dangling symlink if the flag is on
462462 if not os .path .exists (linkto ) and ignore_dangling_symlinks :
463463 continue
464- # otherwise let the copy occurs . copy2 will raise an error
464+ # otherwise let the copy occur . copy2 will raise an error
465465 if srcentry .is_dir ():
466466 copytree (srcobj , dstname , symlinks , ignore ,
467- copy_function )
467+ copy_function , dirs_exist_ok = dirs_exist_ok )
468468 else :
469469 copy_function (srcobj , dstname )
470470 elif srcentry .is_dir ():
471- copytree (srcobj , dstname , symlinks , ignore , copy_function )
471+ copytree (srcobj , dstname , symlinks , ignore , copy_function ,
472+ dirs_exist_ok = dirs_exist_ok )
472473 else :
473474 # Will raise a SpecialFileError for unsupported file types
474475 copy_function (srcentry , dstname )
@@ -489,10 +490,12 @@ def _copytree(entries, src, dst, symlinks, ignore, copy_function,
489490 return dst
490491
491492def copytree (src , dst , symlinks = False , ignore = None , copy_function = copy2 ,
492- ignore_dangling_symlinks = False ):
493- """Recursively copy a directory tree.
493+ ignore_dangling_symlinks = False , dirs_exist_ok = False ):
494+ """Recursively copy a directory tree and return the destination directory.
495+
496+ dirs_exist_ok dictates whether to raise an exception in case dst or any
497+ missing parent directory already exists.
494498
495- The destination directory must not already exist.
496499 If exception(s) occur, an Error is raised with a list of reasons.
497500
498501 If the optional symlinks flag is true, symbolic links in the
@@ -527,7 +530,8 @@ def copytree(src, dst, symlinks=False, ignore=None, copy_function=copy2,
527530 with os .scandir (src ) as entries :
528531 return _copytree (entries = entries , src = src , dst = dst , symlinks = symlinks ,
529532 ignore = ignore , copy_function = copy_function ,
530- ignore_dangling_symlinks = ignore_dangling_symlinks )
533+ ignore_dangling_symlinks = ignore_dangling_symlinks ,
534+ dirs_exist_ok = dirs_exist_ok )
531535
532536# version vulnerable to race conditions
533537def _rmtree_unsafe (path , onerror ):
0 commit comments