(func, path, exc_info)
| 878 | @classmethod |
| 879 | def _rmtree(cls, name, ignore_errors=False, repeated=False): |
| 880 | def onerror(func, path, exc_info): |
| 881 | if issubclass(exc_info[0], PermissionError): |
| 882 | if repeated and path == name: |
| 883 | if ignore_errors: |
| 884 | return |
| 885 | raise |
| 886 | |
| 887 | try: |
| 888 | if path != name: |
| 889 | _resetperms(_os.path.dirname(path)) |
| 890 | _resetperms(path) |
| 891 | |
| 892 | try: |
| 893 | _os.unlink(path) |
| 894 | except IsADirectoryError: |
| 895 | cls._rmtree(path, ignore_errors=ignore_errors) |
| 896 | except PermissionError: |
| 897 | # The PermissionError handler was originally added for |
| 898 | # FreeBSD in directories, but it seems that it is raised |
| 899 | # on Windows too. |
| 900 | # bpo-43153: Calling _rmtree again may |
| 901 | # raise NotADirectoryError and mask the PermissionError. |
| 902 | # So we must re-raise the current PermissionError if |
| 903 | # path is not a directory. |
| 904 | try: |
| 905 | st = _os.lstat(path) |
| 906 | except OSError: |
| 907 | if ignore_errors: |
| 908 | return |
| 909 | raise |
| 910 | if (_stat.S_ISLNK(st.st_mode) or |
| 911 | not _stat.S_ISDIR(st.st_mode) or |
| 912 | (hasattr(st, 'st_file_attributes') and |
| 913 | st.st_file_attributes & _stat.FILE_ATTRIBUTE_REPARSE_POINT and |
| 914 | st.st_reparse_tag == _stat.IO_REPARSE_TAG_MOUNT_POINT) |
| 915 | ): |
| 916 | if ignore_errors: |
| 917 | return |
| 918 | raise |
| 919 | cls._rmtree(path, ignore_errors=ignore_errors, |
| 920 | repeated=(path == name)) |
| 921 | except FileNotFoundError: |
| 922 | pass |
| 923 | elif issubclass(exc_info[0], FileNotFoundError): |
| 924 | pass |
| 925 | else: |
| 926 | if not ignore_errors: |
| 927 | raise |
| 928 | |
| 929 | _shutil.rmtree(name, onerror=onerror) |
| 930 |
nothing calls this directly
no test coverage detected