"""Path utility to: * split a path entirely, * join it, * return true commonprefix on paths. >>> 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 """ import os import os.path from itertools import takewhile 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 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 >>> join(('a', 'b')) == os.path.join('a', 'b') True """ return os.path.join(*iterable) def _equal_elem(iterable): """Return True if all elements of the container are equal. >>> _equal_elem((0,1)), _equal_elem((0,0)) (False, True) """ first = _first(iterable) return all(x == first for x in iterable) def _first(iterable): "Return first element of an iterable" return next(iter(iterable)) def commonprefix(*paths): """Return the common prefix path of the given paths >>> 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))) if __name__ == '__main__': import doctest doctest.testmod()