(entries, src, dst, symlinks, ignore, copy_function,
ignore_dangling_symlinks, dirs_exist_ok=False)
| 543 | return _ignore_patterns |
| 544 | |
| 545 | def _copytree(entries, src, dst, symlinks, ignore, copy_function, |
| 546 | ignore_dangling_symlinks, dirs_exist_ok=False): |
| 547 | if ignore is not None: |
| 548 | ignored_names = ignore(os.fspath(src), [x.name for x in entries]) |
| 549 | else: |
| 550 | ignored_names = () |
| 551 | |
| 552 | os.makedirs(dst, exist_ok=dirs_exist_ok) |
| 553 | errors = [] |
| 554 | use_srcentry = copy_function is copy2 or copy_function is copy |
| 555 | |
| 556 | for srcentry in entries: |
| 557 | if srcentry.name in ignored_names: |
| 558 | continue |
| 559 | srcname = os.path.join(src, srcentry.name) |
| 560 | dstname = os.path.join(dst, srcentry.name) |
| 561 | srcobj = srcentry if use_srcentry else srcname |
| 562 | try: |
| 563 | is_symlink = srcentry.is_symlink() |
| 564 | if is_symlink and os.name == 'nt': |
| 565 | # Special check for directory junctions, which appear as |
| 566 | # symlinks but we want to recurse. |
| 567 | lstat = srcentry.stat(follow_symlinks=False) |
| 568 | if lstat.st_reparse_tag == stat.IO_REPARSE_TAG_MOUNT_POINT: |
| 569 | is_symlink = False |
| 570 | if is_symlink: |
| 571 | linkto = os.readlink(srcname) |
| 572 | if symlinks: |
| 573 | # We can't just leave it to `copy_function` because legacy |
| 574 | # code with a custom `copy_function` may rely on copytree |
| 575 | # doing the right thing. |
| 576 | os.symlink(linkto, dstname) |
| 577 | copystat(srcobj, dstname, follow_symlinks=not symlinks) |
| 578 | else: |
| 579 | # ignore dangling symlink if the flag is on |
| 580 | if not os.path.exists(linkto) and ignore_dangling_symlinks: |
| 581 | continue |
| 582 | # otherwise let the copy occur. copy2 will raise an error |
| 583 | if srcentry.is_dir(): |
| 584 | copytree(srcobj, dstname, symlinks, ignore, |
| 585 | copy_function, ignore_dangling_symlinks, |
| 586 | dirs_exist_ok) |
| 587 | else: |
| 588 | copy_function(srcobj, dstname) |
| 589 | elif srcentry.is_dir(): |
| 590 | copytree(srcobj, dstname, symlinks, ignore, copy_function, |
| 591 | ignore_dangling_symlinks, dirs_exist_ok) |
| 592 | else: |
| 593 | # Will raise a SpecialFileError for unsupported file types |
| 594 | copy_function(srcobj, dstname) |
| 595 | # catch the Error from the recursive copytree so that we can |
| 596 | # continue with other files |
| 597 | except Error as err: |
| 598 | errors.extend(err.args[0]) |
| 599 | except OSError as why: |
| 600 | errors.append((srcname, dstname, str(why))) |
| 601 | try: |
| 602 | copystat(src, dst) |
no test coverage detected
searching dependent graphs…