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" ]
33+ "samefile" , "sameopenfile" , "samestat" , "commonpath" ,
34+ "ALLOW_MISSING" ]
3435
3536def _get_bothseps (path ):
3637 if isinstance (path , bytes ):
@@ -571,9 +572,10 @@ def abspath(path):
571572 from nt import _getfinalpathname , readlink as _nt_readlink
572573except ImportError :
573574 # realpath is a no-op on systems without _getfinalpathname support.
574- realpath = abspath
575+ def realpath (path , * , strict = False ):
576+ return abspath (path )
575577else :
576- def _readlink_deep (path ):
578+ def _readlink_deep (path , ignored_error = OSError ):
577579 # These error codes indicate that we should stop reading links and
578580 # return the path we currently have.
579581 # 1: ERROR_INVALID_FUNCTION
@@ -606,7 +608,7 @@ def _readlink_deep(path):
606608 path = old_path
607609 break
608610 path = normpath (join (dirname (old_path ), path ))
609- except OSError as ex :
611+ except ignored_error as ex :
610612 if ex .winerror in allowed_winerror :
611613 break
612614 raise
@@ -615,7 +617,7 @@ def _readlink_deep(path):
615617 break
616618 return path
617619
618- def _getfinalpathname_nonstrict (path ):
620+ def _getfinalpathname_nonstrict (path , ignored_error = OSError ):
619621 # These error codes indicate that we should stop resolving the path
620622 # and return the value we currently have.
621623 # 1: ERROR_INVALID_FUNCTION
@@ -642,17 +644,18 @@ def _getfinalpathname_nonstrict(path):
642644 try :
643645 path = _getfinalpathname (path )
644646 return join (path , tail ) if tail else path
645- except OSError as ex :
647+ except ignored_error as ex :
646648 if ex .winerror not in allowed_winerror :
647649 raise
648650 try :
649651 # The OS could not resolve this path fully, so we attempt
650652 # to follow the link ourselves. If we succeed, join the tail
651653 # and return.
652- new_path = _readlink_deep (path )
654+ new_path = _readlink_deep (path ,
655+ ignored_error = ignored_error )
653656 if new_path != path :
654657 return join (new_path , tail ) if tail else new_path
655- except OSError :
658+ except ignored_error :
656659 # If we fail to readlink(), let's keep traversing
657660 pass
658661 path , name = split (path )
@@ -683,16 +686,24 @@ def realpath(path, *, strict=False):
683686 if normcase (path ) == normcase (devnull ):
684687 return '\\ \\ .\\ NUL'
685688 had_prefix = path .startswith (prefix )
689+
690+ if strict is ALLOW_MISSING :
691+ ignored_error = FileNotFoundError
692+ strict = True
693+ elif strict :
694+ ignored_error = ()
695+ else :
696+ ignored_error = OSError
697+
686698 if not had_prefix and not isabs (path ):
687699 path = join (cwd , path )
688700 try :
689701 path = _getfinalpathname (path )
690702 initial_winerror = 0
691- except OSError as ex :
692- if strict :
693- raise
703+ except ignored_error as ex :
694704 initial_winerror = ex .winerror
695- path = _getfinalpathname_nonstrict (path )
705+ path = _getfinalpathname_nonstrict (path ,
706+ ignored_error = ignored_error )
696707 # The path returned by _getfinalpathname will always start with \\?\ -
697708 # strip off that prefix unless it was already provided on the original
698709 # path.
0 commit comments