summaryrefslogtreecommitdiff
path: root/fs/path.py
diff options
context:
space:
mode:
authorwillmcgugan <willmcgugan@67cdc799-7952-0410-af00-57a81ceafa0f>2010-12-23 18:28:58 +0000
committerwillmcgugan <willmcgugan@67cdc799-7952-0410-af00-57a81ceafa0f>2010-12-23 18:28:58 +0000
commit68cf930d18851b4b748f97058404e9307b2dcffa (patch)
treee21ee14bb3c5ce1ae2f2bd5f1cff5d9f694dcaa8 /fs/path.py
parent52a338f9a00e873974a4816c0ea0f6b59734f968 (diff)
downloadpyfilesystem-68cf930d18851b4b748f97058404e9307b2dcffa.tar.gz
Some optimizations
git-svn-id: http://pyfilesystem.googlecode.com/svn/trunk@573 67cdc799-7952-0410-af00-57a81ceafa0f
Diffstat (limited to 'fs/path.py')
-rw-r--r--fs/path.py56
1 files changed, 35 insertions, 21 deletions
diff --git a/fs/path.py b/fs/path.py
index 87a8691..23bac89 100644
--- a/fs/path.py
+++ b/fs/path.py
@@ -10,7 +10,9 @@ optional leading slash).
"""
+import re
+_requires_normalization = re.compile(r'/\.\.|\./|//|\\').search
def normpath(path):
"""Normalizes a path to be in the format expected by FS objects.
@@ -34,24 +36,29 @@ def normpath(path):
ValueError: too many backrefs in path 'foo/../../bar'
"""
- if not path:
+
+ if path in ('', '/'):
return path
+
+ # An early out if there is no need to normalize this paath
+ if not _requires_normalization(path):
+ return path.rstrip('/')
+
components = []
- append = components.append
- for comp in [c for c in path.replace('\\','/').split("/") if c not in ('', '.')]:
+ append = components.append
+ for comp in [c for c in path.replace('\\','/').split("/") if c not in ('', '.')]:
if comp == "..":
try:
components.pop()
- except IndexError:
- err = "too many backrefs in path '%s'" % (path,)
- raise ValueError(err)
+ except IndexError:
+ raise ValueError("too many backrefs in path '%s'" % path)
else:
append(comp)
if path[0] in '\\/':
if not components:
append("")
- components.insert(0, "")
- return "/".join(components)
+ components.insert(0, "")
+ return "/".join(components)
def iteratepath(path, numsplits=None):
@@ -77,20 +84,24 @@ def recursepath(path, reverse=False):
>>> recursepath('a/b/c')
['/', u'/a', u'/a/b', u'/a/b/c']
- """
+ """
+
+ if path in ('', '/'):
+ return [u'/']
+
+ path = abspath(normpath(path)) + '/'
+
paths = [u'/']
- append = paths.append
- path = u'/' + normpath(path.lstrip('/'))
- find = path.find
- pos = 1
- if len(path) > 1:
- while 1:
- pos = find('/', pos + 1)
- if pos == -1:
- append(path)
- break
- append(path[:pos])
-
+ find = path.find
+ append = paths.append
+ pos = 1
+ len_path = len(path)
+
+ while pos < len_path:
+ pos = find('/', pos)
+ append(path[:pos])
+ pos += 1
+
if reverse:
return paths[::-1]
return paths
@@ -534,3 +545,6 @@ def iswildcard(path):
assert path is not None
base_chars = frozenset(basename(path))
return not base_chars.isdisjoint(_wild_chars)
+
+if __name__ == "__main__":
+ print recursepath('a/b/c') \ No newline at end of file