"""Path utility to:
* split a path entirely
* join it
* return true commonprefix on paths
>>> import os
>>> path = os.getcwd()
>>> join(split(path)) == path
True
>>> p1, p2, p3 = (os.path.join(*'abc'), os.path.join(*'abd'),
... os.path.join(*'ab'))
>>> commonprefix(p1, p2, p3) == p3
True
>>> p1, p2 = os.path.join(*'xyz'), os.path.join(*'abd')
>>> commonprefix(p1, p2)
''
"""
import os.path
def isplit(path):
"Generator splitting a path"
dirname, basename = os.path.split(path)
if path == dirname:
# stop recursivity
yield path
elif dirname:
# continue recursivity
for i in isplit(dirname):
yield i
if basename:
# return tail
yield basename
def join(iterable):
"""Join iterable's items as a path string
>>> join(('a', 'b')) == os.path.join('a', 'b')
True
"""
items = tuple(iterable)
if not items:
return ''
return os.path.join(*items)
def split(path):
"""Return the folder list of the given path
>>> split(os.path.join('a', 'b'))
('a', 'b')
"""
return tuple(isplit(path))
def commonprefix(*paths):
"""Return the common prefix path of the given paths
>>> commonprefix(os.path.join('a', 'c'), os.path.join('a', 'b'))
'a'
"""
paths = map(split, paths)
if not paths: return ''
p1 = min(paths)
p2 = max(paths)
for i, c in enumerate(p1):
if c != p2[i]:
return join(p1[:i])
return join(p1)
if __name__ == '__main__':
import doctest
doctest.testmod()
Diff to Previous Revision
--- revision 4 2011-04-06 20:29:06
+++ revision 5 2011-04-06 20:29:46
@@ -1,9 +1,10 @@
"""Path utility to:
-* split a path entirely,
-* join it,
-* return true commonprefix on paths.
+* split a path entirely
+* join it
+* return true commonprefix on paths
+ >>> import os
>>> path = os.getcwd()
>>> join(split(path)) == path
True
@@ -12,10 +13,11 @@
... os.path.join(*'ab'))
>>> commonprefix(p1, p2, p3) == p3
True
+ >>> p1, p2 = os.path.join(*'xyz'), os.path.join(*'abd')
+ >>> commonprefix(p1, p2)
+ ''
"""
-import os
import os.path
-from itertools import takewhile
def isplit(path):
"Generator splitting a path"
@@ -30,14 +32,6 @@
if basename:
# return tail
yield basename
-
-def split(path):
- """Return the folder list of the given path
-
- >>> split(os.path.join('a', 'b'))
- ['a', 'b']
- """
- return list(isplit(path))
def join(iterable):
"""Join iterable's items as a path string
@@ -45,20 +39,18 @@
>>> join(('a', 'b')) == os.path.join('a', 'b')
True
"""
- return os.path.join(*iterable)
+ items = tuple(iterable)
+ if not items:
+ return ''
+ return os.path.join(*items)
+
+def split(path):
+ """Return the folder list of the given path
-def _equal_elem(iterable):
- """Return True if all elements of the container are equal.
-
- >>> _equal_elem((0,1)), _equal_elem((0,0))
- (False, True)
+ >>> split(os.path.join('a', 'b'))
+ ('a', 'b')
"""
- first = _first(iterable)
- return all(x == first for x in iterable)
-
-def _first(iterable):
- "Return first element of an iterable"
- return next(iter(iterable))
+ return tuple(isplit(path))
def commonprefix(*paths):
"""Return the common prefix path of the given paths
@@ -66,8 +58,14 @@
>>> commonprefix(os.path.join('a', 'c'), os.path.join('a', 'b'))
'a'
"""
- tuples = zip(*map(isplit, paths))
- return join(map(_first, takewhile(_equal_elem, tuples)))
+ paths = map(split, paths)
+ if not paths: return ''
+ p1 = min(paths)
+ p2 = max(paths)
+ for i, c in enumerate(p1):
+ if c != p2[i]:
+ return join(p1[:i])
+ return join(p1)
if __name__ == '__main__':
import doctest