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)
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)
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
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