[4025019] | 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() |
---|