2929           "abspath" ,"curdir" ,"pardir" ,"sep" ,"pathsep" ,"defpath" ,"altsep" ,
3030           "extsep" ,"devnull" ,"realpath" ,"supports_unicode_filenames" ,"relpath" ,
3131           "samefile" , "sameopenfile" , "samestat" , "commonpath" , "isjunction" ,
32-            "isdevdrive" ]
32+            "isdevdrive" ,  "ALLOW_MISSING" ]
3333
3434def  _get_bothseps (path ):
3535    if  isinstance (path , bytes ):
@@ -601,9 +601,10 @@ def abspath(path):
601601    from  nt  import  _findfirstfile , _getfinalpathname , readlink  as  _nt_readlink 
602602except  ImportError :
603603    # realpath is a no-op on systems without _getfinalpathname support. 
604-     realpath  =  abspath 
604+     def  realpath (path , * , strict = False ):
605+         return  abspath (path )
605606else :
606-     def  _readlink_deep (path ):
607+     def  _readlink_deep (path ,  ignored_error = OSError ):
607608        # These error codes indicate that we should stop reading links and 
608609        # return the path we currently have. 
609610        # 1: ERROR_INVALID_FUNCTION 
@@ -636,7 +637,7 @@ def _readlink_deep(path):
636637                        path  =  old_path 
637638                        break 
638639                    path  =  normpath (join (dirname (old_path ), path ))
639-             except  OSError  as  ex :
640+             except  ignored_error  as  ex :
640641                if  ex .winerror  in  allowed_winerror :
641642                    break 
642643                raise 
@@ -645,7 +646,7 @@ def _readlink_deep(path):
645646                break 
646647        return  path 
647648
648-     def  _getfinalpathname_nonstrict (path ):
649+     def  _getfinalpathname_nonstrict (path ,  ignored_error = OSError ):
649650        # These error codes indicate that we should stop resolving the path 
650651        # and return the value we currently have. 
651652        # 1: ERROR_INVALID_FUNCTION 
@@ -673,25 +674,26 @@ def _getfinalpathname_nonstrict(path):
673674            try :
674675                path  =  _getfinalpathname (path )
675676                return  join (path , tail ) if  tail  else  path 
676-             except  OSError  as  ex :
677+             except  ignored_error  as  ex :
677678                if  ex .winerror  not  in allowed_winerror :
678679                    raise 
679680                try :
680681                    # The OS could not resolve this path fully, so we attempt 
681682                    # to follow the link ourselves. If we succeed, join the tail 
682683                    # and return. 
683-                     new_path  =  _readlink_deep (path )
684+                     new_path  =  _readlink_deep (path ,
685+                                               ignored_error = ignored_error )
684686                    if  new_path  !=  path :
685687                        return  join (new_path , tail ) if  tail  else  new_path 
686-                 except  OSError :
688+                 except  ignored_error :
687689                    # If we fail to readlink(), let's keep traversing 
688690                    pass 
689691                # If we get these errors, try to get the real name of the file without accessing it. 
690692                if  ex .winerror  in  (1 , 5 , 32 , 50 , 87 , 1920 , 1921 ):
691693                    try :
692694                        name  =  _findfirstfile (path )
693695                        path , _  =  split (path )
694-                     except  OSError :
696+                     except  ignored_error :
695697                        path , name  =  split (path )
696698                else :
697699                    path , name  =  split (path )
@@ -721,24 +723,32 @@ def realpath(path, *, strict=False):
721723            if  normcase (path ) ==  devnull :
722724                return  '\\ \\ .\\ NUL' 
723725        had_prefix  =  path .startswith (prefix )
726+ 
727+         if  strict  is  ALLOW_MISSING :
728+             ignored_error  =  FileNotFoundError 
729+             strict  =  True 
730+         elif  strict :
731+             ignored_error  =  ()
732+         else :
733+             ignored_error  =  OSError 
734+ 
724735        if  not  had_prefix  and  not  isabs (path ):
725736            path  =  join (cwd , path )
726737        try :
727738            path  =  _getfinalpathname (path )
728739            initial_winerror  =  0 
729740        except  ValueError  as  ex :
730741            # gh-106242: Raised for embedded null characters 
731-             # In strict mode , we convert into an OSError. 
742+             # In strict modes , we convert into an OSError. 
732743            # Non-strict mode returns the path as-is, since we've already 
733744            # made it absolute. 
734745            if  strict :
735746                raise  OSError (str (ex )) from  None 
736747            path  =  normpath (path )
737-         except  OSError  as  ex :
738-             if  strict :
739-                 raise 
748+         except  ignored_error  as  ex :
740749            initial_winerror  =  ex .winerror 
741-             path  =  _getfinalpathname_nonstrict (path )
750+             path  =  _getfinalpathname_nonstrict (path ,
751+                                                ignored_error = ignored_error )
742752        # The path returned by _getfinalpathname will always start with \\?\ - 
743753        # strip off that prefix unless it was already provided on the original 
744754        # path. 
0 commit comments