| 914 | |
| 915 | @classmethod |
| 916 | def _rmtree(cls, name, ignore_errors=False, repeated=False): |
| 917 | def onexc(func, path, exc): |
| 918 | if isinstance(exc, PermissionError): |
| 919 | if repeated and path == name: |
| 920 | if ignore_errors: |
| 921 | return |
| 922 | raise |
| 923 | |
| 924 | try: |
| 925 | if path != name: |
| 926 | _resetperms(_os.path.dirname(path)) |
| 927 | _resetperms(path) |
| 928 | |
| 929 | try: |
| 930 | _os.unlink(path) |
| 931 | except IsADirectoryError: |
| 932 | cls._rmtree(path, ignore_errors=ignore_errors) |
| 933 | except PermissionError: |
| 934 | # The PermissionError handler was originally added for |
| 935 | # FreeBSD in directories, but it seems that it is raised |
| 936 | # on Windows too. |
| 937 | # bpo-43153: Calling _rmtree again may |
| 938 | # raise NotADirectoryError and mask the PermissionError. |
| 939 | # So we must re-raise the current PermissionError if |
| 940 | # path is not a directory. |
| 941 | if not _os.path.isdir(path) or _os.path.isjunction(path): |
| 942 | if ignore_errors: |
| 943 | return |
| 944 | raise |
| 945 | cls._rmtree(path, ignore_errors=ignore_errors, |
| 946 | repeated=(path == name)) |
| 947 | except FileNotFoundError: |
| 948 | pass |
| 949 | elif isinstance(exc, FileNotFoundError): |
| 950 | pass |
| 951 | else: |
| 952 | if not ignore_errors: |
| 953 | raise |
| 954 | |
| 955 | _shutil.rmtree(name, onexc=onexc) |
| 956 | |
| 957 | @classmethod |
| 958 | def _cleanup(cls, name, warn_message, ignore_errors=False, delete=True): |