File tree 3 files changed +41
-2
lines changed
3 files changed +41
-2
lines changed Original file line number Diff line number Diff line change 41
41
import io as _io
42
42
import os as _os
43
43
import shutil as _shutil
44
+ import stat as _stat
44
45
import errno as _errno
45
46
from random import Random as _Random
46
47
import sys as _sys
@@ -876,8 +877,31 @@ def resetperms(path):
876
877
877
878
try :
878
879
_os .unlink (path )
879
- # PermissionError is raised on FreeBSD for directories
880
- except (IsADirectoryError , PermissionError ):
880
+ except IsADirectoryError :
881
+ cls ._rmtree (path , ignore_errors = ignore_errors )
882
+ except PermissionError :
883
+ # The PermissionError handler was originally added for
884
+ # FreeBSD in directories, but it seems that it is raised
885
+ # on Windows too.
886
+ # bpo-43153: Calling _rmtree again may
887
+ # raise NotADirectoryError and mask the PermissionError.
888
+ # So we must re-raise the current PermissionError if
889
+ # path is not a directory.
890
+ try :
891
+ st = _os .lstat (path )
892
+ except OSError :
893
+ if ignore_errors :
894
+ return
895
+ raise
896
+ if (_stat .S_ISLNK (st .st_mode ) or
897
+ not _stat .S_ISDIR (st .st_mode ) or
898
+ (hasattr (st , 'st_file_attributes' ) and
899
+ st .st_file_attributes & _stat .FILE_ATTRIBUTE_REPARSE_POINT and
900
+ st .st_reparse_tag == _stat .IO_REPARSE_TAG_MOUNT_POINT )
901
+ ):
902
+ if ignore_errors :
903
+ return
904
+ raise
881
905
cls ._rmtree (path , ignore_errors = ignore_errors )
882
906
except FileNotFoundError :
883
907
pass
Original file line number Diff line number Diff line change @@ -1533,6 +1533,17 @@ def test_explict_cleanup_ignore_errors(self):
1533
1533
temp_path .exists (),
1534
1534
f"TemporaryDirectory { temp_path !s} exists after cleanup" )
1535
1535
1536
+ @unittest .skipUnless (os .name == "nt" , "Only on Windows." )
1537
+ def test_explicit_cleanup_correct_error (self ):
1538
+ with tempfile .TemporaryDirectory () as working_dir :
1539
+ temp_dir = self .do_create (dir = working_dir )
1540
+ with open (os .path .join (temp_dir .name , "example.txt" ), 'wb' ):
1541
+ # Previously raised NotADirectoryError on some OSes
1542
+ # (e.g. Windows). See bpo-43153.
1543
+ with self .assertRaises (PermissionError ):
1544
+ temp_dir .cleanup ()
1545
+
1546
+
1536
1547
@os_helper .skip_unless_symlink
1537
1548
def test_cleanup_with_symlink_to_a_directory (self ):
1538
1549
# cleanup() should not follow symlinks to directories (issue #12464)
Original file line number Diff line number Diff line change
1
+ On Windows, ``tempfile.TemporaryDirectory `` previously masked a
2
+ ``PermissionError `` with ``NotADirectoryError `` during directory cleanup. It
3
+ now correctly raises ``PermissionError `` if errors are not ignored. Patch by
4
+ Andrei Kulakov and Ken Jin.
You can’t perform that action at this time.
0 commit comments