Welcome, guest | Sign In | My Account | Store | Cart
"""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

History