diff options
-rw-r--r-- | fs/multifs.py | 4 | ||||
-rw-r--r-- | fs/path.py | 28 | ||||
-rw-r--r-- | fs/tests/test_path.py | 15 |
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] @@ -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): |