3030           "ismount" , "expanduser" ,"expandvars" ,"normpath" ,"abspath" ,
3131           "curdir" ,"pardir" ,"sep" ,"pathsep" ,"defpath" ,"altsep" ,
3232           "extsep" ,"devnull" ,"realpath" ,"supports_unicode_filenames" ,"relpath" ,
33-            "samefile" , "sameopenfile" , "samestat" , "commonpath" , "isjunction" ]
33+            "samefile" , "sameopenfile" , "samestat" , "commonpath" , "isjunction" ,
34+            "ALLOW_MISSING" ]
3435
3536def  _get_bothseps (path ):
3637    if  isinstance (path , bytes ):
@@ -609,9 +610,10 @@ def abspath(path):
609610    from  nt  import  _getfinalpathname , readlink  as  _nt_readlink 
610611except  ImportError :
611612    # realpath is a no-op on systems without _getfinalpathname support. 
612-     realpath  =  abspath 
613+     def  realpath (path , * , strict = False ):
614+         return  abspath (path )
613615else :
614-     def  _readlink_deep (path ):
616+     def  _readlink_deep (path ,  ignored_error = OSError ):
615617        # These error codes indicate that we should stop reading links and 
616618        # return the path we currently have. 
617619        # 1: ERROR_INVALID_FUNCTION 
@@ -644,7 +646,7 @@ def _readlink_deep(path):
644646                        path  =  old_path 
645647                        break 
646648                    path  =  normpath (join (dirname (old_path ), path ))
647-             except  OSError  as  ex :
649+             except  ignored_error  as  ex :
648650                if  ex .winerror  in  allowed_winerror :
649651                    break 
650652                raise 
@@ -653,7 +655,7 @@ def _readlink_deep(path):
653655                break 
654656        return  path 
655657
656-     def  _getfinalpathname_nonstrict (path ):
658+     def  _getfinalpathname_nonstrict (path ,  ignored_error = OSError ):
657659        # These error codes indicate that we should stop resolving the path 
658660        # and return the value we currently have. 
659661        # 1: ERROR_INVALID_FUNCTION 
@@ -680,17 +682,18 @@ def _getfinalpathname_nonstrict(path):
680682            try :
681683                path  =  _getfinalpathname (path )
682684                return  join (path , tail ) if  tail  else  path 
683-             except  OSError  as  ex :
685+             except  ignored_error  as  ex :
684686                if  ex .winerror  not  in allowed_winerror :
685687                    raise 
686688                try :
687689                    # The OS could not resolve this path fully, so we attempt 
688690                    # to follow the link ourselves. If we succeed, join the tail 
689691                    # and return. 
690-                     new_path  =  _readlink_deep (path )
692+                     new_path  =  _readlink_deep (path ,
693+                                               ignored_error = ignored_error )
691694                    if  new_path  !=  path :
692695                        return  join (new_path , tail ) if  tail  else  new_path 
693-                 except  OSError :
696+                 except  ignored_error :
694697                    # If we fail to readlink(), let's keep traversing 
695698                    pass 
696699                path , name  =  split (path )
@@ -721,24 +724,32 @@ def realpath(path, *, strict=False):
721724            if  normcase (path ) ==  normcase (devnull ):
722725                return  '\\ \\ .\\ NUL' 
723726        had_prefix  =  path .startswith (prefix )
727+ 
728+         if  strict  is  ALLOW_MISSING :
729+             ignored_error  =  FileNotFoundError 
730+             strict  =  True 
731+         elif  strict :
732+             ignored_error  =  ()
733+         else :
734+             ignored_error  =  OSError 
735+ 
724736        if  not  had_prefix  and  not  isabs (path ):
725737            path  =  join (cwd , path )
726738        try :
727739            path  =  _getfinalpathname (path )
728740            initial_winerror  =  0 
729741        except  ValueError  as  ex :
730742            # gh-106242: Raised for embedded null characters 
731-             # In strict mode , we convert into an OSError. 
743+             # In strict modes , we convert into an OSError. 
732744            # Non-strict mode returns the path as-is, since we've already 
733745            # made it absolute. 
734746            if  strict :
735747                raise  OSError (str (ex )) from  None 
736748            path  =  normpath (path )
737-         except  OSError  as  ex :
738-             if  strict :
739-                 raise 
749+         except  ignored_error  as  ex :
740750            initial_winerror  =  ex .winerror 
741-             path  =  _getfinalpathname_nonstrict (path )
751+             path  =  _getfinalpathname_nonstrict (path ,
752+                                                ignored_error = ignored_error )
742753        # The path returned by _getfinalpathname will always start with \\?\ - 
743754        # strip off that prefix unless it was already provided on the original 
744755        # path. 
0 commit comments