Mercurial > repos > guerler > springsuite
comparison planemo/lib/python3.7/site-packages/pip/_internal/utils/appdirs.py @ 1:56ad4e20f292 draft
"planemo upload commit 6eee67778febed82ddd413c3ca40b3183a3898f1"
author | guerler |
---|---|
date | Fri, 31 Jul 2020 00:32:28 -0400 |
parents | |
children |
comparison
equal
deleted
inserted
replaced
0:d30785e31577 | 1:56ad4e20f292 |
---|---|
1 """ | |
2 This code was taken from https://github.com/ActiveState/appdirs and modified | |
3 to suit our purposes. | |
4 """ | |
5 from __future__ import absolute_import | |
6 | |
7 import os | |
8 import sys | |
9 | |
10 from pip._vendor.six import PY2, text_type | |
11 | |
12 from pip._internal.utils.compat import WINDOWS, expanduser | |
13 from pip._internal.utils.typing import MYPY_CHECK_RUNNING | |
14 | |
15 if MYPY_CHECK_RUNNING: | |
16 from typing import List | |
17 | |
18 | |
19 def user_cache_dir(appname): | |
20 # type: (str) -> str | |
21 r""" | |
22 Return full path to the user-specific cache dir for this application. | |
23 | |
24 "appname" is the name of application. | |
25 | |
26 Typical user cache directories are: | |
27 macOS: ~/Library/Caches/<AppName> | |
28 Unix: ~/.cache/<AppName> (XDG default) | |
29 Windows: C:\Users\<username>\AppData\Local\<AppName>\Cache | |
30 | |
31 On Windows the only suggestion in the MSDN docs is that local settings go | |
32 in the `CSIDL_LOCAL_APPDATA` directory. This is identical to the | |
33 non-roaming app data dir (the default returned by `user_data_dir`). Apps | |
34 typically put cache data somewhere *under* the given dir here. Some | |
35 examples: | |
36 ...\Mozilla\Firefox\Profiles\<ProfileName>\Cache | |
37 ...\Acme\SuperApp\Cache\1.0 | |
38 | |
39 OPINION: This function appends "Cache" to the `CSIDL_LOCAL_APPDATA` value. | |
40 """ | |
41 if WINDOWS: | |
42 # Get the base path | |
43 path = os.path.normpath(_get_win_folder("CSIDL_LOCAL_APPDATA")) | |
44 | |
45 # When using Python 2, return paths as bytes on Windows like we do on | |
46 # other operating systems. See helper function docs for more details. | |
47 if PY2 and isinstance(path, text_type): | |
48 path = _win_path_to_bytes(path) | |
49 | |
50 # Add our app name and Cache directory to it | |
51 path = os.path.join(path, appname, "Cache") | |
52 elif sys.platform == "darwin": | |
53 # Get the base path | |
54 path = expanduser("~/Library/Caches") | |
55 | |
56 # Add our app name to it | |
57 path = os.path.join(path, appname) | |
58 else: | |
59 # Get the base path | |
60 path = os.getenv("XDG_CACHE_HOME", expanduser("~/.cache")) | |
61 | |
62 # Add our app name to it | |
63 path = os.path.join(path, appname) | |
64 | |
65 return path | |
66 | |
67 | |
68 def user_data_dir(appname, roaming=False): | |
69 # type: (str, bool) -> str | |
70 r""" | |
71 Return full path to the user-specific data dir for this application. | |
72 | |
73 "appname" is the name of application. | |
74 If None, just the system directory is returned. | |
75 "roaming" (boolean, default False) can be set True to use the Windows | |
76 roaming appdata directory. That means that for users on a Windows | |
77 network setup for roaming profiles, this user data will be | |
78 sync'd on login. See | |
79 <http://technet.microsoft.com/en-us/library/cc766489(WS.10).aspx> | |
80 for a discussion of issues. | |
81 | |
82 Typical user data directories are: | |
83 macOS: ~/Library/Application Support/<AppName> | |
84 if it exists, else ~/.config/<AppName> | |
85 Unix: ~/.local/share/<AppName> # or in | |
86 $XDG_DATA_HOME, if defined | |
87 Win XP (not roaming): C:\Documents and Settings\<username>\ ... | |
88 ...Application Data\<AppName> | |
89 Win XP (roaming): C:\Documents and Settings\<username>\Local ... | |
90 ...Settings\Application Data\<AppName> | |
91 Win 7 (not roaming): C:\\Users\<username>\AppData\Local\<AppName> | |
92 Win 7 (roaming): C:\\Users\<username>\AppData\Roaming\<AppName> | |
93 | |
94 For Unix, we follow the XDG spec and support $XDG_DATA_HOME. | |
95 That means, by default "~/.local/share/<AppName>". | |
96 """ | |
97 if WINDOWS: | |
98 const = roaming and "CSIDL_APPDATA" or "CSIDL_LOCAL_APPDATA" | |
99 path = os.path.join(os.path.normpath(_get_win_folder(const)), appname) | |
100 elif sys.platform == "darwin": | |
101 path = os.path.join( | |
102 expanduser('~/Library/Application Support/'), | |
103 appname, | |
104 ) if os.path.isdir(os.path.join( | |
105 expanduser('~/Library/Application Support/'), | |
106 appname, | |
107 ) | |
108 ) else os.path.join( | |
109 expanduser('~/.config/'), | |
110 appname, | |
111 ) | |
112 else: | |
113 path = os.path.join( | |
114 os.getenv('XDG_DATA_HOME', expanduser("~/.local/share")), | |
115 appname, | |
116 ) | |
117 | |
118 return path | |
119 | |
120 | |
121 def user_config_dir(appname, roaming=True): | |
122 # type: (str, bool) -> str | |
123 """Return full path to the user-specific config dir for this application. | |
124 | |
125 "appname" is the name of application. | |
126 If None, just the system directory is returned. | |
127 "roaming" (boolean, default True) can be set False to not use the | |
128 Windows roaming appdata directory. That means that for users on a | |
129 Windows network setup for roaming profiles, this user data will be | |
130 sync'd on login. See | |
131 <http://technet.microsoft.com/en-us/library/cc766489(WS.10).aspx> | |
132 for a discussion of issues. | |
133 | |
134 Typical user data directories are: | |
135 macOS: same as user_data_dir | |
136 Unix: ~/.config/<AppName> | |
137 Win *: same as user_data_dir | |
138 | |
139 For Unix, we follow the XDG spec and support $XDG_CONFIG_HOME. | |
140 That means, by default "~/.config/<AppName>". | |
141 """ | |
142 if WINDOWS: | |
143 path = user_data_dir(appname, roaming=roaming) | |
144 elif sys.platform == "darwin": | |
145 path = user_data_dir(appname) | |
146 else: | |
147 path = os.getenv('XDG_CONFIG_HOME', expanduser("~/.config")) | |
148 path = os.path.join(path, appname) | |
149 | |
150 return path | |
151 | |
152 | |
153 # for the discussion regarding site_config_dirs locations | |
154 # see <https://github.com/pypa/pip/issues/1733> | |
155 def site_config_dirs(appname): | |
156 # type: (str) -> List[str] | |
157 r"""Return a list of potential user-shared config dirs for this application. | |
158 | |
159 "appname" is the name of application. | |
160 | |
161 Typical user config directories are: | |
162 macOS: /Library/Application Support/<AppName>/ | |
163 Unix: /etc or $XDG_CONFIG_DIRS[i]/<AppName>/ for each value in | |
164 $XDG_CONFIG_DIRS | |
165 Win XP: C:\Documents and Settings\All Users\Application ... | |
166 ...Data\<AppName>\ | |
167 Vista: (Fail! "C:\ProgramData" is a hidden *system* directory | |
168 on Vista.) | |
169 Win 7: Hidden, but writeable on Win 7: | |
170 C:\ProgramData\<AppName>\ | |
171 """ | |
172 if WINDOWS: | |
173 path = os.path.normpath(_get_win_folder("CSIDL_COMMON_APPDATA")) | |
174 pathlist = [os.path.join(path, appname)] | |
175 elif sys.platform == 'darwin': | |
176 pathlist = [os.path.join('/Library/Application Support', appname)] | |
177 else: | |
178 # try looking in $XDG_CONFIG_DIRS | |
179 xdg_config_dirs = os.getenv('XDG_CONFIG_DIRS', '/etc/xdg') | |
180 if xdg_config_dirs: | |
181 pathlist = [ | |
182 os.path.join(expanduser(x), appname) | |
183 for x in xdg_config_dirs.split(os.pathsep) | |
184 ] | |
185 else: | |
186 pathlist = [] | |
187 | |
188 # always look in /etc directly as well | |
189 pathlist.append('/etc') | |
190 | |
191 return pathlist | |
192 | |
193 | |
194 # -- Windows support functions -- | |
195 | |
196 def _get_win_folder_from_registry(csidl_name): | |
197 # type: (str) -> str | |
198 """ | |
199 This is a fallback technique at best. I'm not sure if using the | |
200 registry for this guarantees us the correct answer for all CSIDL_* | |
201 names. | |
202 """ | |
203 import _winreg | |
204 | |
205 shell_folder_name = { | |
206 "CSIDL_APPDATA": "AppData", | |
207 "CSIDL_COMMON_APPDATA": "Common AppData", | |
208 "CSIDL_LOCAL_APPDATA": "Local AppData", | |
209 }[csidl_name] | |
210 | |
211 key = _winreg.OpenKey( | |
212 _winreg.HKEY_CURRENT_USER, | |
213 r"Software\Microsoft\Windows\CurrentVersion\Explorer\Shell Folders" | |
214 ) | |
215 directory, _type = _winreg.QueryValueEx(key, shell_folder_name) | |
216 return directory | |
217 | |
218 | |
219 def _get_win_folder_with_ctypes(csidl_name): | |
220 # type: (str) -> str | |
221 csidl_const = { | |
222 "CSIDL_APPDATA": 26, | |
223 "CSIDL_COMMON_APPDATA": 35, | |
224 "CSIDL_LOCAL_APPDATA": 28, | |
225 }[csidl_name] | |
226 | |
227 buf = ctypes.create_unicode_buffer(1024) | |
228 ctypes.windll.shell32.SHGetFolderPathW(None, csidl_const, None, 0, buf) | |
229 | |
230 # Downgrade to short path name if have highbit chars. See | |
231 # <http://bugs.activestate.com/show_bug.cgi?id=85099>. | |
232 has_high_char = False | |
233 for c in buf: | |
234 if ord(c) > 255: | |
235 has_high_char = True | |
236 break | |
237 if has_high_char: | |
238 buf2 = ctypes.create_unicode_buffer(1024) | |
239 if ctypes.windll.kernel32.GetShortPathNameW(buf.value, buf2, 1024): | |
240 buf = buf2 | |
241 | |
242 return buf.value | |
243 | |
244 | |
245 if WINDOWS: | |
246 try: | |
247 import ctypes | |
248 _get_win_folder = _get_win_folder_with_ctypes | |
249 except ImportError: | |
250 _get_win_folder = _get_win_folder_from_registry | |
251 | |
252 | |
253 def _win_path_to_bytes(path): | |
254 """Encode Windows paths to bytes. Only used on Python 2. | |
255 | |
256 Motivation is to be consistent with other operating systems where paths | |
257 are also returned as bytes. This avoids problems mixing bytes and Unicode | |
258 elsewhere in the codebase. For more details and discussion see | |
259 <https://github.com/pypa/pip/issues/3463>. | |
260 | |
261 If encoding using ASCII and MBCS fails, return the original Unicode path. | |
262 """ | |
263 for encoding in ('ASCII', 'MBCS'): | |
264 try: | |
265 return path.encode(encoding) | |
266 except (UnicodeEncodeError, LookupError): | |
267 pass | |
268 return path |