| 261 | |
| 262 | |
| 263 | def _remove_path_dot_segments(path: str) -> str: |
| 264 | # See http://tools.ietf.org/html/rfc3986#section-5.2.4 for pseudo-code |
| 265 | segments = path.split("/") # Turn the path into a list of segments |
| 266 | output = [] # Initialize the variable to use to store output |
| 267 | |
| 268 | for segment in segments: |
| 269 | # '.' is the current directory, so ignore it, it is superfluous |
| 270 | if segment == ".": |
| 271 | continue |
| 272 | # Anything other than '..', should be appended to the output |
| 273 | if segment != "..": |
| 274 | output.append(segment) |
| 275 | # In this case segment == '..', if we can, we should pop the last |
| 276 | # element |
| 277 | elif output: |
| 278 | output.pop() |
| 279 | |
| 280 | # If the path starts with '/' and the output is empty or the first string |
| 281 | # is non-empty |
| 282 | if path.startswith("/") and (not output or output[0]): |
| 283 | output.insert(0, "") |
| 284 | |
| 285 | # If the path starts with '/.' or '/..' ensure we add one more empty |
| 286 | # string to add a trailing '/' |
| 287 | if path.endswith(("/.", "/..")): |
| 288 | output.append("") |
| 289 | |
| 290 | return "/".join(output) |
| 291 | |
| 292 | |
| 293 | @typing.overload |