@@ -590,30 +590,30 @@ def copytree(src, dst, symlinks=False, ignore=None, copy_function=copy2,
590590 dirs_exist_ok = dirs_exist_ok )
591591
592592if 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 ))
601597else :
602- def _rmtree_islink (path ):
603- return os . path . islink ( path )
598+ def _rmtree_islink (st ):
599+ return stat . S_ISLNK ( st . st_mode )
604600
605601# version vulnerable to race conditions
606602def _rmtree_unsafe (path , onexc ):
607603 try :
608604 with os .scandir (path ) as scandir_it :
609605 entries = list (scandir_it )
606+ except FileNotFoundError :
607+ return
610608 except OSError as err :
611609 onexc (os .scandir , path , err )
612610 entries = []
613611 for entry in entries :
614612 fullname = entry .path
615613 try :
616614 is_dir = entry .is_dir (follow_symlinks = False )
615+ except FileNotFoundError :
616+ continue
617617 except OSError :
618618 is_dir = False
619619
@@ -624,17 +624,23 @@ def _rmtree_unsafe(path, onexc):
624624 # a directory with a symlink after the call to
625625 # os.scandir or entry.is_dir above.
626626 raise OSError ("Cannot call rmtree on a symbolic link" )
627+ except FileNotFoundError :
628+ continue
627629 except OSError as err :
628630 onexc (os .path .islink , fullname , err )
629631 continue
630632 _rmtree_unsafe (fullname , onexc )
631633 else :
632634 try :
633635 os .unlink (fullname )
636+ except FileNotFoundError :
637+ continue
634638 except OSError as err :
635639 onexc (os .unlink , fullname , err )
636640 try :
637641 os .rmdir (path )
642+ except FileNotFoundError :
643+ pass
638644 except OSError as err :
639645 onexc (os .rmdir , path , err )
640646
@@ -643,6 +649,8 @@ def _rmtree_safe_fd(topfd, path, onexc):
643649 try :
644650 with os .scandir (topfd ) as scandir_it :
645651 entries = list (scandir_it )
652+ except FileNotFoundError :
653+ return
646654 except OSError as err :
647655 err .filename = path
648656 onexc (os .scandir , path , err )
@@ -651,20 +659,26 @@ def _rmtree_safe_fd(topfd, path, onexc):
651659 fullname = os .path .join (path , entry .name )
652660 try :
653661 is_dir = entry .is_dir (follow_symlinks = False )
662+ except FileNotFoundError :
663+ continue
654664 except OSError :
655665 is_dir = False
656666 else :
657667 if is_dir :
658668 try :
659669 orig_st = entry .stat (follow_symlinks = False )
660670 is_dir = stat .S_ISDIR (orig_st .st_mode )
671+ except FileNotFoundError :
672+ continue
661673 except OSError as err :
662674 onexc (os .lstat , fullname , err )
663675 continue
664676 if is_dir :
665677 try :
666678 dirfd = os .open (entry .name , os .O_RDONLY , dir_fd = topfd )
667679 dirfd_closed = False
680+ except FileNotFoundError :
681+ continue
668682 except OSError as err :
669683 onexc (os .open , fullname , err )
670684 else :
@@ -675,6 +689,8 @@ def _rmtree_safe_fd(topfd, path, onexc):
675689 os .close (dirfd )
676690 dirfd_closed = True
677691 os .rmdir (entry .name , dir_fd = topfd )
692+ except FileNotFoundError :
693+ continue
678694 except OSError as err :
679695 onexc (os .rmdir , fullname , err )
680696 else :
@@ -692,6 +708,8 @@ def _rmtree_safe_fd(topfd, path, onexc):
692708 else :
693709 try :
694710 os .unlink (entry .name , dir_fd = topfd )
711+ except FileNotFoundError :
712+ continue
695713 except OSError as err :
696714 onexc (os .unlink , fullname , err )
697715
@@ -781,7 +799,12 @@ def onexc(*args):
781799 if dir_fd is not None :
782800 raise NotImplementedError ("dir_fd unavailable on this platform" )
783801 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 ):
785808 # symlinks to directories are forbidden, see bug #1669
786809 raise OSError ("Cannot call rmtree on a symbolic link" )
787810 except OSError as err :
0 commit comments