Coverage for torxtools/pathtools.py: 56%

36 statements  

« prev     ^ index     » next       coverage.py v7.5.1, created at 2024-05-18 01:02 +0000

1""" 

2Functions for working with filesystem paths and finding files. 

3 

4The :func:`expandpath` does recursive shell-like expansion of paths from lists. 

5""" 

6import os 

7import typing as t 

8 

9import boltons.pathutils 

10 

11try: 

12 pass 

13except ImportError: 

14 pass 

15 

16__all__ = [ 

17 "cachedir", 

18 "expandpath", 

19 "find_pyproject", 

20] 

21 

22 

23def expandpath(path: t.Union[str, t.List[str], None]) -> t.Union[str, t.List[str], None]: 

24 """ 

25 Recursive shell-like expansion of environment variables and tilde home directory. 

26 

27 Parameters 

28 ---------- 

29 path: str, [str], None 

30 a single path, a list of paths, or none. 

31 

32 Returns 

33 ------- 

34 str, [str], None: 

35 a single expanded path, a list of expanded path, or none 

36 

37 Example 

38 ------- 

39 

40 .. code-block:: python 

41 

42 import os 

43 from torxtools import pathtools 

44 

45 os.environ["SPAM"] = "eggs" 

46 assert pathtools.expandpath(["~/$SPAM/one", "~/$SPAM/two"]) == [ 

47 os.path.expanduser("~/eggs/one"), 

48 os.path.expanduser("~/eggs/two"), 

49 ] 

50 

51 See Also 

52 -------- 

53 :py:func:`boltons:boltons.pathutils.expandpath` 

54 """ 

55 

56 def _expandpath(path): 

57 if path is None: 

58 return None 

59 if isinstance(path, list): 

60 return [_expandpath(p) for p in path] 

61 return boltons.pathutils.expandpath(path) 

62 

63 return _expandpath(path) 

64 

65 

66def cachedir(appname: str, path: str) -> str: 

67 """ 

68 Find a suitable location for cache files. 

69 

70 Parameters 

71 ---------- 

72 appname: str 

73 Name of application. Used as last part of the cachedir path. 

74 

75 path: str 

76 a single path, a list of paths, or none. 

77 

78 Returns 

79 ------- 

80 str, None: 

81 a suitable cachedir, created if not existing 

82 """ 

83 

84 def create_cachedir(path: str) -> str: 

85 # Check that path exists and is correct type 

86 if os.path.isdir(path): 

87 return path 

88 os.mkdir(path) 

89 return path 

90 

91 # Path was passed, create it 

92 if path: 

93 return create_cachedir(path) 

94 

95 if not appname: 

96 return None 

97 

98 # Root: use /var/cache 

99 if os.geteuid() == 0: 

100 path = expandpath(f"/var/cache/{appname}") 

101 return create_cachedir(path) 

102 

103 # Non-Root: use xdg 

104 path = expandpath(f"$XDG_CACHE_HOME/{appname}") 

105 return create_cachedir(path) 

106 

107 

108def find_pyproject(path: str) -> str: 

109 """ 

110 Find location of "pyproject.toml" 

111 

112 Parameters 

113 ---------- 

114 path: str 

115 a single path to a directory to search down recursivly. 

116 

117 Returns 

118 ------- 

119 str: 

120 a absolute path to the location of 'pyproject.toml' 

121 

122 Example 

123 ------- 

124 

125 .. code-block:: python 

126 

127 import os 

128 from torxtools import pathtools 

129 

130 pyproject = pathtools.find_pyproject(os.path.dirname(__file__)) 

131 """ 

132 

133 path = os.path.abspath(path) 

134 while not os.path.exists(f"{path}/pyproject.toml"): 

135 path = os.path.dirname(path) 

136 if path == "/": 136 ↛ 137line 136 didn't jump to line 137, because the condition on line 136 was never true

137 raise FileNotFoundError("Failed to find 'pyproject.toml' file") 

138 

139 return f"{path}/pyproject.toml"