You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
Support different modes in os.path.realpath() #71189
Note: these values reflect the state of the issue at the time it was migrated and might not reflect the current state.
Show more details
GitHub fields:
assignee=Noneclosed_at=Nonecreated_at=<Date2016-05-11.18:54:44.165>labels= ['type-feature', 'library']
title='Support different modes in posixpath.realpath()'updated_at=<Date2021-04-08.00:42:45.008>user='https://github.com/serhiy-storchaka'
For now posixpath.realpath() don't raise an exception if encounter broken link. Instead it just lefts broken link name and following path components unresolved. This is dangerous since broken link name can be collapsed with following ".." and resulting valid path can point at wrong location. May be this is even security issue.
On other hand, Path.resolve() raises an exception when encounters broken link. This is not always desirable, there is a wish to make it more lenient. See bpo-19717 for more information.
The readlink utility from GNU coreutils has three mode for resolving file path:
-f, --canonicalize
canonicalize by following every symlink in every component of the given name recursively; all but the last component must exist
-e, --canonicalize-existing
canonicalize by following every symlink in every component of the given name recursively, all components must exist
-m, --canonicalize-missing
canonicalize by following every symlink in every component of the given name recursively, without requirements on components existence
Current behavior of posixpath.realpath() is matches (besides one minor detail) to readlink -m. The behavior of Path.resolve() matches readlink -e.
Proposed preliminary patch implements the support of all three modes in posixpath.realpath(): CAN_MISSING, CAN_ALL_BUT_LAST and CAN_EXISTING. It exactly matches the behavior of readlink. The default mode is CAN_MISSING.
There is minor behavior difference in the default mode. If there is a file "file", a link "link" that points to "file" and a broken link "broken", then "broken/../link" was resolved to "link" and now it is resolved to "file".
The patch lacks the documentation. Ternary flag looks as not the best API. Binary flag would be better. But I don't know what can be dropped. CAN_MISSING is needed for compatibility, but it looks less useful and may be insecure (not more than normpath()). CAN_EXISTING and CAN_ALL_BUT_LAST is needed in different cases. I think that in many cases CAN_ALL_BUT_LAST is actually needed instead of CAN_MISSING.
After resolving this issue the solution will be adopted for Path.resolve().
Activity
serhiy-storchaka commentedon May 11, 2016
For now posixpath.realpath() don't raise an exception if encounter broken link. Instead it just lefts broken link name and following path components unresolved. This is dangerous since broken link name can be collapsed with following ".." and resulting valid path can point at wrong location. May be this is even security issue.
On other hand, Path.resolve() raises an exception when encounters broken link. This is not always desirable, there is a wish to make it more lenient. See bpo-19717 for more information.
The readlink utility from GNU coreutils has three mode for resolving file path:
Current behavior of posixpath.realpath() is matches (besides one minor detail) to
readlink -m. The behavior of Path.resolve() matchesreadlink -e.Proposed preliminary patch implements the support of all three modes in posixpath.realpath(): CAN_MISSING, CAN_ALL_BUT_LAST and CAN_EXISTING. It exactly matches the behavior of readlink. The default mode is CAN_MISSING.
There is minor behavior difference in the default mode. If there is a file "file", a link "link" that points to "file" and a broken link "broken", then "broken/../link" was resolved to "link" and now it is resolved to "file".
The patch lacks the documentation. Ternary flag looks as not the best API. Binary flag would be better. But I don't know what can be dropped. CAN_MISSING is needed for compatibility, but it looks less useful and may be insecure (not more than normpath()). CAN_EXISTING and CAN_ALL_BUT_LAST is needed in different cases. I think that in many cases CAN_ALL_BUT_LAST is actually needed instead of CAN_MISSING.
After resolving this issue the solution will be adopted for Path.resolve().
barneygale commentedon Apr 8, 2021
Just stumbled upon this issue after submitting a PR: #25264
In my PR,
strict=Falseis like--canonicalize-missing, andstrict=Trueis like--canonicalize-existing.Looks like our patches are along similar lines. I've missed a trick by not calling
stat()to trigger the ELOOP error.pythongh-71189: Support all-but-last mode in posixpath.realpath()
[-]Support different modes in posixpath.realpath()[/-][+]Support different modes in os.path.realpath()[/+]gh-71189: Support all-but-last mode in os.path.realpath() (GH-117562)
pythongh-71189: Support all-but-last mode in os.path.realpath() (pyth…