(path, relative_to, follow_path_symlink=True)
| 133 | |
| 134 | @memoize |
| 135 | def RelativePath(path, relative_to, follow_path_symlink=True): |
| 136 | # Assuming both |path| and |relative_to| are relative to the current |
| 137 | # directory, returns a relative path that identifies path relative to |
| 138 | # relative_to. |
| 139 | # If |follow_symlink_path| is true (default) and |path| is a symlink, then |
| 140 | # this method returns a path to the real file represented by |path|. If it is |
| 141 | # false, this method returns a path to the symlink. If |path| is not a |
| 142 | # symlink, this option has no effect. |
| 143 | |
| 144 | # Convert to normalized (and therefore absolute paths). |
| 145 | path = os.path.realpath(path) if follow_path_symlink else os.path.abspath(path) |
| 146 | relative_to = os.path.realpath(relative_to) |
| 147 | |
| 148 | # On Windows, we can't create a relative path to a different drive, so just |
| 149 | # use the absolute path. |
| 150 | if sys.platform == "win32" and ( |
| 151 | os.path.splitdrive(path)[0].lower() |
| 152 | != os.path.splitdrive(relative_to)[0].lower() |
| 153 | ): |
| 154 | return path |
| 155 | |
| 156 | # Split the paths into components. |
| 157 | path_split = path.split(os.path.sep) |
| 158 | relative_to_split = relative_to.split(os.path.sep) |
| 159 | |
| 160 | # Determine how much of the prefix the two paths share. |
| 161 | prefix_len = len(os.path.commonprefix([path_split, relative_to_split])) |
| 162 | |
| 163 | # Put enough ".." components to back up out of relative_to to the common |
| 164 | # prefix, and then append the part of path_split after the common prefix. |
| 165 | relative_split = [os.path.pardir] * ( |
| 166 | len(relative_to_split) - prefix_len |
| 167 | ) + path_split[prefix_len:] |
| 168 | |
| 169 | if len(relative_split) == 0: |
| 170 | # The paths were the same. |
| 171 | return "" |
| 172 | |
| 173 | # Turn it back into a string and we're done. |
| 174 | return os.path.join(*relative_split) |
| 175 | |
| 176 | |
| 177 | @memoize |
no test coverage detected
searching dependent graphs…