@@ -590,30 +590,30 @@ def copytree(src, dst, symlinks=False, ignore=None, copy_function=copy2,
590
590
dirs_exist_ok = dirs_exist_ok )
591
591
592
592
if hasattr (os .stat_result , 'st_file_attributes' ):
593
- def _rmtree_islink (path ):
594
- try :
595
- st = os .lstat (path )
596
- return (stat .S_ISLNK (st .st_mode ) or
597
- (st .st_file_attributes & stat .FILE_ATTRIBUTE_REPARSE_POINT
598
- and st .st_reparse_tag == stat .IO_REPARSE_TAG_MOUNT_POINT ))
599
- except OSError :
600
- return False
593
+ def _rmtree_islink (st ):
594
+ return (stat .S_ISLNK (st .st_mode ) or
595
+ (st .st_file_attributes & stat .FILE_ATTRIBUTE_REPARSE_POINT
596
+ and st .st_reparse_tag == stat .IO_REPARSE_TAG_MOUNT_POINT ))
601
597
else :
602
- def _rmtree_islink (path ):
603
- return os . path . islink ( path )
598
+ def _rmtree_islink (st ):
599
+ return stat . S_ISLNK ( st . st_mode )
604
600
605
601
# version vulnerable to race conditions
606
602
def _rmtree_unsafe (path , onexc ):
607
603
try :
608
604
with os .scandir (path ) as scandir_it :
609
605
entries = list (scandir_it )
606
+ except FileNotFoundError :
607
+ return
610
608
except OSError as err :
611
609
onexc (os .scandir , path , err )
612
610
entries = []
613
611
for entry in entries :
614
612
fullname = entry .path
615
613
try :
616
614
is_dir = entry .is_dir (follow_symlinks = False )
615
+ except FileNotFoundError :
616
+ continue
617
617
except OSError :
618
618
is_dir = False
619
619
@@ -624,17 +624,23 @@ def _rmtree_unsafe(path, onexc):
624
624
# a directory with a symlink after the call to
625
625
# os.scandir or entry.is_dir above.
626
626
raise OSError ("Cannot call rmtree on a symbolic link" )
627
+ except FileNotFoundError :
628
+ continue
627
629
except OSError as err :
628
630
onexc (os .path .islink , fullname , err )
629
631
continue
630
632
_rmtree_unsafe (fullname , onexc )
631
633
else :
632
634
try :
633
635
os .unlink (fullname )
636
+ except FileNotFoundError :
637
+ continue
634
638
except OSError as err :
635
639
onexc (os .unlink , fullname , err )
636
640
try :
637
641
os .rmdir (path )
642
+ except FileNotFoundError :
643
+ pass
638
644
except OSError as err :
639
645
onexc (os .rmdir , path , err )
640
646
@@ -643,6 +649,8 @@ def _rmtree_safe_fd(topfd, path, onexc):
643
649
try :
644
650
with os .scandir (topfd ) as scandir_it :
645
651
entries = list (scandir_it )
652
+ except FileNotFoundError :
653
+ return
646
654
except OSError as err :
647
655
err .filename = path
648
656
onexc (os .scandir , path , err )
@@ -651,20 +659,26 @@ def _rmtree_safe_fd(topfd, path, onexc):
651
659
fullname = os .path .join (path , entry .name )
652
660
try :
653
661
is_dir = entry .is_dir (follow_symlinks = False )
662
+ except FileNotFoundError :
663
+ continue
654
664
except OSError :
655
665
is_dir = False
656
666
else :
657
667
if is_dir :
658
668
try :
659
669
orig_st = entry .stat (follow_symlinks = False )
660
670
is_dir = stat .S_ISDIR (orig_st .st_mode )
671
+ except FileNotFoundError :
672
+ continue
661
673
except OSError as err :
662
674
onexc (os .lstat , fullname , err )
663
675
continue
664
676
if is_dir :
665
677
try :
666
678
dirfd = os .open (entry .name , os .O_RDONLY , dir_fd = topfd )
667
679
dirfd_closed = False
680
+ except FileNotFoundError :
681
+ continue
668
682
except OSError as err :
669
683
onexc (os .open , fullname , err )
670
684
else :
@@ -675,6 +689,8 @@ def _rmtree_safe_fd(topfd, path, onexc):
675
689
os .close (dirfd )
676
690
dirfd_closed = True
677
691
os .rmdir (entry .name , dir_fd = topfd )
692
+ except FileNotFoundError :
693
+ continue
678
694
except OSError as err :
679
695
onexc (os .rmdir , fullname , err )
680
696
else :
@@ -692,6 +708,8 @@ def _rmtree_safe_fd(topfd, path, onexc):
692
708
else :
693
709
try :
694
710
os .unlink (entry .name , dir_fd = topfd )
711
+ except FileNotFoundError :
712
+ continue
695
713
except OSError as err :
696
714
onexc (os .unlink , fullname , err )
697
715
@@ -781,7 +799,12 @@ def onexc(*args):
781
799
if dir_fd is not None :
782
800
raise NotImplementedError ("dir_fd unavailable on this platform" )
783
801
try :
784
- if _rmtree_islink (path ):
802
+ st = os .lstat (path )
803
+ except OSError as err :
804
+ onexc (os .lstat , path , err )
805
+ return
806
+ try :
807
+ if _rmtree_islink (st ):
785
808
# symlinks to directories are forbidden, see bug #1669
786
809
raise OSError ("Cannot call rmtree on a symbolic link" )
787
810
except OSError as err :
0 commit comments