summaryrefslogtreecommitdiff
path: root/fs/path.py
diff options
context:
space:
mode:
Diffstat (limited to 'fs/path.py')
-rw-r--r--fs/path.py68
1 files changed, 54 insertions, 14 deletions
diff --git a/fs/path.py b/fs/path.py
index 4cdb873..aba1722 100644
--- a/fs/path.py
+++ b/fs/path.py
@@ -1,6 +1,5 @@
"""
-
- fs.path: useful functions for FS path manipulation.
+Useful functions for FS path manipulation.
This is broadly similar to the standard 'os.path' module but works with
paths in the canonical format expected by all FS objects (backslash-separated,
@@ -16,6 +15,8 @@ def normpath(path):
duplicate slashes, replaces forward with backward slashes, and generally
tries very hard to return a new path string the canonical FS format.
If the path is invalid, ValueError will be raised.
+
+ :param path: Path to normalize
>>> normpath(r"foo\\bar\\baz")
'foo/bar/baz'
@@ -47,20 +48,41 @@ def normpath(path):
if not components:
components = [""]
components.insert(0,"")
- return "/".join(components)
+ if isinstance(path, unicode):
+ return u"/".join(components)
+ else:
+ return '/'.join(components)
def iteratepath(path, numsplits=None):
- """Iterate over the individual components of a path."""
+ """Iterate over the individual components of a path.
+
+ :param path: Path to iterate over
+ :numsplits: Maximum number of splits
+
+ """
path = relpath(normpath(path))
if not path:
return []
if numsplits == None:
- return path.split('/')
+ return map(None, path.split('/'))
else:
- return path.split('/', numsplits)
-
-
+ return map(None, path.split('/', numsplits))
+
+def recursepath(path, reverse=False):
+ """Iterate from root to path, returning intermediate paths"""
+
+ paths = list(iteratepath(path))
+
+ if reverse:
+ paths = []
+ while path.lstrip('/'):
+ paths.append(path)
+ path = dirname(path)
+ return paths
+ else:
+ return [u'/'.join(paths[:i+1]) for i in xrange(len(paths))]
+
def abspath(path):
"""Convert the given path to an absolute path.
@@ -69,9 +91,9 @@ def abspath(path):
"""
if not path:
- return "/"
- if path[0] != "/":
- return "/" + path
+ return u'/'
+ if not path.startswith('/'):
+ return u'/' + path
return path
@@ -80,6 +102,8 @@ def relpath(path):
This is the inverse of abspath(), stripping a leading '/' from the
path if it is present.
+
+ :param path: Path to adjust
"""
while path and path[0] == "/":
@@ -89,6 +113,8 @@ def relpath(path):
def pathjoin(*paths):
"""Joins any number of paths together, returning a new path string.
+
+ :param paths: Paths to join are given in positional arguments
>>> pathjoin('foo', 'bar', 'baz')
'foo/bar/baz'
@@ -111,7 +137,7 @@ def pathjoin(*paths):
path = normpath("/".join(relpaths))
if absolute and not path.startswith("/"):
- path = "/" + path
+ path = u"/" + path
return path
# Allow pathjoin() to be used as fs.path.join()
@@ -123,6 +149,8 @@ def pathsplit(path):
This function splits a path into a pair (head,tail) where 'tail' is the
last pathname component and 'head' is all preceeding components.
+
+ :param path: Path to split
>>> pathsplit("foo/bar")
('foo', 'bar')
@@ -133,7 +161,7 @@ def pathsplit(path):
"""
split = normpath(path).rsplit('/', 1)
if len(split) == 1:
- return ('', split[0])
+ return (u'', split[0])
return tuple(split)
# Allow pathsplit() to be used as fs.path.split()
@@ -145,6 +173,8 @@ def dirname(path):
This is always equivalent to the 'head' component of the value returned
by pathsplit(path).
+
+ :param path: A FS path
>>> dirname('foo/bar/baz')
'foo/bar'
@@ -158,6 +188,8 @@ def basename(path):
This is always equivalent to the 'head' component of the value returned
by pathsplit(path).
+
+ :param path: A FS path
>>> basename('foo/bar/baz')
'baz'
@@ -168,6 +200,9 @@ def basename(path):
def issamedir(path1, path2):
"""Return true if two paths reference a resource in the same directory.
+
+ :param path1: An FS path
+ :param path2: An FS path
>>> issamedir("foo/bar/baz.txt", "foo/bar/spam.txt")
True
@@ -180,7 +215,10 @@ def issamedir(path1, path2):
def isprefix(path1, path2):
"""Return true is path1 is a prefix of path2.
-
+
+ :param path1: An FS path
+ :param path2: An FS path
+
>>> isprefix("foo/bar", "foo/bar/spam.txt")
True
>>> isprefix("foo/bar/", "foo/bar")
@@ -204,6 +242,8 @@ def isprefix(path1, path2):
def forcedir(path):
"""Ensure the path ends with a trailing /
+
+ :param path: An FS path
>>> forcedir("foo/bar")
'foo/bar/'