Commit 83eeef4b authored by Guido van Rossum's avatar Guido van Rossum

SF patch #461781 by Chris Lawrence: os.path.realpath - Resolve symlinks:

   Once upon a time, I put together a little function
   that tries to find the canonical filename for a given
   pathname on POSIX. I've finally gotten around to
   turning it into a proper patch with documentation.
   On non-POSIX, I made it an alias for 'abspath', as
   that's the behavior on POSIX when no symlinks are
   encountered in the path.

   Example:
   >>> os.path.realpath('/usr/bin/X11/X')
   '/usr/X11R6/bin/X'
parent 3065c94f
...@@ -137,6 +137,13 @@ case (use \function{normcase()} for that). On Windows, it converts ...@@ -137,6 +137,13 @@ case (use \function{normcase()} for that). On Windows, it converts
forward slashes to backward slashes. forward slashes to backward slashes.
\end{funcdesc} \end{funcdesc}
\begin{funcdesc}{realpath}{path}
Return the canonical path of the specified filename, eliminating any
symbolic links encountered in the path.
Availability: \UNIX{}.
\versionadded{2.2}
\end{funcdesc}
\begin{funcdesc}{samefile}{path1, path2} \begin{funcdesc}{samefile}{path1, path2}
Return true if both pathname arguments refer to the same file or Return true if both pathname arguments refer to the same file or
directory (as indicated by device number and i-node number). directory (as indicated by device number and i-node number).
......
...@@ -330,3 +330,6 @@ def abspath(path): ...@@ -330,3 +330,6 @@ def abspath(path):
if not isabs(path): if not isabs(path):
path = join(os.getcwd(), path) path = join(os.getcwd(), path)
return normpath(path) return normpath(path)
# realpath is a no-op on systems without islink support
realpath = abspath
...@@ -225,3 +225,6 @@ def abspath(path): ...@@ -225,3 +225,6 @@ def abspath(path):
if not isabs(path): if not isabs(path):
path = join(os.getcwd(), path) path = join(os.getcwd(), path)
return normpath(path) return normpath(path)
# realpath is a no-op on systems without islink support
realpath = abspath
...@@ -451,3 +451,6 @@ def abspath(path): ...@@ -451,3 +451,6 @@ def abspath(path):
else: else:
path = os.getcwd() path = os.getcwd()
return normpath(path) return normpath(path)
# realpath is a no-op on systems without islink support
realpath = abspath
...@@ -315,6 +315,10 @@ def abspath(p): ...@@ -315,6 +315,10 @@ def abspath(p):
return normpath(join(os.getcwd(), p)) return normpath(join(os.getcwd(), p))
# realpath is a no-op on systems without islink support
realpath = abspath
# Normalize a path. Only special path element under RISC OS is "^" for "..". # Normalize a path. Only special path element under RISC OS is "^" for "..".
def normpath(p): def normpath(p):
......
...@@ -379,3 +379,24 @@ def abspath(path): ...@@ -379,3 +379,24 @@ def abspath(path):
if not isabs(path): if not isabs(path):
path = join(os.getcwd(), path) path = join(os.getcwd(), path)
return normpath(path) return normpath(path)
# Return a canonical path (i.e. the absolute location of a file on the
# filesystem).
def realpath(filename):
"""Return the canonical path of the specified filename, eliminating any
symbolic links encountered in the path."""
filename = abspath(filename)
bits = ['/'] + filename.split('/')[1:]
for i in range(2, len(bits)+1):
component = join(*bits[0:i])
if islink(component):
resolved = os.readlink(component)
(dir, file) = split(component)
resolved = normpath(join(dir, resolved))
newpath = join(*([resolved] + bits[i:]))
return realpath(newpath)
return filename
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment