blob: e89c00b3d97c88339187c3cda03445a7822807e0 (
plain) (
blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
|
import os
import platform
_WINDOWS_PLATFORM = platform.system() == "Windows"
def combine(path1: str, path2) -> str:
if not path1:
return path2
return "{}/{}".format(path1.rstrip("/"), path2.lstrip("/"))
def split(path: str) -> tuple[str, str]:
if "/" not in path:
return ("", path)
split = path.rsplit("/", 1)
return (split[0] or "/", split[1])
def dirname(path: str) -> str:
return split(path)[0]
def basename(path: str) -> str:
return split(path)[1]
def forcedir(path: str) -> str:
# Ensure the path ends with a trailing forward slash.
if not path.endswith("/"):
return path + "/"
return path
def abspath(path: str) -> str:
# FS objects have no concept of a *current directory*. This simply
# ensures the path starts with a forward slash.
if not path.startswith("/"):
return "/" + path
return path
def isbase(path1: str, path2: str) -> bool:
# Check if `path1` is a base or prefix of `path2`.
_path1 = forcedir(abspath(path1))
_path2 = forcedir(abspath(path2))
return _path2.startswith(_path1)
def frombase(path1: str, path2: str) -> str:
# Get the final path of `path2` that isn't in `path1`.
if not isbase(path1, path2):
raise ValueError(f"path1 must be a prefix of path2: {path1!r} vs {path2!r}")
return path2[len(path1) :]
def relpath(path: str) -> str:
return path.lstrip("/")
def normpath(path: str) -> str:
normalized = os.path.normpath(path)
if _WINDOWS_PLATFORM:
# os.path.normpath converts backslashes to forward slashes on Windows
# but we want forward slashes, so we convert them back
normalized = normalized.replace("\\", "/")
return normalized
|