29
29
"abspath" ,"curdir" ,"pardir" ,"sep" ,"pathsep" ,"defpath" ,"altsep" ,
30
30
"extsep" ,"devnull" ,"realpath" ,"supports_unicode_filenames" ,"relpath" ,
31
31
"samefile" , "sameopenfile" , "samestat" , "commonpath" , "isjunction" ,
32
- "isdevdrive" ]
32
+ "isdevdrive" , "ALLOW_MISSING" ]
33
33
34
34
def _get_bothseps (path ):
35
35
if isinstance (path , bytes ):
@@ -601,9 +601,10 @@ def abspath(path):
601
601
from nt import _findfirstfile , _getfinalpathname , readlink as _nt_readlink
602
602
except ImportError :
603
603
# realpath is a no-op on systems without _getfinalpathname support.
604
- realpath = abspath
604
+ def realpath (path , * , strict = False ):
605
+ return abspath (path )
605
606
else :
606
- def _readlink_deep (path ):
607
+ def _readlink_deep (path , ignored_error = OSError ):
607
608
# These error codes indicate that we should stop reading links and
608
609
# return the path we currently have.
609
610
# 1: ERROR_INVALID_FUNCTION
@@ -636,7 +637,7 @@ def _readlink_deep(path):
636
637
path = old_path
637
638
break
638
639
path = normpath (join (dirname (old_path ), path ))
639
- except OSError as ex :
640
+ except ignored_error as ex :
640
641
if ex .winerror in allowed_winerror :
641
642
break
642
643
raise
@@ -645,7 +646,7 @@ def _readlink_deep(path):
645
646
break
646
647
return path
647
648
648
- def _getfinalpathname_nonstrict (path ):
649
+ def _getfinalpathname_nonstrict (path , ignored_error = OSError ):
649
650
# These error codes indicate that we should stop resolving the path
650
651
# and return the value we currently have.
651
652
# 1: ERROR_INVALID_FUNCTION
@@ -673,25 +674,26 @@ def _getfinalpathname_nonstrict(path):
673
674
try :
674
675
path = _getfinalpathname (path )
675
676
return join (path , tail ) if tail else path
676
- except OSError as ex :
677
+ except ignored_error as ex :
677
678
if ex .winerror not in allowed_winerror :
678
679
raise
679
680
try :
680
681
# The OS could not resolve this path fully, so we attempt
681
682
# to follow the link ourselves. If we succeed, join the tail
682
683
# and return.
683
- new_path = _readlink_deep (path )
684
+ new_path = _readlink_deep (path ,
685
+ ignored_error = ignored_error )
684
686
if new_path != path :
685
687
return join (new_path , tail ) if tail else new_path
686
- except OSError :
688
+ except ignored_error :
687
689
# If we fail to readlink(), let's keep traversing
688
690
pass
689
691
# If we get these errors, try to get the real name of the file without accessing it.
690
692
if ex .winerror in (1 , 5 , 32 , 50 , 87 , 1920 , 1921 ):
691
693
try :
692
694
name = _findfirstfile (path )
693
695
path , _ = split (path )
694
- except OSError :
696
+ except ignored_error :
695
697
path , name = split (path )
696
698
else :
697
699
path , name = split (path )
@@ -721,24 +723,32 @@ def realpath(path, *, strict=False):
721
723
if normcase (path ) == devnull :
722
724
return '\\ \\ .\\ NUL'
723
725
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
+
724
735
if not had_prefix and not isabs (path ):
725
736
path = join (cwd , path )
726
737
try :
727
738
path = _getfinalpathname (path )
728
739
initial_winerror = 0
729
740
except ValueError as ex :
730
741
# 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.
732
743
# Non-strict mode returns the path as-is, since we've already
733
744
# made it absolute.
734
745
if strict :
735
746
raise OSError (str (ex )) from None
736
747
path = normpath (path )
737
- except OSError as ex :
738
- if strict :
739
- raise
748
+ except ignored_error as ex :
740
749
initial_winerror = ex .winerror
741
- path = _getfinalpathname_nonstrict (path )
750
+ path = _getfinalpathname_nonstrict (path ,
751
+ ignored_error = ignored_error )
742
752
# The path returned by _getfinalpathname will always start with \\?\ -
743
753
# strip off that prefix unless it was already provided on the original
744
754
# path.
0 commit comments