From 03d52fa44d15178080fb70d00b35317e518c388d Mon Sep 17 00:00:00 2001 From: Stephen Arnold Date: Wed, 17 Jun 2020 20:03:11 -0700 Subject: [PATCH] appdirs.py: add site-specific state dir, update tests * use '/var/lib/AppName' dir on Linux * use site_data with appended 'State' dir on non-Linux platforms Signed-off-by: Stephen Arnold --- appdirs.py | 56 +++++++++++++++++++++++++++++++++++++++++++++++- test/test_api.py | 3 +++ tox.ini | 1 + 3 files changed, 59 insertions(+), 1 deletion(-) diff --git a/appdirs.py b/appdirs.py index fcc26ad..edc1b24 100644 --- a/appdirs.py +++ b/appdirs.py @@ -318,6 +318,54 @@ def user_cache_dir(appname=None, appauthor=None, version=None, opinion=True): return path +def site_state_dir(appname=None, appauthor=None, version=None): + r"""Return full path to the user-shared state dir for this application. + + "appname" is the name of application. + If None, just the system directory is returned. + "appauthor" (only used on Windows) is the name of the + appauthor or distributing body for this application. Typically + it is the owning company name. This falls back to appname. You may + pass False to disable it. + "version" is an optional version path element to append to the + path. You might want to use this if you want multiple versions + of your app to be able to run independently. If used, this + would typically be ".". + Only applied when appname is present. + + Typical site data directories are: + Mac OS X: /Library/Application Support//state + Unix: /var/lib/ + Win XP: C:\Documents and Settings\All Users\Application Data\\\State + Vista: (Fail! "C:\ProgramData" is a hidden *system* directory on Vista.) + Win 7: C:\ProgramData\\\State # Hidden, but writeable on Win 7. + + For Unix, this does not have an $XDG_STATE_DIR default + + WARNING: Do not use this on Windows. See the Vista-Fail note above for why. + """ + if system == "win32": + if appauthor is None: + appauthor = appname + path = os.path.normpath(_get_win_folder("CSIDL_COMMON_APPDATA")) + if appname: + if appauthor is not False: + path = os.path.join(path, appauthor, appname, 'State') + else: + path = os.path.join(path, appname, 'State') + elif system == 'darwin': + path = os.path.expanduser('/Library/Application Support') + if appname: + path = os.path.join(path, appname, 'State') + else: + path = '/var/lib' + if appname: + path = os.path.join(path, appname) + if appname and version: + path = os.path.join(path, version) + return path + + def user_state_dir(appname=None, appauthor=None, version=None, roaming=False): r"""Return full path to the user-specific state dir for this application. @@ -451,6 +499,11 @@ def user_state_dir(self): return user_state_dir(self.appname, self.appauthor, version=self.version) + @property + def site_state_dir(self): + return site_state_dir(self.appname, self.appauthor, + version=self.version) + @property def user_log_dir(self): return user_log_dir(self.appname, self.appauthor, @@ -561,7 +614,8 @@ def _get_win_folder_with_jna(csidl_name): "user_state_dir", "user_log_dir", "site_data_dir", - "site_config_dir") + "site_config_dir", + "site_state_dir") print("-- app dirs %s --" % __version__) diff --git a/test/test_api.py b/test/test_api.py index 8c89fb2..c4b5dd8 100644 --- a/test/test_api.py +++ b/test/test_api.py @@ -22,6 +22,8 @@ def test_helpers(self): appdirs.user_cache_dir('MyApp', 'MyCompany'), STRING_TYPE) self.assertIsInstance( appdirs.user_state_dir('MyApp', 'MyCompany'), STRING_TYPE) + self.assertIsInstance( + appdirs.site_state_dir('MyApp', 'MyCompany'), STRING_TYPE) self.assertIsInstance( appdirs.user_log_dir('MyApp', 'MyCompany'), STRING_TYPE) @@ -31,6 +33,7 @@ def test_dirs(self): self.assertIsInstance(dirs.site_data_dir, STRING_TYPE) self.assertIsInstance(dirs.user_cache_dir, STRING_TYPE) self.assertIsInstance(dirs.user_state_dir, STRING_TYPE) + self.assertIsInstance(dirs.site_state_dir, STRING_TYPE) self.assertIsInstance(dirs.user_log_dir, STRING_TYPE) if __name__ == "__main__": diff --git a/tox.ini b/tox.ini index 736e201..13cb8fd 100644 --- a/tox.ini +++ b/tox.ini @@ -1,5 +1,6 @@ [tox] envlist = py{27,py,35,36,37,38,py3} +# skip_missing_interpreters = true [testenv] commands = python setup.py test