diff options
author | rfkelly0 <rfkelly0@67cdc799-7952-0410-af00-57a81ceafa0f> | 2009-05-05 06:02:48 +0000 |
---|---|---|
committer | rfkelly0 <rfkelly0@67cdc799-7952-0410-af00-57a81ceafa0f> | 2009-05-05 06:02:48 +0000 |
commit | e3e5919d40cf9a5f145dc2e3d5cf6e6d8f3e3ed5 (patch) | |
tree | 4c51dffe4edf26ebb94a1dc9832483371de2764d | |
parent | 51a81b318719b480c0211f9dbba33859a120dd49 (diff) | |
download | pyfilesystem-e3e5919d40cf9a5f145dc2e3d5cf6e6d8f3e3ed5.tar.gz |
Condense and cleanup helpers.py/utils.py
git-svn-id: http://pyfilesystem.googlecode.com/svn/branches/rfk-ideas@126 67cdc799-7952-0410-af00-57a81ceafa0f
-rw-r--r-- | fs/helpers.py | 144 | ||||
-rw-r--r-- | fs/utils.py | 9 |
2 files changed, 96 insertions, 57 deletions
diff --git a/fs/helpers.py b/fs/helpers.py index 23e0ef4..7d86ba2 100644 --- a/fs/helpers.py +++ b/fs/helpers.py @@ -1,47 +1,91 @@ -"""Contains a number of standalone functions for path manipulation.""" +""" + + fs.helpers: useful standalone functions for FS path manipulation. + +""" from itertools import chain -def _iteratepath(path, numsplits=None): - path = resolvepath(path) +def iteratepath(path, numsplits=None): + """Iterate over the individual components of a path.""" + path = normpath(path) if not path: return [] - + if path[0] == "/": + path = path[1:] if numsplits == None: - return filter(lambda p:bool(p), path.split('/')) + return path.split('/') else: - return filter(lambda p:bool(p), path.split('/', numsplits)) + return path.split('/', numsplits) +def normpath(path): + """Normalizes a path to be in the format expected by FS objects. -def isabsolutepath(path): - """Returns True if a given path is absolute. + This function remove any leading or trailing slashes, collapses + 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. - >>> isabsolutepath("a/b/c") - False + >>> normpath(r"foo\\bar\\baz") + 'foo/bar/baz' - >>> isabsolutepath("/foo/bar") - True + >>> normpath("/foo//bar/frob/../baz") + '/foo/bar/baz' + + >>> normpath("foo/../../bar") + Traceback (most recent call last) + ... + ValueError: too many backrefs in path 'foo/../../bar' """ - if path: - return path[0] in '\\/' - return False + if not path: + return path -def normpath(path): - """Normalizes a path to be in the formated expected by FS objects. - Returns a new path string. + components = [] + for comp in path.replace('\\','/').split("/"): + if not comp or comp == ".": + pass + elif comp == "..": + try: + components.pop() + except IndexError: + err = "too many backrefs in path '%s'" % (path,) + raise ValueError(err) + else: + components.append(comp) - >>> normpath(r"foo\\bar\\baz") - 'foo/bar/baz' + if path[0] in "\\/": + components.insert(0,"") + + return "/".join(components) + + +def abspath(path): + """Convert the given path to a normalized, absolute path. + path -- A FS path """ - return path.replace('\\', '/') + path = normpath(path) + if not path or path[0] != "/": + path = "/" + path + return path + + +def relpath(path): + """Convert the given path to a normalized, relative path. + + path -- A FS path + """ + path = normpath(path) + if path and path[0] == "/": + path = path[1:] + return path def pathjoin(*paths): - """Joins any number of paths together. Returns a new path string. + """Joins any number of paths together, returning a new path string. paths -- An iterable of path strings @@ -51,39 +95,32 @@ def pathjoin(*paths): >>> pathjoin('foo/bar', '../baz') 'foo/baz' + >>> pathjoin('foo/bar', '/baz') + '/baz' + """ absolute = False relpaths = [] for p in paths: if p: - if p[0] in '\\/': - del relpaths[:] - absolute = True - relpaths.append(p) - - pathstack = [] - - for component in chain(*(normpath(path).split('/') for path in relpaths)): - if component == "..": - if not pathstack: - raise ValueError("Relative path is invalid") - sub = pathstack.pop() - elif component == ".": - pass - elif component: - pathstack.append(component) + if p[0] in '\\/': + del relpaths[:] + absolute = True + relpaths.append(p) + path = normpath("/".join(relpaths)) if absolute: - return "/" + "/".join(pathstack) - else: - return "/".join(pathstack) + path = "/" + path + return path def pathsplit(path): """Splits a path on a path separator. Returns a tuple containing the path up to that last separator and the remaining path component. + path -- A FS path + >>> pathsplit("foo/bar") ('foo', 'bar') @@ -91,12 +128,12 @@ def pathsplit(path): ('foo/bar', 'baz') """ - split = normpath(path).rsplit('/', 1) if len(split) == 1: return ('', split[0]) return tuple(split) + def dirname(path): """Returns the parent directory of a path. @@ -108,6 +145,7 @@ def dirname(path): """ return pathsplit(path)[0] + def resourcename(path): """Returns the resource references by a path. @@ -119,21 +157,11 @@ def resourcename(path): """ return pathsplit(path)[1] -def resolvepath(path): - """Normalises the path and removes any relative path components. - - path -- A path string - - >>> resolvepath(r"foo\\bar\\..\\baz") - 'foo/baz' - - """ - return pathjoin(path) def makerelative(path): """Makes a path relative by removing initial separator. - path -- A path + path -- A FS path >>> makerelative("/foo/bar") 'foo/bar' @@ -144,10 +172,11 @@ def makerelative(path): return path[1:] return path + def makeabsolute(path): - """Makes a path absolute by adding a separater at the beginning of the path. + """Makes a path absolute by adding a separator at the start of the path. - path -- A path + path -- A FS path >>> makeabsolute("foo/bar/baz") '/foo/bar/baz' @@ -158,6 +187,7 @@ def makeabsolute(path): return '/'+path return path + def issamedir(path1, path2): """Return true if two paths reference a resource in the same directory. @@ -169,4 +199,6 @@ def issamedir(path1, path2): >>> issamedir("foo/bar/baz/txt", "spam/eggs/spam.txt") False """ - return pathsplit(resolvepath(path1))[0] == pathsplit(resolvepath(path2))[0] + return pathsplit(normpath(path1))[0] == pathsplit(normpath(path2))[0] + + diff --git a/fs/utils.py b/fs/utils.py index dd863eb..85fa464 100644 --- a/fs/utils.py +++ b/fs/utils.py @@ -1,4 +1,8 @@ -"""Contains a number of high level utility functions for working with FS objects.""" +""" + + fs.utils: high level utility functions for working with FS objects. + +""" import shutil from mountfs import MountFS @@ -82,6 +86,7 @@ def movefile(src_fs, src_path, dst_fs, dst_path, chunk_size=16384): if dst is not None: dst.close() + def movedir(fs1, fs2, ignore_errors=False, chunk_size=16384): """Moves contents of a directory from one filesystem to another. @@ -103,6 +108,7 @@ def movedir(fs1, fs2, ignore_errors=False, chunk_size=16384): mount_fs.mount('dir2', fs2) mount_fs.movedir('dir1', 'dir2', ignore_errors=ignore_errors, chunk_size=chunk_size) + def copydir(fs1, fs2, ignore_errors=False, chunk_size=16384): """Copies contents of a directory from one filesystem to another. @@ -124,6 +130,7 @@ def copydir(fs1, fs2, ignore_errors=False, chunk_size=16384): mount_fs.mount('dir2', fs2) mount_fs.copydir('dir1', 'dir2', ignore_errors=ignore_errors, chunk_size=chunk_size) + def countbytes(count_fs): """Returns the total number of bytes contained within files in a filesystem. |