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