1 | #!/usr/bin/env python |
---|
2 | """ |
---|
3 | Utilities for path manipulation. Not to be confused with the pathutils module |
---|
4 | from the pythonutils package (http://groups.google.com/group/pythonutils). |
---|
5 | """ |
---|
6 | |
---|
7 | # NOTE: If enough of _that_ pathutils functionality is required, we can switch |
---|
8 | # this module for that one. |
---|
9 | |
---|
10 | # TODO: Make algorithm more robust and complete; consider using abspath. |
---|
11 | |
---|
12 | __all__ = ['relpath'] |
---|
13 | |
---|
14 | from os.path import join |
---|
15 | from os.path import sep |
---|
16 | |
---|
17 | def relpath(p1, p2): |
---|
18 | """Compute the relative path of p1 with respect to p2.""" |
---|
19 | |
---|
20 | def commonpath(L1, L2, common=[]): |
---|
21 | if len(L1) < 1: return (common, L1, L2) |
---|
22 | if len(L2) < 1: return (common, L1, L2) |
---|
23 | if L1[0] != L2[0]: return (common, L1, L2) |
---|
24 | return commonpath(L1[1:], L2[1:], common=common+[L1[0]]) |
---|
25 | |
---|
26 | # if the strings are equal, then return "." |
---|
27 | if p1 == p2: return "." |
---|
28 | (common,L1,L2) = commonpath(p2.split(sep), p1.split(sep)) |
---|
29 | # if there is nothing in common, then return an empty string |
---|
30 | if not common: return "" |
---|
31 | # otherwise, replace the common pieces with "../" (or "..\") |
---|
32 | p = [(".."+sep) * len(L1)] + L2 |
---|
33 | return join(*p) |
---|
34 | |
---|
35 | def test(): |
---|
36 | p1 = sep.join(["a","b","c","d"]) |
---|
37 | p2 = sep.join(["a","b","c1","d1"]) |
---|
38 | p3 = sep.join(["a","b","c","d","e"]) |
---|
39 | p4 = sep.join(["a","b","c","d1","e"]) |
---|
40 | p5 = sep.join(["w","x","y","z"]) |
---|
41 | |
---|
42 | assert relpath(p1, p1) == "." |
---|
43 | assert relpath(p2, p1) == sep.join(["..", "..", "c1", "d1"]) |
---|
44 | assert relpath(p3, p1) == "e" |
---|
45 | assert relpath(p4, p1) == sep.join(["..", "d1", "e"]) |
---|
46 | assert relpath(p5, p1) == "" |
---|
47 | |
---|
48 | if __name__ == '__main__': |
---|
49 | test() |
---|