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" fr
(path, posix=True)
| 80 | |
| 81 | |
| 82 | def resolve(path, posix=True): |
| 83 | """ |
| 84 | Return a resolved relative POSIX path from `path` where extra slashes |
| 85 | including leading and trailing slashes are removed, dot '.' and dotdot '..' |
| 86 | path segments have been removed or resolved as possible. When a dotdot path |
| 87 | segment cannot be further resolved and would be "escaping" from the provided |
| 88 | path "tree", it is replaced by the string 'dotdot'. |
| 89 | |
| 90 | The `path` is treated as a POSIX path if `posix` is True (default) or as a |
| 91 | Windows path with blackslash separators otherwise. |
| 92 | """ |
| 93 | if not path: |
| 94 | return "." |
| 95 | |
| 96 | path = path.strip() |
| 97 | if not path: |
| 98 | return "." |
| 99 | |
| 100 | if not is_posixpath(path): |
| 101 | path = as_winpath(path) |
| 102 | posix = False |
| 103 | |
| 104 | pathmod, path_sep = path_handlers(path, posix) |
| 105 | |
| 106 | path = path.strip(path_sep) |
| 107 | segments = [s.strip() for s in path.split(path_sep) if s.strip()] |
| 108 | |
| 109 | # remove empty (// or ///) or blank (space only) or single dot segments |
| 110 | segments = [s for s in segments if s and s != "."] |
| 111 | |
| 112 | path = path_sep.join(segments) |
| 113 | |
| 114 | # resolves . dot, .. dotdot |
| 115 | path = pathmod.normpath(path) |
| 116 | |
| 117 | segments = path.split(path_sep) |
| 118 | |
| 119 | # remove empty or blank segments |
| 120 | segments = [s.strip() for s in segments if s and s.strip()] |
| 121 | |
| 122 | # is this a windows absolute path? if yes strip the colon to make this relative |
| 123 | if segments and len(segments[0]) == 2 and segments[0].endswith(":"): |
| 124 | segments[0] = segments[0][:-1] |
| 125 | |
| 126 | # replace any remaining (usually leading) .. segment with a literal "dotdot" |
| 127 | dotdot = "dotdot" |
| 128 | dd = ".." |
| 129 | segments = [dotdot if s == dd else s for s in segments if s] |
| 130 | if segments: |
| 131 | path = path_sep.join(segments) |
| 132 | else: |
| 133 | path = "." |
| 134 | |
| 135 | path = as_posixpath(path) |
| 136 | |
| 137 | return path |
| 138 | |
| 139 |
no test coverage detected