1
2
3
4 import os.path
5
7 """Return the canonical path of the specified filename, eliminating any
8 symbolic links encountered in the path."""
9 if os.path.isabs(filename):
10 bits = ['/'] + filename.split('/')[1:]
11 else:
12 bits = [''] + filename.split('/')
13
14 for i in range(2, len(bits)+1):
15 component = os.path.join(*bits[0:i])
16
17 if os.path.islink(component):
18 resolved = _resolve_link(component)
19 if resolved is None:
20
21 return os.path.abspath(os.path.join(*([component] + bits[i:])))
22 else:
23 newpath = os.path.join(*([resolved] + bits[i:]))
24 return realpath(newpath)
25
26 return os.path.abspath(filename)
27
28
30 """Internal helper function. Takes a path and follows symlinks
31 until we either arrive at something that isn't a symlink, or
32 encounter a path we've seen before (meaning that there's a loop).
33 """
34 paths_seen = []
35 while os.path.islink(path):
36 if path in paths_seen:
37
38 return None
39 paths_seen.append(path)
40
41 resolved = os.readlink(path)
42 if not os.path.isabs(resolved):
43 dir = os.path.dirname(path)
44 path = os.path.normpath(os.path.join(dir, resolved))
45 else:
46 path = os.path.normpath(resolved)
47 return path
48
49 os.path.realpath = realpath
50 os.path._resolve_link = _resolve_link
51