+from os.path import isabs, islink, abspath, normpath
+ """Join two or more pathname components, inserting '/' as needed.
+ If any component is an absolute path, all previous path components
+ will be discarded. An empty last part will result in a path that
+ ends with a separator."""
+ elif path == '' or path.endswith('/'):
+ """Return the canonical path of the specified filename, eliminating any
+symbolic links encountered in the path."""
+ bits = ['/'] + filename.split('/')[1:]
+ bits = [''] + filename.split('/')
+ for i in range(2, len(bits)+1):
+ component = join(bits, bits[1:i])
+ # Resolve symbolic links.
+ resolved = _resolve_link(component)
+ # Infinite loop -- return original component + rest of the path
+ return abspath(join(component, bits[i:]))
+ newpath = join(resolved, bits[i:])
+ return realpath(newpath)
+ return abspath(filename)
+ """Internal helper function. Takes a path and follows symlinks
+ until we either arrive at something that isn't a symlink, or
+ encounter a path we've seen before (meaning that there's a loop).
+ # Already seen this path, so we must have a symlink loop
+ paths_seen[path] = None
+ # Resolve where the link points to
+ resolved = os.readlink(path)
+ if not isabs(resolved):
+ path = normpath(join(dir, [resolved]))
+ path = normpath(resolved)