Coverage for torxtools/pathtools.py: 54%

36 statements  

« prev     ^ index     » next       coverage.py v7.6.9, created at 2024-12-20 22: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""" 

6 

7import os 

8import typing as t 

9 

10import boltons.pathutils 

11 

12try: 

13 pass 

14except ImportError: 

15 pass 

16 

17__all__ = [ 

18 "cachedir", 

19 "expandpath", 

20 "find_pyproject", 

21] 

22 

23 

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

25 """ 

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

27 

28 Parameters 

29 ---------- 

30 path: str, [str], None 

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

32 

33 Returns 

34 ------- 

35 str, [str], None: 

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

37 

38 Example 

39 ------- 

40 

41 .. code-block:: python 

42 

43 import os 

44 from torxtools import pathtools 

45 

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

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

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

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

50 ] 

51 

52 See Also 

53 -------- 

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

55 """ 

56 

57 def _expandpath(path): 

58 if path is None: 

59 return None 

60 if isinstance(path, list): 

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

62 return boltons.pathutils.expandpath(path) 

63 

64 return _expandpath(path) 

65 

66 

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

68 """ 

69 Find a suitable location for cache files. 

70 

71 Parameters 

72 ---------- 

73 appname: str 

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

75 

76 path: str 

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

78 

79 Returns 

80 ------- 

81 str, None: 

82 a suitable cachedir, created if not existing 

83 """ 

84 

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

86 # Check that path exists and is correct type 

87 if os.path.isdir(path): 

88 return path 

89 os.mkdir(path) 

90 return path 

91 

92 # Path was passed, create it 

93 if path: 

94 return create_cachedir(path) 

95 

96 if not appname: 

97 return None 

98 

99 # Root: use /var/cache 

100 if os.geteuid() == 0: 

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

102 return create_cachedir(path) 

103 

104 # Non-Root: use xdg 

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

106 return create_cachedir(path) 

107 

108 

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

110 """ 

111 Find location of "pyproject.toml" 

112 

113 Parameters 

114 ---------- 

115 path: str 

116 a single path to a directory to search down recursively. 

117 

118 Returns 

119 ------- 

120 str: 

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

122 

123 Example 

124 ------- 

125 

126 .. code-block:: python 

127 

128 import os 

129 from torxtools import pathtools 

130 

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

132 """ 

133 

134 path = os.path.abspath(path) 

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

136 path = os.path.dirname(path) 

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

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

139 

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