summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorwillmcgugan@gmail.com <willmcgugan@gmail.com@67cdc799-7952-0410-af00-57a81ceafa0f>2013-06-28 12:28:08 +0000
committerwillmcgugan@gmail.com <willmcgugan@gmail.com@67cdc799-7952-0410-af00-57a81ceafa0f>2013-06-28 12:28:08 +0000
commit9545ff3d5e3605d2c70a67a2de9607bd34d08014 (patch)
tree62afbfcd04de8b294a49d3801cae150a7ee86b30
parent8a78d3236747fc2602eff9e307ff938607a14444 (diff)
downloadpyfilesystem-9545ff3d5e3605d2c70a67a2de9607bd34d08014.tar.gz
Added 'relativefrom' method to path.py
git-svn-id: http://pyfilesystem.googlecode.com/svn/trunk@857 67cdc799-7952-0410-af00-57a81ceafa0f
-rw-r--r--fs/multifs.py4
-rw-r--r--fs/path.py28
-rw-r--r--fs/tests/test_path.py15
3 files changed, 45 insertions, 2 deletions
diff --git a/fs/multifs.py b/fs/multifs.py
index cac6cf5..cdfce67 100644
--- a/fs/multifs.py
+++ b/fs/multifs.py
@@ -127,7 +127,7 @@ class MultiFS(FS):
def _priority_sort(self):
"""Sort filesystems by priority order"""
- priority_order = sorted(self.fs_lookup.keys(), key=lambda n:self.fs_priorities[n], reverse=True)
+ priority_order = sorted(self.fs_lookup.keys(), key=lambda n: self.fs_priorities[n], reverse=True)
self.fs_sequence = [self.fs_lookup[name] for name in priority_order]
@synchronize
@@ -181,7 +181,7 @@ class MultiFS(FS):
"""
if name not in self.fs_lookup:
- raise ValueError("No filesystem called '%s'"%name)
+ raise ValueError("No filesystem called '%s'" % name)
fs = self.fs_lookup[name]
self.fs_sequence.remove(fs)
del self.fs_lookup[name]
diff --git a/fs/path.py b/fs/path.py
index 806725a..ec97d1c 100644
--- a/fs/path.py
+++ b/fs/path.py
@@ -396,6 +396,29 @@ def frombase(path1, path2):
return path2[len(path1):]
+def relativefrom(base, path):
+ """Return a path relative from a given base path,
+ i.e. insert backrefs as appropriate to reach the path from the base.
+
+ :param base_path: Path to a directory
+ :param path: Path you wish to make relative
+
+
+ >>> relativefrom("foo/bar", "baz/index.html")
+ '../baz/index.html'
+
+ """
+ base = list(iteratepath(base))
+ path = list(iteratepath(path))
+
+ while base and path and base[0] == path[0]:
+ base.pop(0)
+ path.pop(0)
+
+ # If you multiply a list by a negative number, you get an empty list!
+ return u'/'.join([u'..'] * len(base) + path)
+
+
class PathMap(object):
"""Dict-like object with paths for keys.
@@ -626,3 +649,8 @@ def iswildcard(path):
if __name__ == "__main__":
print recursepath('a/b/c')
+
+ print relativefrom('/', '/foo')
+ print relativefrom('/foo/bar', '/foo/baz')
+ print relativefrom('/foo/bar/baz', '/foo/egg')
+ print relativefrom('/foo/bar/baz/egg', '/foo/egg')
diff --git a/fs/tests/test_path.py b/fs/tests/test_path.py
index dc023a3..117fdae 100644
--- a/fs/tests/test_path.py
+++ b/fs/tests/test_path.py
@@ -150,6 +150,21 @@ class TestPathFunctions(unittest.TestCase):
self.assertFalse(iswildcard('img.jpg'))
self.assertFalse(iswildcard('foo/bar'))
+ def test_realtivefrom(self):
+ tests = [('/', '/foo.html', 'foo.html'),
+ ('/foo', '/foo/bar.html', 'bar.html'),
+ ('/foo/bar/', '/egg.html', '../../egg.html'),
+ ('/a/b/c/d', 'e', '../../../../e'),
+ ('/a/b/c/d', 'a/d', '../../../d'),
+ ('/docs/', 'tags/index.html', '../tags/index.html'),
+ ('foo/bar', 'baz/index.html', '../../baz/index.html'),
+ ('', 'a', 'a'),
+ ('a', 'b/c', '../b/c')
+ ]
+
+ for base, path, result in tests:
+ self.assertEqual(relativefrom(base, path), result)
+
class Test_PathMap(unittest.TestCase):