comparison lib/python3.8/site-packages/pip/_vendor/appdirs.py @ 0:9e54283cc701 draft

"planemo upload commit d12c32a45bcd441307e632fca6d9af7d60289d44"
author guerler
date Mon, 27 Jul 2020 03:47:31 -0400
parents
children
comparison
equal deleted inserted replaced
-1:000000000000 0:9e54283cc701
1 #!/usr/bin/env python
2 # -*- coding: utf-8 -*-
3 # Copyright (c) 2005-2010 ActiveState Software Inc.
4 # Copyright (c) 2013 Eddy Petrișor
5
6 """Utilities for determining application-specific dirs.
7
8 See <http://github.com/ActiveState/appdirs> for details and usage.
9 """
10 # Dev Notes:
11 # - MSDN on where to store app data files:
12 # http://support.microsoft.com/default.aspx?scid=kb;en-us;310294#XSLTH3194121123120121120120
13 # - Mac OS X: http://developer.apple.com/documentation/MacOSX/Conceptual/BPFileSystem/index.html
14 # - XDG spec for Un*x: http://standards.freedesktop.org/basedir-spec/basedir-spec-latest.html
15
16 __version_info__ = (1, 4, 3)
17 __version__ = '.'.join(map(str, __version_info__))
18
19
20 import sys
21 import os
22
23 PY3 = sys.version_info[0] == 3
24
25 if PY3:
26 unicode = str
27
28 if sys.platform.startswith('java'):
29 import platform
30 os_name = platform.java_ver()[3][0]
31 if os_name.startswith('Windows'): # "Windows XP", "Windows 7", etc.
32 system = 'win32'
33 elif os_name.startswith('Mac'): # "Mac OS X", etc.
34 system = 'darwin'
35 else: # "Linux", "SunOS", "FreeBSD", etc.
36 # Setting this to "linux2" is not ideal, but only Windows or Mac
37 # are actually checked for and the rest of the module expects
38 # *sys.platform* style strings.
39 system = 'linux2'
40 elif sys.platform == 'cli' and os.name == 'nt':
41 # Detect Windows in IronPython to match pip._internal.utils.compat.WINDOWS
42 # Discussion: <https://github.com/pypa/pip/pull/7501>
43 system = 'win32'
44 else:
45 system = sys.platform
46
47
48
49 def user_data_dir(appname=None, appauthor=None, version=None, roaming=False):
50 r"""Return full path to the user-specific data dir for this application.
51
52 "appname" is the name of application.
53 If None, just the system directory is returned.
54 "appauthor" (only used on Windows) is the name of the
55 appauthor or distributing body for this application. Typically
56 it is the owning company name. This falls back to appname. You may
57 pass False to disable it.
58 "version" is an optional version path element to append to the
59 path. You might want to use this if you want multiple versions
60 of your app to be able to run independently. If used, this
61 would typically be "<major>.<minor>".
62 Only applied when appname is present.
63 "roaming" (boolean, default False) can be set True to use the Windows
64 roaming appdata directory. That means that for users on a Windows
65 network setup for roaming profiles, this user data will be
66 sync'd on login. See
67 <http://technet.microsoft.com/en-us/library/cc766489(WS.10).aspx>
68 for a discussion of issues.
69
70 Typical user data directories are:
71 Mac OS X: ~/Library/Application Support/<AppName> # or ~/.config/<AppName>, if the other does not exist
72 Unix: ~/.local/share/<AppName> # or in $XDG_DATA_HOME, if defined
73 Win XP (not roaming): C:\Documents and Settings\<username>\Application Data\<AppAuthor>\<AppName>
74 Win XP (roaming): C:\Documents and Settings\<username>\Local Settings\Application Data\<AppAuthor>\<AppName>
75 Win 7 (not roaming): C:\Users\<username>\AppData\Local\<AppAuthor>\<AppName>
76 Win 7 (roaming): C:\Users\<username>\AppData\Roaming\<AppAuthor>\<AppName>
77
78 For Unix, we follow the XDG spec and support $XDG_DATA_HOME.
79 That means, by default "~/.local/share/<AppName>".
80 """
81 if system == "win32":
82 if appauthor is None:
83 appauthor = appname
84 const = roaming and "CSIDL_APPDATA" or "CSIDL_LOCAL_APPDATA"
85 path = os.path.normpath(_get_win_folder(const))
86 if appname:
87 if appauthor is not False:
88 path = os.path.join(path, appauthor, appname)
89 else:
90 path = os.path.join(path, appname)
91 elif system == 'darwin':
92 path = os.path.expanduser('~/Library/Application Support/')
93 if appname:
94 path = os.path.join(path, appname)
95 if not os.path.isdir(path):
96 path = os.path.expanduser('~/.config/')
97 if appname:
98 path = os.path.join(path, appname)
99 else:
100 path = os.getenv('XDG_DATA_HOME', os.path.expanduser("~/.local/share"))
101 if appname:
102 path = os.path.join(path, appname)
103 if appname and version:
104 path = os.path.join(path, version)
105 return path
106
107
108 def site_data_dir(appname=None, appauthor=None, version=None, multipath=False):
109 r"""Return full path to the user-shared data dir for this application.
110
111 "appname" is the name of application.
112 If None, just the system directory is returned.
113 "appauthor" (only used on Windows) is the name of the
114 appauthor or distributing body for this application. Typically
115 it is the owning company name. This falls back to appname. You may
116 pass False to disable it.
117 "version" is an optional version path element to append to the
118 path. You might want to use this if you want multiple versions
119 of your app to be able to run independently. If used, this
120 would typically be "<major>.<minor>".
121 Only applied when appname is present.
122 "multipath" is an optional parameter only applicable to *nix
123 which indicates that the entire list of data dirs should be
124 returned. By default, the first item from XDG_DATA_DIRS is
125 returned, or '/usr/local/share/<AppName>',
126 if XDG_DATA_DIRS is not set
127
128 Typical site data directories are:
129 Mac OS X: /Library/Application Support/<AppName>
130 Unix: /usr/local/share/<AppName> or /usr/share/<AppName>
131 Win XP: C:\Documents and Settings\All Users\Application Data\<AppAuthor>\<AppName>
132 Vista: (Fail! "C:\ProgramData" is a hidden *system* directory on Vista.)
133 Win 7: C:\ProgramData\<AppAuthor>\<AppName> # Hidden, but writeable on Win 7.
134
135 For Unix, this is using the $XDG_DATA_DIRS[0] default.
136
137 WARNING: Do not use this on Windows. See the Vista-Fail note above for why.
138 """
139 if system == "win32":
140 if appauthor is None:
141 appauthor = appname
142 path = os.path.normpath(_get_win_folder("CSIDL_COMMON_APPDATA"))
143 if appname:
144 if appauthor is not False:
145 path = os.path.join(path, appauthor, appname)
146 else:
147 path = os.path.join(path, appname)
148 elif system == 'darwin':
149 path = os.path.expanduser('/Library/Application Support')
150 if appname:
151 path = os.path.join(path, appname)
152 else:
153 # XDG default for $XDG_DATA_DIRS
154 # only first, if multipath is False
155 path = os.getenv('XDG_DATA_DIRS',
156 os.pathsep.join(['/usr/local/share', '/usr/share']))
157 pathlist = [os.path.expanduser(x.rstrip(os.sep)) for x in path.split(os.pathsep)]
158 if appname:
159 if version:
160 appname = os.path.join(appname, version)
161 pathlist = [os.path.join(x, appname) for x in pathlist]
162
163 if multipath:
164 path = os.pathsep.join(pathlist)
165 else:
166 path = pathlist[0]
167 return path
168
169 if appname and version:
170 path = os.path.join(path, version)
171 return path
172
173
174 def user_config_dir(appname=None, appauthor=None, version=None, roaming=False):
175 r"""Return full path to the user-specific config dir for this application.
176
177 "appname" is the name of application.
178 If None, just the system directory is returned.
179 "appauthor" (only used on Windows) is the name of the
180 appauthor or distributing body for this application. Typically
181 it is the owning company name. This falls back to appname. You may
182 pass False to disable it.
183 "version" is an optional version path element to append to the
184 path. You might want to use this if you want multiple versions
185 of your app to be able to run independently. If used, this
186 would typically be "<major>.<minor>".
187 Only applied when appname is present.
188 "roaming" (boolean, default False) can be set True to use the Windows
189 roaming appdata directory. That means that for users on a Windows
190 network setup for roaming profiles, this user data will be
191 sync'd on login. See
192 <http://technet.microsoft.com/en-us/library/cc766489(WS.10).aspx>
193 for a discussion of issues.
194
195 Typical user config directories are:
196 Mac OS X: same as user_data_dir
197 Unix: ~/.config/<AppName> # or in $XDG_CONFIG_HOME, if defined
198 Win *: same as user_data_dir
199
200 For Unix, we follow the XDG spec and support $XDG_CONFIG_HOME.
201 That means, by default "~/.config/<AppName>".
202 """
203 if system in ["win32", "darwin"]:
204 path = user_data_dir(appname, appauthor, None, roaming)
205 else:
206 path = os.getenv('XDG_CONFIG_HOME', os.path.expanduser("~/.config"))
207 if appname:
208 path = os.path.join(path, appname)
209 if appname and version:
210 path = os.path.join(path, version)
211 return path
212
213
214 # for the discussion regarding site_config_dir locations
215 # see <https://github.com/pypa/pip/issues/1733>
216 def site_config_dir(appname=None, appauthor=None, version=None, multipath=False):
217 r"""Return full path to the user-shared data dir for this application.
218
219 "appname" is the name of application.
220 If None, just the system directory is returned.
221 "appauthor" (only used on Windows) is the name of the
222 appauthor or distributing body for this application. Typically
223 it is the owning company name. This falls back to appname. You may
224 pass False to disable it.
225 "version" is an optional version path element to append to the
226 path. You might want to use this if you want multiple versions
227 of your app to be able to run independently. If used, this
228 would typically be "<major>.<minor>".
229 Only applied when appname is present.
230 "multipath" is an optional parameter only applicable to *nix
231 which indicates that the entire list of config dirs should be
232 returned. By default, the first item from XDG_CONFIG_DIRS is
233 returned, or '/etc/xdg/<AppName>', if XDG_CONFIG_DIRS is not set
234
235 Typical site config directories are:
236 Mac OS X: same as site_data_dir
237 Unix: /etc/xdg/<AppName> or $XDG_CONFIG_DIRS[i]/<AppName> for each value in
238 $XDG_CONFIG_DIRS
239 Win *: same as site_data_dir
240 Vista: (Fail! "C:\ProgramData" is a hidden *system* directory on Vista.)
241
242 For Unix, this is using the $XDG_CONFIG_DIRS[0] default, if multipath=False
243
244 WARNING: Do not use this on Windows. See the Vista-Fail note above for why.
245 """
246 if system in ["win32", "darwin"]:
247 path = site_data_dir(appname, appauthor)
248 if appname and version:
249 path = os.path.join(path, version)
250 else:
251 # XDG default for $XDG_CONFIG_DIRS (missing or empty)
252 # see <https://github.com/pypa/pip/pull/7501#discussion_r360624829>
253 # only first, if multipath is False
254 path = os.getenv('XDG_CONFIG_DIRS') or '/etc/xdg'
255 pathlist = [os.path.expanduser(x.rstrip(os.sep)) for x in path.split(os.pathsep) if x]
256 if appname:
257 if version:
258 appname = os.path.join(appname, version)
259 pathlist = [os.path.join(x, appname) for x in pathlist]
260 # always look in /etc directly as well
261 pathlist.append('/etc')
262
263 if multipath:
264 path = os.pathsep.join(pathlist)
265 else:
266 path = pathlist[0]
267 return path
268
269
270 def user_cache_dir(appname=None, appauthor=None, version=None, opinion=True):
271 r"""Return full path to the user-specific cache dir for this application.
272
273 "appname" is the name of application.
274 If None, just the system directory is returned.
275 "appauthor" (only used on Windows) is the name of the
276 appauthor or distributing body for this application. Typically
277 it is the owning company name. This falls back to appname. You may
278 pass False to disable it.
279 "version" is an optional version path element to append to the
280 path. You might want to use this if you want multiple versions
281 of your app to be able to run independently. If used, this
282 would typically be "<major>.<minor>".
283 Only applied when appname is present.
284 "opinion" (boolean) can be False to disable the appending of
285 "Cache" to the base app data dir for Windows. See
286 discussion below.
287
288 Typical user cache directories are:
289 Mac OS X: ~/Library/Caches/<AppName>
290 Unix: ~/.cache/<AppName> (XDG default)
291 Win XP: C:\Documents and Settings\<username>\Local Settings\Application Data\<AppAuthor>\<AppName>\Cache
292 Vista: C:\Users\<username>\AppData\Local\<AppAuthor>\<AppName>\Cache
293
294 On Windows the only suggestion in the MSDN docs is that local settings go in
295 the `CSIDL_LOCAL_APPDATA` directory. This is identical to the non-roaming
296 app data dir (the default returned by `user_data_dir` above). Apps typically
297 put cache data somewhere *under* the given dir here. Some examples:
298 ...\Mozilla\Firefox\Profiles\<ProfileName>\Cache
299 ...\Acme\SuperApp\Cache\1.0
300 OPINION: This function appends "Cache" to the `CSIDL_LOCAL_APPDATA` value.
301 This can be disabled with the `opinion=False` option.
302 """
303 if system == "win32":
304 if appauthor is None:
305 appauthor = appname
306 path = os.path.normpath(_get_win_folder("CSIDL_LOCAL_APPDATA"))
307 # When using Python 2, return paths as bytes on Windows like we do on
308 # other operating systems. See helper function docs for more details.
309 if not PY3 and isinstance(path, unicode):
310 path = _win_path_to_bytes(path)
311 if appname:
312 if appauthor is not False:
313 path = os.path.join(path, appauthor, appname)
314 else:
315 path = os.path.join(path, appname)
316 if opinion:
317 path = os.path.join(path, "Cache")
318 elif system == 'darwin':
319 path = os.path.expanduser('~/Library/Caches')
320 if appname:
321 path = os.path.join(path, appname)
322 else:
323 path = os.getenv('XDG_CACHE_HOME', os.path.expanduser('~/.cache'))
324 if appname:
325 path = os.path.join(path, appname)
326 if appname and version:
327 path = os.path.join(path, version)
328 return path
329
330
331 def user_state_dir(appname=None, appauthor=None, version=None, roaming=False):
332 r"""Return full path to the user-specific state dir for this application.
333
334 "appname" is the name of application.
335 If None, just the system directory is returned.
336 "appauthor" (only used on Windows) is the name of the
337 appauthor or distributing body for this application. Typically
338 it is the owning company name. This falls back to appname. You may
339 pass False to disable it.
340 "version" is an optional version path element to append to the
341 path. You might want to use this if you want multiple versions
342 of your app to be able to run independently. If used, this
343 would typically be "<major>.<minor>".
344 Only applied when appname is present.
345 "roaming" (boolean, default False) can be set True to use the Windows
346 roaming appdata directory. That means that for users on a Windows
347 network setup for roaming profiles, this user data will be
348 sync'd on login. See
349 <http://technet.microsoft.com/en-us/library/cc766489(WS.10).aspx>
350 for a discussion of issues.
351
352 Typical user state directories are:
353 Mac OS X: same as user_data_dir
354 Unix: ~/.local/state/<AppName> # or in $XDG_STATE_HOME, if defined
355 Win *: same as user_data_dir
356
357 For Unix, we follow this Debian proposal <https://wiki.debian.org/XDGBaseDirectorySpecification#state>
358 to extend the XDG spec and support $XDG_STATE_HOME.
359
360 That means, by default "~/.local/state/<AppName>".
361 """
362 if system in ["win32", "darwin"]:
363 path = user_data_dir(appname, appauthor, None, roaming)
364 else:
365 path = os.getenv('XDG_STATE_HOME', os.path.expanduser("~/.local/state"))
366 if appname:
367 path = os.path.join(path, appname)
368 if appname and version:
369 path = os.path.join(path, version)
370 return path
371
372
373 def user_log_dir(appname=None, appauthor=None, version=None, opinion=True):
374 r"""Return full path to the user-specific log dir for this application.
375
376 "appname" is the name of application.
377 If None, just the system directory is returned.
378 "appauthor" (only used on Windows) is the name of the
379 appauthor or distributing body for this application. Typically
380 it is the owning company name. This falls back to appname. You may
381 pass False to disable it.
382 "version" is an optional version path element to append to the
383 path. You might want to use this if you want multiple versions
384 of your app to be able to run independently. If used, this
385 would typically be "<major>.<minor>".
386 Only applied when appname is present.
387 "opinion" (boolean) can be False to disable the appending of
388 "Logs" to the base app data dir for Windows, and "log" to the
389 base cache dir for Unix. See discussion below.
390
391 Typical user log directories are:
392 Mac OS X: ~/Library/Logs/<AppName>
393 Unix: ~/.cache/<AppName>/log # or under $XDG_CACHE_HOME if defined
394 Win XP: C:\Documents and Settings\<username>\Local Settings\Application Data\<AppAuthor>\<AppName>\Logs
395 Vista: C:\Users\<username>\AppData\Local\<AppAuthor>\<AppName>\Logs
396
397 On Windows the only suggestion in the MSDN docs is that local settings
398 go in the `CSIDL_LOCAL_APPDATA` directory. (Note: I'm interested in
399 examples of what some windows apps use for a logs dir.)
400
401 OPINION: This function appends "Logs" to the `CSIDL_LOCAL_APPDATA`
402 value for Windows and appends "log" to the user cache dir for Unix.
403 This can be disabled with the `opinion=False` option.
404 """
405 if system == "darwin":
406 path = os.path.join(
407 os.path.expanduser('~/Library/Logs'),
408 appname)
409 elif system == "win32":
410 path = user_data_dir(appname, appauthor, version)
411 version = False
412 if opinion:
413 path = os.path.join(path, "Logs")
414 else:
415 path = user_cache_dir(appname, appauthor, version)
416 version = False
417 if opinion:
418 path = os.path.join(path, "log")
419 if appname and version:
420 path = os.path.join(path, version)
421 return path
422
423
424 class AppDirs(object):
425 """Convenience wrapper for getting application dirs."""
426 def __init__(self, appname=None, appauthor=None, version=None,
427 roaming=False, multipath=False):
428 self.appname = appname
429 self.appauthor = appauthor
430 self.version = version
431 self.roaming = roaming
432 self.multipath = multipath
433
434 @property
435 def user_data_dir(self):
436 return user_data_dir(self.appname, self.appauthor,
437 version=self.version, roaming=self.roaming)
438
439 @property
440 def site_data_dir(self):
441 return site_data_dir(self.appname, self.appauthor,
442 version=self.version, multipath=self.multipath)
443
444 @property
445 def user_config_dir(self):
446 return user_config_dir(self.appname, self.appauthor,
447 version=self.version, roaming=self.roaming)
448
449 @property
450 def site_config_dir(self):
451 return site_config_dir(self.appname, self.appauthor,
452 version=self.version, multipath=self.multipath)
453
454 @property
455 def user_cache_dir(self):
456 return user_cache_dir(self.appname, self.appauthor,
457 version=self.version)
458
459 @property
460 def user_state_dir(self):
461 return user_state_dir(self.appname, self.appauthor,
462 version=self.version)
463
464 @property
465 def user_log_dir(self):
466 return user_log_dir(self.appname, self.appauthor,
467 version=self.version)
468
469
470 #---- internal support stuff
471
472 def _get_win_folder_from_registry(csidl_name):
473 """This is a fallback technique at best. I'm not sure if using the
474 registry for this guarantees us the correct answer for all CSIDL_*
475 names.
476 """
477 if PY3:
478 import winreg as _winreg
479 else:
480 import _winreg
481
482 shell_folder_name = {
483 "CSIDL_APPDATA": "AppData",
484 "CSIDL_COMMON_APPDATA": "Common AppData",
485 "CSIDL_LOCAL_APPDATA": "Local AppData",
486 }[csidl_name]
487
488 key = _winreg.OpenKey(
489 _winreg.HKEY_CURRENT_USER,
490 r"Software\Microsoft\Windows\CurrentVersion\Explorer\Shell Folders"
491 )
492 dir, type = _winreg.QueryValueEx(key, shell_folder_name)
493 return dir
494
495
496 def _get_win_folder_with_pywin32(csidl_name):
497 from win32com.shell import shellcon, shell
498 dir = shell.SHGetFolderPath(0, getattr(shellcon, csidl_name), 0, 0)
499 # Try to make this a unicode path because SHGetFolderPath does
500 # not return unicode strings when there is unicode data in the
501 # path.
502 try:
503 dir = unicode(dir)
504
505 # Downgrade to short path name if have highbit chars. See
506 # <http://bugs.activestate.com/show_bug.cgi?id=85099>.
507 has_high_char = False
508 for c in dir:
509 if ord(c) > 255:
510 has_high_char = True
511 break
512 if has_high_char:
513 try:
514 import win32api
515 dir = win32api.GetShortPathName(dir)
516 except ImportError:
517 pass
518 except UnicodeError:
519 pass
520 return dir
521
522
523 def _get_win_folder_with_ctypes(csidl_name):
524 import ctypes
525
526 csidl_const = {
527 "CSIDL_APPDATA": 26,
528 "CSIDL_COMMON_APPDATA": 35,
529 "CSIDL_LOCAL_APPDATA": 28,
530 }[csidl_name]
531
532 buf = ctypes.create_unicode_buffer(1024)
533 ctypes.windll.shell32.SHGetFolderPathW(None, csidl_const, None, 0, buf)
534
535 # Downgrade to short path name if have highbit chars. See
536 # <http://bugs.activestate.com/show_bug.cgi?id=85099>.
537 has_high_char = False
538 for c in buf:
539 if ord(c) > 255:
540 has_high_char = True
541 break
542 if has_high_char:
543 buf2 = ctypes.create_unicode_buffer(1024)
544 if ctypes.windll.kernel32.GetShortPathNameW(buf.value, buf2, 1024):
545 buf = buf2
546
547 return buf.value
548
549 def _get_win_folder_with_jna(csidl_name):
550 import array
551 from com.sun import jna
552 from com.sun.jna.platform import win32
553
554 buf_size = win32.WinDef.MAX_PATH * 2
555 buf = array.zeros('c', buf_size)
556 shell = win32.Shell32.INSTANCE
557 shell.SHGetFolderPath(None, getattr(win32.ShlObj, csidl_name), None, win32.ShlObj.SHGFP_TYPE_CURRENT, buf)
558 dir = jna.Native.toString(buf.tostring()).rstrip("\0")
559
560 # Downgrade to short path name if have highbit chars. See
561 # <http://bugs.activestate.com/show_bug.cgi?id=85099>.
562 has_high_char = False
563 for c in dir:
564 if ord(c) > 255:
565 has_high_char = True
566 break
567 if has_high_char:
568 buf = array.zeros('c', buf_size)
569 kernel = win32.Kernel32.INSTANCE
570 if kernel.GetShortPathName(dir, buf, buf_size):
571 dir = jna.Native.toString(buf.tostring()).rstrip("\0")
572
573 return dir
574
575 if system == "win32":
576 try:
577 from ctypes import windll
578 _get_win_folder = _get_win_folder_with_ctypes
579 except ImportError:
580 try:
581 import com.sun.jna
582 _get_win_folder = _get_win_folder_with_jna
583 except ImportError:
584 _get_win_folder = _get_win_folder_from_registry
585
586
587 def _win_path_to_bytes(path):
588 """Encode Windows paths to bytes. Only used on Python 2.
589
590 Motivation is to be consistent with other operating systems where paths
591 are also returned as bytes. This avoids problems mixing bytes and Unicode
592 elsewhere in the codebase. For more details and discussion see
593 <https://github.com/pypa/pip/issues/3463>.
594
595 If encoding using ASCII and MBCS fails, return the original Unicode path.
596 """
597 for encoding in ('ASCII', 'MBCS'):
598 try:
599 return path.encode(encoding)
600 except (UnicodeEncodeError, LookupError):
601 pass
602 return path
603
604
605 #---- self test code
606
607 if __name__ == "__main__":
608 appname = "MyApp"
609 appauthor = "MyCompany"
610
611 props = ("user_data_dir",
612 "user_config_dir",
613 "user_cache_dir",
614 "user_state_dir",
615 "user_log_dir",
616 "site_data_dir",
617 "site_config_dir")
618
619 print("-- app dirs %s --" % __version__)
620
621 print("-- app dirs (with optional 'version')")
622 dirs = AppDirs(appname, appauthor, version="1.0")
623 for prop in props:
624 print("%s: %s" % (prop, getattr(dirs, prop)))
625
626 print("\n-- app dirs (without optional 'version')")
627 dirs = AppDirs(appname, appauthor)
628 for prop in props:
629 print("%s: %s" % (prop, getattr(dirs, prop)))
630
631 print("\n-- app dirs (without optional 'appauthor')")
632 dirs = AppDirs(appname)
633 for prop in props:
634 print("%s: %s" % (prop, getattr(dirs, prop)))
635
636 print("\n-- app dirs (with disabled 'appauthor')")
637 dirs = AppDirs(appname, appauthor=False)
638 for prop in props:
639 print("%s: %s" % (prop, getattr(dirs, prop)))