Example #1
0
def safe_path(path, posix=False):
    """
    Convert `path` to a safe and portable POSIX path usable on multiple OSes. The
    returned path is an ASCII-only byte string, resolved for relative segments and
    itself relative.

    The `path` is treated as a POSIX path if `posix` is True or as a Windows path
    with blackslash separators otherwise.
    """
    # if the path is UTF, try to use unicode instead
    if not isinstance(path, unicode):
        path = as_unicode(path)

    path = path.strip()

    if not is_posixpath(path):
        path = as_winpath(path)
        posix = False

    path = resolve(path, posix)

    _pathmod, path_sep = path_handlers(path, posix)

    segments = [s.strip() for s in path.split(path_sep) if s.strip()]
    segments = [portable_filename(s) for s in segments]

    # print('safe_path: orig:', orig_path, 'segments:', segments)

    if not segments:
        return '_'

    # always return posix
    sep = u'/' if isinstance(path, unicode) else b'/'
    path = sep.join(segments)
    return as_posixpath(path)
Example #2
0
def safe_path(path, posix=False):
    """
    Convert `path` to a safe and portable POSIX path usable on multiple OSes. The
    returned path is an ASCII-only byte string, resolved for relative segments and
    itself relative.

    The `path` is treated as a POSIX path if `posix` is True or as a Windows path
    with blackslash separators otherwise.
    """
    # if the path is UTF, try to use unicode instead
    if not isinstance(path, unicode):
        path = as_unicode(path)

    path = path.strip()

    if not is_posixpath(path):
        path = as_winpath(path)
        posix = False

    path = resolve(path, posix)

    _pathmod, path_sep = path_handlers(path, posix)

    segments = [s.strip() for s in path.split(path_sep) if s.strip()]
    segments = [portable_filename(s) for s in segments]

    # print('safe_path: orig:', orig_path, 'segments:', segments)

    if not segments:
        return '_'

    # always return posix
    sep = u'/' if isinstance(path, unicode) else b'/'
    path = sep.join(segments)
    return as_posixpath(path)
Example #3
0
def resolve(path, posix=True):
    """
    Return a resolved relative POSIX path from `path` where extra slashes including
    leading and trailing slashes are removed, dot '.' and dotdot '..' path segments
    have been removed or resolved as possible. When a dotdot path segment cannot be
    further resolved and would be "escaping" from the provided path "tree", it is
    replaced by the string 'dotdot'.

    The `path` is treated as a POSIX path if `posix` is True (default) or as a
    Windows path with blackslash separators otherwise.
    """
    is_unicode = isinstance(path, unicode)
    dot = is_unicode and u'.' or b'.'

    if not path:
        return dot

    path = path.strip()
    if not path:
        return dot

    if not is_posixpath(path):
        path = as_winpath(path)
        posix = False

    pathmod, path_sep = path_handlers(path, posix)

    path = path.strip(path_sep)
    segments = [s.strip() for s in path.split(path_sep) if s.strip()]

    # remove empty (// or ///) or blank (space only) or single dot segments
    segments = [s for s in segments if s and s != dot]

    path = path_sep.join(segments)

    # resolves . dot, .. dotdot
    path = pathmod.normpath(path)

    segments = path.split(path_sep)

    # remove empty or blank segments
    segments = [s.strip() for s in segments if s and s.strip()]

    # is this a windows absolute path? if yes strip the colon to make this relative
    if segments and len(segments[0]) == 2 and segments[0].endswith(':'):
        segments[0] = segments[0][:-1]

    # replace any remaining (usually leading) .. segment with a literal "dotdot"
    dotdot = is_unicode and u'dotdot' or b'dotdot'
    dd = is_unicode and u'..' or b'..'
    segments = [dotdot if s == dd else s for s in segments if s]
    if segments:
        path = path_sep.join(segments)
    else:
        path = dot

    path = as_posixpath(path)

    return path
Example #4
0
def resolve(path, posix=True):
    """
    Return a resolved relative POSIX path from `path` where extra slashes including
    leading and trailing slashes are removed, dot '.' and dotdot '..' path segments
    have been removed or resolved as possible. When a dotdot path segment cannot be
    further resolved and would be "escaping" from the provided path "tree", it is
    replaced by the string 'dotdot'.

    The `path` is treated as a POSIX path if `posix` is True (default) or as a
    Windows path with blackslash separators otherwise.
    """
    is_unicode = isinstance(path, unicode)
    dot = is_unicode and u'.' or b'.'

    if not path:
        return dot

    path = path.strip()
    if not path:
        return dot

    if not is_posixpath(path):
        path = as_winpath(path)
        posix = False

    pathmod, path_sep = path_handlers(path, posix)

    path = path.strip(path_sep)
    segments = [s.strip() for s in path.split(path_sep) if s.strip()]

    # remove empty (// or ///) or blank (space only) or single dot segments
    segments = [s for s in segments if s and s != dot]

    path = path_sep.join(segments)

    # resolves . dot, .. dotdot
    path = pathmod.normpath(path)

    segments = path.split(path_sep)

    # remove empty or blank segments
    segments = [s.strip() for s in segments if s and s.strip()]

    # is this a windows absolute path? if yes strip the colon to make this relative
    if segments and len(segments[0]) == 2 and segments[0].endswith(':'):
        segments[0] = segments[0][:-1]

    # replace any remaining (usually leading) .. segment with a literal "dotdot"
    dotdot = is_unicode and u'dotdot' or b'dotdot'
    dd = is_unicode and u'..' or b'..'
    segments = [dotdot if s == dd else s for s in segments if s]
    if segments:
        path = path_sep.join(segments)
    else:
        path = dot

    path = as_posixpath(path)

    return path
Example #5
0
def path_handlers(path, posix=True):
    """
    Return a path module and path separator to use for handling (e.g. split and join)
    `path` using either POSIX or Windows conventions depending on the `path` content.
    Force usage of POSIX conventions if `posix` is True.
    """
    # determine if we use posix or windows path handling
    is_posix = is_posixpath(path)
    use_posix = posix or is_posix
    pathmod = use_posix and posixpath or ntpath
    path_sep = POSIX_PATH_SEP if use_posix else WIN_PATH_SEP
    path_sep = isinstance(path, unicode) and unicode(path_sep) or path_sep
    return pathmod, path_sep
Example #6
0
def path_handlers(path, posix=True):
    """
    Return a path module and path separator to use for handling (e.g. split and join)
    `path` using either POSIX or Windows conventions depending on the `path` content.
    Force usage of POSIX conventions if `posix` is True.
    """
    # determine if we use posix or windows path handling
    is_posix = is_posixpath(path)
    use_posix = posix or is_posix
    pathmod = use_posix and posixpath or ntpath
    path_sep = POSIX_PATH_SEP if use_posix else WIN_PATH_SEP
    path_sep = isinstance(path, unicode) and unicode(path_sep) or path_sep
    return pathmod, path_sep