Recursively delete a directory tree. If dir_fd is not None, it should be a file descriptor open to a directory; path will then be relative to that directory. dir_fd may not be implemented on your platform. If it is unavailable, using it will raise a NotImplementedError.
(path, ignore_errors=False, onerror=None, *, dir_fd=None)
| 708 | os.stat in os.supports_follow_symlinks) |
| 709 | |
| 710 | def rmtree(path, ignore_errors=False, onerror=None, *, dir_fd=None): |
| 711 | """Recursively delete a directory tree. |
| 712 | |
| 713 | If dir_fd is not None, it should be a file descriptor open to a directory; |
| 714 | path will then be relative to that directory. |
| 715 | dir_fd may not be implemented on your platform. |
| 716 | If it is unavailable, using it will raise a NotImplementedError. |
| 717 | |
| 718 | If ignore_errors is set, errors are ignored; otherwise, if onerror |
| 719 | is set, it is called to handle the error with arguments (func, |
| 720 | path, exc_info) where func is platform and implementation dependent; |
| 721 | path is the argument to that function that caused it to fail; and |
| 722 | exc_info is a tuple returned by sys.exc_info(). If ignore_errors |
| 723 | is false and onerror is None, an exception is raised. |
| 724 | |
| 725 | """ |
| 726 | sys.audit("shutil.rmtree", path, dir_fd) |
| 727 | if ignore_errors: |
| 728 | def onerror(*args): |
| 729 | pass |
| 730 | elif onerror is None: |
| 731 | def onerror(*args): |
| 732 | raise |
| 733 | if _use_fd_functions: |
| 734 | # While the unsafe rmtree works fine on bytes, the fd based does not. |
| 735 | if isinstance(path, bytes): |
| 736 | path = os.fsdecode(path) |
| 737 | # Note: To guard against symlink races, we use the standard |
| 738 | # lstat()/open()/fstat() trick. |
| 739 | try: |
| 740 | orig_st = os.lstat(path, dir_fd=dir_fd) |
| 741 | except Exception: |
| 742 | onerror(os.lstat, path, sys.exc_info()) |
| 743 | return |
| 744 | try: |
| 745 | fd = os.open(path, os.O_RDONLY | os.O_NONBLOCK, dir_fd=dir_fd) |
| 746 | fd_closed = False |
| 747 | except Exception: |
| 748 | onerror(os.open, path, sys.exc_info()) |
| 749 | return |
| 750 | try: |
| 751 | if os.path.samestat(orig_st, os.fstat(fd)): |
| 752 | _rmtree_safe_fd(fd, path, onerror) |
| 753 | try: |
| 754 | os.close(fd) |
| 755 | except OSError: |
| 756 | # close() should not be retried after an error. |
| 757 | fd_closed = True |
| 758 | onerror(os.close, path, sys.exc_info()) |
| 759 | fd_closed = True |
| 760 | try: |
| 761 | os.rmdir(path, dir_fd=dir_fd) |
| 762 | except OSError: |
| 763 | onerror(os.rmdir, path, sys.exc_info()) |
| 764 | else: |
| 765 | try: |
| 766 | # symlinks to directories are forbidden, see bug #1669 |
| 767 | raise OSError("Cannot call rmtree on a symbolic link") |
no test coverage detected