3636 "samefile" ,"sameopenfile" ,"samestat" ,
3737 "curdir" ,"pardir" ,"sep" ,"pathsep" ,"defpath" ,"altsep" ,"extsep" ,
3838 "devnull" ,"realpath" ,"supports_unicode_filenames" ,"relpath" ,
39- "commonpath" , "isjunction" ,"isdevdrive" ,"ALLOW_MISSING" ]
39+ "commonpath" ,"isjunction" ,"isdevdrive" ,
40+ "ALL_BUT_LAST" ,"ALLOW_MISSING" ]
4041
4142
4243def _get_sep (path ):
@@ -404,7 +405,8 @@ def realpath(filename, /, *, strict=False):
404405 getcwd = os .getcwd
405406 if strict is ALLOW_MISSING :
406407 ignored_error = FileNotFoundError
407- strict = True
408+ elif strict is ALL_BUT_LAST :
409+ ignored_error = FileNotFoundError
408410 elif strict :
409411 ignored_error = ()
410412 else :
@@ -418,7 +420,7 @@ def realpath(filename, /, *, strict=False):
418420 # indicates that a symlink target has been resolved, and that the original
419421 # symlink path can be retrieved by popping again. The [::-1] slice is a
420422 # very fast way of spelling list(reversed(...)).
421- rest = filename .split (sep )[::- 1 ]
423+ rest = filename .rstrip ( sep ). split (sep )[::- 1 ]
422424
423425 # Number of unprocessed parts in 'rest'. This can differ from len(rest)
424426 # later, because 'rest' might contain markers for unresolved symlinks.
@@ -427,6 +429,7 @@ def realpath(filename, /, *, strict=False):
427429 # The resolved path, which is absolute throughout this function.
428430 # Note: getcwd() returns a normalized and symlink-free path.
429431 path = sep if filename .startswith (sep ) else getcwd ()
432+ trailing_sep = filename .endswith (sep )
430433
431434 # Mapping from symlink paths to *fully resolved* symlink targets. If a
432435 # symlink is encountered but not yet resolved, the value is None. This is
@@ -459,7 +462,8 @@ def realpath(filename, /, *, strict=False):
459462 try :
460463 st_mode = lstat (newpath ).st_mode
461464 if not stat .S_ISLNK (st_mode ):
462- if strict and part_count and not stat .S_ISDIR (st_mode ):
465+ if (strict and (part_count or trailing_sep )
466+ and not stat .S_ISDIR (st_mode )):
463467 raise OSError (errno .ENOTDIR , os .strerror (errno .ENOTDIR ),
464468 newpath )
465469 path = newpath
@@ -486,7 +490,8 @@ def realpath(filename, /, *, strict=False):
486490 continue
487491 target = readlink (newpath )
488492 except ignored_error :
489- pass
493+ if strict is ALL_BUT_LAST and part_count :
494+ raise
490495 else :
491496 # Resolve the symbolic link
492497 if target .startswith (sep ):
0 commit comments