def normpath(path, trailing=False):
    """Normalize path, eliminating double slashes, etc."""
    comps = path.split('/')
    new_comps = []
    for comp in comps:
        if comp == '':
            continue
        if comp in ('.', '..'):
            raise ValueError('relative paths not allowed')
        new_comps.append(comp)
    new_path = '/'.join(new_comps)
    if trailing is True and path.endswith('/'):
        new_path += '/'
    if path.startswith('/'):
        return '/' + new_path
    return new_path


def join(a, *p):
    """Join two or more pathname components, inserting '/' as needed.

    If any component is an absolute path, all previous path components
    will be discarded.

    """
    path = a
    for b in p:
        if b.startswith('/'):
            path = b
        elif path == '' or path.endswith('/'):
            path += b
        else:
            path += '/' + b
    return path


def isabs(s):
    """Test whether a path is absolute"""
    return s.startswith('/')


def basename(p):
    """Returns the final component of a pathname"""
    i = p.rfind('/') + 1
    return p[i:]


def _prefix_root(root, path, trailing=False):
    """Prepend a root to a path. """
    return normpath(join(_norm_root(root), path.lstrip('/')), trailing=trailing)


def _norm_root(root):
    return normpath(join('/', root))
