2929 "ismount" , "expanduser" ,"expandvars" ,"normpath" ,"abspath" ,
3030 "curdir" ,"pardir" ,"sep" ,"pathsep" ,"defpath" ,"altsep" ,
3131 "extsep" ,"devnull" ,"realpath" ,"supports_unicode_filenames" ,"relpath" ,
32- "samefile" , "sameopenfile" , "samestat" , "commonpath" ]
32+ "samefile" , "sameopenfile" , "samestat" , "commonpath" ,
33+ "ALLOW_MISSING" ]
3334
3435def _get_bothseps (path ):
3536 if isinstance (path , bytes ):
@@ -532,9 +533,10 @@ def abspath(path):
532533 from nt import _getfinalpathname , readlink as _nt_readlink
533534except ImportError :
534535 # realpath is a no-op on systems without _getfinalpathname support.
535- realpath = abspath
536+ def realpath (path , * , strict = False ):
537+ return abspath (path )
536538else :
537- def _readlink_deep (path ):
539+ def _readlink_deep (path , ignored_error = OSError ):
538540 # These error codes indicate that we should stop reading links and
539541 # return the path we currently have.
540542 # 1: ERROR_INVALID_FUNCTION
@@ -567,7 +569,7 @@ def _readlink_deep(path):
567569 path = old_path
568570 break
569571 path = normpath (join (dirname (old_path ), path ))
570- except OSError as ex :
572+ except ignored_error as ex :
571573 if ex .winerror in allowed_winerror :
572574 break
573575 raise
@@ -576,7 +578,7 @@ def _readlink_deep(path):
576578 break
577579 return path
578580
579- def _getfinalpathname_nonstrict (path ):
581+ def _getfinalpathname_nonstrict (path , ignored_error = OSError ):
580582 # These error codes indicate that we should stop resolving the path
581583 # and return the value we currently have.
582584 # 1: ERROR_INVALID_FUNCTION
@@ -600,17 +602,18 @@ def _getfinalpathname_nonstrict(path):
600602 try :
601603 path = _getfinalpathname (path )
602604 return join (path , tail ) if tail else path
603- except OSError as ex :
605+ except ignored_error as ex :
604606 if ex .winerror not in allowed_winerror :
605607 raise
606608 try :
607609 # The OS could not resolve this path fully, so we attempt
608610 # to follow the link ourselves. If we succeed, join the tail
609611 # and return.
610- new_path = _readlink_deep (path )
612+ new_path = _readlink_deep (path ,
613+ ignored_error = ignored_error )
611614 if new_path != path :
612615 return join (new_path , tail ) if tail else new_path
613- except OSError :
616+ except ignored_error :
614617 # If we fail to readlink(), let's keep traversing
615618 pass
616619 path , name = split (path )
@@ -641,16 +644,24 @@ def realpath(path, *, strict=False):
641644 if normcase (path ) == normcase (devnull ):
642645 return '\\ \\ .\\ NUL'
643646 had_prefix = path .startswith (prefix )
647+
648+ if strict is ALLOW_MISSING :
649+ ignored_error = FileNotFoundError
650+ strict = True
651+ elif strict :
652+ ignored_error = ()
653+ else :
654+ ignored_error = OSError
655+
644656 if not had_prefix and not isabs (path ):
645657 path = join (cwd , path )
646658 try :
647659 path = _getfinalpathname (path )
648660 initial_winerror = 0
649- except OSError as ex :
650- if strict :
651- raise
661+ except ignored_error as ex :
652662 initial_winerror = ex .winerror
653- path = _getfinalpathname_nonstrict (path )
663+ path = _getfinalpathname_nonstrict (path ,
664+ ignored_error = ignored_error )
654665 # The path returned by _getfinalpathname will always start with \\?\ -
655666 # strip off that prefix unless it was already provided on the original
656667 # path.
0 commit comments