8000 New 'forced_home' and 'home' setter · FirebirdSQL/python3-base@541ed8d · GitHub
[go: up one dir, main page]

Skip to content

Commit 541ed8d

Browse files
committed
New 'forced_home' and 'home' setter
1 parent a5a36a6 commit 541ed8d

File tree

2 files changed

+155
-27
lines changed

2 files changed

+155
-27
lines changed

firebird/base/config.py

Lines changed: 56 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -97,14 +97,19 @@ class DirectoryScheme:
9797
Note:
9898
All paths are set when the instance is created and can be changed later.
9999
"""
100-
def __init__(self, name: str, version: str=None):
100+
def __init__(self, name: str, version: str=None, force_home: bool=False):
101101
"""
102102
Arguments:
103103
name: Appplication name.
104104
version: Application version.
105+
force_home: When True, general directories (i.e. all except user-specific and
106+
TMP) would be always based on HOME directory.
105107
"""
106108
self.name: str = name
107109
self.version: str = version
110+
self.force_home: bool = force_home
111+
_h = os.getenv(f'{self.name.upper()}_HOME')
112+
self.__home: Path = Path(_h) if _h is not None else Path(os.getcwd())
108113
home = self.home
109114
self.dir_map: Dict[str, Path] = {'config': home / 'config',
110115
'run_data': home / 'run_data',
@@ -124,11 +129,28 @@ def has_home_env(self) -> bool:
124129
return os.getenv(f'{self.name.upper()}_HOME') is not None
125130
@property
126131
def home(self) -> Path:
127-
"""HOME directory. Either path set by "<app_name>_HOME" environment variable, or
128-
current working directory.
129-
"""
130-
home = os.getenv(f'{self.name.upper()}_HOME')
131-
return Path(home) if home is not None else Path(os.getcwd())
132+
"""HOME directory. Initial value is path set by "<app_name>_HOME" environment
133+
variable, or to current working directory when variable is not defined.
134+
135+
Important:
136+
When new value is assigned, the general directories (i.e. all except user-specific
137+
and TMP) are redefined as subdirectories of new home path ONLY when HOME was
138+
initially defined using "<app_name>_HOME" environment variable, or instance
139+
was created with `force_home`=True.
140+
141+
However, all paths could be still changed individually to any value.
142+
"""
143+
return self.__home
144+
@home.setter
145+
def home(self, value: Union[Path, str]) -> None:
146+
self.__home = value if isinstance(value, Path) else Path(value)
147+
if self.has_home_env() or self.force_home:
148+
self.dir_map.update({'config': self.__home / 'config',
149+
'run_data': self.__home / 'run_data',
150+
'logs': self.__home / 'logs',
151+
'data': self.__home / 'data',
152+
'cache': self.__home / 'cache',
153+
'srv': self.__home / 'srv'})
132154
@property
133155
def config(self) -> Path:
134156
"""Directory for host-specific system-wide configuration files.
@@ -229,25 +251,27 @@ def user_cache(self, path: Path) -> None:
229251
class WindowsDirectoryScheme(DirectoryScheme):
230252
"""Directory scheme that conforms to Windows standards.
231253
232-
If HOME is defined using "<app_name>_HOME" environment variable, only user-specific
233-
directories and TMP are set according to platform standars, while general directories
234-
remain as defined by base `DirectoryScheme`.
254+
If HOME is defined using "<app_name>_HOME" environment variable, or `force_home` parameter
255+
is True, only user-specific directories and TMP are set according to platform standars,
256+
while general directories remain as defined by base `DirectoryScheme`.
235257
"""
236-
def __init__(self, name: str, version: str=None):
258+
def __init__(self, name: str, version: str=None, force_home: bool=False):
237259
"""
238260
Arguments:
239261
name: Appplication name.
240262
version: Application version.
263+
force_home: When True, general directories (i.e. all except user-specific and
264+
TMP) would be always based on HOME directory.
241265
"""
242-
super().__init__(name, version)
266+
super().__init__(name, version, force_home)
243267
app_dir = Path(self.name)
244268
if self.version is not None:
245269
app_dir /= self.version
246270
pd = Path(os.path.expandvars('%PROGRAMDATA%'))
247271
lad = Path(os.path.expandvars('%LOCALAPPDATA%'))
248272
ad = Path(os.path.expandvars('%APPDATA%'))
< 10000 /td>
249273
# Set general directories only when HOME is not forced by environment variable.
250-
if not self.has_home_env():
274+
if not self.has_home_env() and not force_home:
251275
self.dir_map.update({'config': pd / app_dir / 'config',
252276
'run_data': pd / app_dir / 'run',
253277
'logs': pd / app_dir / 'log',
@@ -266,22 +290,24 @@ def __init__(self, name: str, version: str=None):
266290
class LinuxDirectoryScheme(DirectoryScheme):
267291
"""Directory scheme that conforms to Linux standards.
268292
269-
If HOME is defined using "<app_name>_HOME" environment variable, only user-specific
270-
directories and TMP are set according to platform standars, while general directories
271-
remain as defined by base `DirectoryScheme`.
293+
If HOME is defined using "<app_name>_HOME" environment variable, or `force_home` parameter
294+
is True, only user-specific directories and TMP are set according to platform standars,
295+
while general directories remain as defined by base `DirectoryScheme`.
272296
"""
273-
def __init__(self, name: str, version: str=None):
297+
def __init__(self, name: str, version: str=None, force_home: bool=False):
274298
"""
275299
Arguments:
276300
name: Appplication name.
277301
version: Application version.
302+
force_home: When True, general directories (i.e. all except user-specific and
303+
TMP) would be always based on HOME directory.
278304
"""
279-
super().__init__(name, version)
305+
super().__init__(name, version, force_home)
280306
app_dir = Path(self.name)
281307
if self.version is not None:
282308
app_dir /= self.version
283309
# Set general directories only when HOME is not forced by environment variable.
284-
if not self.has_home_env():
310+
if not self.has_home_env() and not force_home:
285311
self.dir_map.update({'config': Path('/etc') / app_dir,
286312
'run_data': Path('/run') / app_dir,
287313
'logs': Path('/var/log') / app_dir,
@@ -304,20 +330,20 @@ class MacOSDirectoryScheme(DirectoryScheme):
304330
directories and TMP are set according to platform standars, while general directories
305331
remain as defined by base `DirectoryScheme`.
306332
"""
307-
def __init__(self, name: str, version: str=None):
333+
def __init__(self, name: str, version: str=None, force_home: bool=False):
308334
"""
309335
Arguments:
310336
name: Appplication name.
311337
version: Application version.
312338
"""
313-
super().__init__(name, version)
339+
super().__init__(name, version, force_home)
314340
app_dir = Path(self.name)
315341
if self.version is not None:
316342
app_dir /= self.version
317343
pd = Path('/Library/Application Support')
318344
lad = Path('~/Library/Application Support').expanduser()
319345
# Set general directories only when HOME is not forced by environment variable.
320-
if not self.has_home_env():
346+
if not self.has_home_env() and not force_home:
321347
self.dir_map.update({'config': pd / app_dir / 'config',
322348
'run_data': pd / app_dir / 'run',
323349
'logs': pd / app_dir / 'log',
@@ -333,12 +359,19 @@ def __init__(self, name: str, version: str=None):
333359
'user_cache': Path('~/Library/Caches').expanduser() / app_dir / 'cache',
334360
})
335361

336-
def get_directory_scheme(app_name: str, version: str=None) -> DirectoryScheme:
362+
def get_directory_scheme(app_name: str, version: str=None, *, force_home: bool=False) -> DirectoryScheme:
337363
"""Returns directory scheme for current platform.
364+
365+
Arguments:
366+
app_name: Application name
367+
version: Application version string
368+
force_home: When True, the general directies are always set to subdirectories of
369+
`DirectoryScheme.home` directory. When False, these the home is used
370+
ONLY when it's set by "<app_name>_HOME" environment variable.
338371
"""
339372
return {'Windows': WindowsDirectoryScheme,
340373
'Linux':LinuxDirectoryScheme,
341-
'Darwin': MacOSDirectoryScheme}.get(platform.system(), DirectoryScheme)(app_name, version)
374+
'Darwin': MacOSDirectoryScheme}.get(platform.system(), DirectoryScheme)(app_name, version, force_home)
342375

343376
T = TypeVar('T')
344377

test/test_config.py

Lines changed: 99 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3213,7 +3213,6 @@ def test_01_widnows(self):
32133213
if platform.system() != 'Windows':
32143214
self.skipTest("Only for Windows")
32153215
scheme = config.get_directory_scheme(self.app_name)
3216-
# 'C:/Users/pavel/AppData/Local/test_app/tmp'
32173216
self.assertEqual(scheme.config, Path('c:/ProgramData/test_app/config'))
32183217
self.assertEqual(scheme.run_data, Path('c:/ProgramData/test_app/run'))
32193218
self.assertEqual(scheme.logs, Path('c:/ProgramData/test_app/log'))
@@ -3225,7 +3224,55 @@ def test_01_widnows(self):
32253224
self.assertEqual(scheme.user_data, Path('~/AppData/Local/test_app/data').expanduser())
32263225
self.assertEqual(scheme.user_sync, Path('~/AppData/Roaming/test_app').expanduser())
32273226
self.assertEqual(scheme.user_cache, Path('~/AppData/Local/test_app/cache').expanduser())
3228-
def test_02_linux(self):
3227+
@mock.patch.dict(os.environ, {f'{app_name.upper()}_HOME': 'c:/mydir/apphome/'})
3228+
def test_02_widnows_home_env(self):
3229+
if platform.system() != 'Windows':
3230+
self.skipTest("Only for Windows")
3231+
scheme = config.get_directory_scheme(self.app_name)
3232+
self.assertEqual(scheme.config, Path('c:/mydir/apphome/config'))
3233+
self.assertEqual(scheme.run_data, Path('c:/mydir/apphome/run_data'))
3234+
self.assertEqual(scheme.logs, Path('c:/mydir/apphome/logs'))
3235+
self.assertEqual(scheme.data, Path('c:/mydir/apphome/data'))
3236+
self.assertEqual(scheme.tmp, Path('~/AppData/Local/test_app/tmp').expanduser())
3237+
self.assertEqual(scheme.cache, Path('c:/mydir/apphome/cache'))
3238+
self.assertEqual(scheme.srv, Path('c:/mydir/apphome/srv'))
3239+
self.assertEqual(scheme.user_config, Path('~/AppData/Local/test_app/config').expanduser())
3240+
self.assertEqual(scheme.user_data, Path('~/AppData/Local/test_app/data').expanduser())
3241+
self.assertEqual(scheme.user_sync, Path('~/AppData/Roaming/test_app').expanduser())
3242+
self.assertEqual(scheme.user_cache, Path('~/AppData/Local/test_app/cache').expanduser())
3243+
@mock.patch('os.getcwd', return_value='c:/mydir/apphome/')
3244+
def test_03_widnows_home_forced(self, *args):
3245+
if platform.system() != 'Windows':
3246+
self.skipTest("Only for Windows")
3247+
scheme = config.get_directory_scheme(self.app_name)
3248+
self.assertEqual(scheme.config, Path('c:/mydir/apphome/config'))
3249+
self.assertEqual(scheme.run_data, Path('c:/mydir/apphome/run_data'))
3250+
self.assertEqual(scheme.logs, Path('c:/mydir/apphome/logs'))
3251+
self.assertEqual(scheme.data, Path('c:/mydir/apphome/data'))
3252+
self.assertEqual(scheme.tmp, Path('~/AppData/Local/test_app/tmp').expanduser())
3253+
self.assertEqual(scheme.cache, Path('c:/mydir/apphome/cache'))
3254+
self.assertEqual(scheme.srv, Path('c:/mydir/apphome/srv'))
3255+
self.assertEqual(scheme.user_config, Path('~/AppData/Local/test_app/config').expanduser())
3256+
self.assertEqual(scheme.user_data, Path('~/AppData/Local/test_app/data').expanduser())
3257+
self.assertEqual(scheme.user_sync, Path('~/AppData/Roaming/test_app').expanduser())
3258+
self.assertEqual(scheme.user_cache, Path('~/AppData/Local/test_app/cache').expanduser())
3259+
def test_04_widnows_home_change(self, *args):
3260+
if platform.system() != 'Windows':
3261+
self.skipTest("Only for Windows")
3262+
scheme = config.get_directory_scheme(self.app_name)
3263+
scheme.home = 'c:/mydir/apphome/'
3264+
self.assertEqual(scheme.config, Path('c:/mydir/apphome/config'))
3265+
self.assertEqual(scheme.run_data, Path('c:/mydir/apphome/run_data'))
3266+
self.assertEqual(scheme.logs, Path('c:/mydir/apphome/logs'))
3267+
self.assertEqual(scheme.data, Path('c:/mydir/apphome/data'))
3268+
self.assertEqual(scheme.tmp, Path('~/AppData/Local/test_app/tmp').expanduser())
3269+
self.assertEqual(scheme.cache, Path('c:/mydir/apphome/cache'))
3270+
self.assertEqual(scheme.srv, Path('c:/mydir/apphome/srv'))
3271+
self.assertEqual(scheme.user_config, Path('~/AppData/Local/test_app/config').expanduser())
3272+
self.assertEqual(scheme.user_data, Path('~/AppData/Local/test_app/data').expanduser())
3273+
self.assertEqual(scheme.user_sync, Path('~/AppData/Roaming/test_app').expanduser())
3274+
self.assertEqual(scheme.user_cache, Path('~/AppData/Local/test_app/cache').expanduser())
3275+
def test_05_linux_default(self):
32293276
if platform.system() != 'Linux':
32303277
self.skipTest("Only for Linux")
32313278
scheme = config.get_directory_scheme(self.app_name)
@@ -3240,12 +3287,60 @@ def test_02_linux(self):
32403287
self.assertEqual(scheme.user_data, Path('~/.local/share/test_app').expanduser())
32413288
self.assertEqual(scheme.user_sync, Path('~/.local/sync/test_app').expanduser())
32423289
self.assertEqual(scheme.user_cache, Path('~/.cache/test_app').expanduser())
3290+
@mock.patch.dict(os.environ, {f'{app_name.upper()}_HOME': '/mydir/apphome/'})
3291+
def test_06_linux_home_env(self):
3292+
if platform.system() != 'Linux':
3293+
self.skipTest("Only for Linux")
3294+
scheme = config.get_directory_scheme(self.app_name)
3295+
self.assertEqual(scheme.config, Path('/mydir/apphome/config'))
3296+
self.assertEqual(scheme.run_data, Path('/mydir/apphome/run_data'))
3297+
self.assertEqual(scheme.logs, Path('/mydir/apphome/logs'))
3298+
self.assertEqual(scheme.data, Path('/mydir/apphome/data'))
3299+
self.assertEqual(scheme.tmp, Path('/var/tmp/test_app'))
3300+
self.assertEqual(scheme.cache, Path('/mydir/apphome/cache'))
3301+
self.assertEqual(scheme.srv, Path('/mydir/apphome/srv'))
3302+
self.assertEqual(scheme.user_config, Path('~/.config/test_app').expanduser())
3303+
self.assertEqual(scheme.user_data, Path('~/.local/share/test_app').expanduser())
3304+
self.assertEqual(scheme.user_sync, Path('~/.local/sync/test_app').expanduser())
3305+
self.assertEqual(scheme.user_cache, Path('~/.cache/test_app').expanduser())
3306+
@mock.patch('os.getcwd', return_value='/mydir/apphome/')
3307+
def test_07_linux_home_forced(self, *args):
3308+
if platform.system() != 'Linux':
3309+
self.skipTest("Only for Linux")
3310+
scheme = config.get_directory_scheme(self.app_name, force_home=True)
3311+
self.assertEqual(scheme.config, Path('/mydir/apphome/config'))
3312+
self.assertEqual(scheme.run_data, Path('/mydir/apphome/run_data'))
3313+
self.assertEqual(scheme.logs, Path('/mydir/apphome/logs'))
3314+
self.assertEqual(scheme.data, Path('/mydir/apphome/data'))
3315+
self.assertEqual(scheme.tmp, Path('/var/tmp/test_app'))
3316+
self.assertEqual(scheme.cache, Path('/mydir/apphome/cache'))
3317+
self.assertEqual(scheme.srv, Path('/mydir/apphome/srv'))
3318+
self.assertEqual(scheme.user_config, Path('~/.config/test_app').expanduser())
3319+
self.assertEqual(scheme.user_data, Path('~/.local/share/test_app').expanduser())
3320+
self.assertEqual(scheme.user_sync, Path('~/.local/sync/test_app').expanduser())
3321+
self.assertEqual(scheme.user_cache, Path('~/.cache/test_app').expanduser())
3322+
def test_08_linux_home_change(self, *args):
3323+
if platform.system() != 'Linux':
3324+
self.skipTest("Only for Linux")
3325+
scheme = config.get_directory_scheme(self.app_name, force_home=True)
3326+
scheme.home = '/mydir/apphome/'
3327+
self.assertEqual(scheme.config, Path('/mydir/apphome/config'))
3328+
self.assertEqual(scheme.run_data, Path('/mydir/apphome/run_data'))
3329+
self.assertEqual(scheme.logs, Path('/mydir/apphome/logs'))
3330+
self.assertEqual(scheme.data, Path('/mydir/apphome/data'))
3331+
self.assertEqual(scheme.tmp, Path('/var/tmp/test_app'))
3332+
self.assertEqual(scheme.cache, Path('/mydir/apphome/cache'))
3333+
self.assertEqual(scheme.srv, Path('/mydir/apphome/srv'))
3334+
self.assertEqual(scheme.user_config, Path('~/.config/test_app').expanduser())
3335+
self.assertEqual(scheme.user_data, Path('~/.local/share/test_app').expanduser())
3336+
self.assertEqual(scheme.user_sync, Path('~/.local/sync/test_app').expanduser())
3337+
self.assertEqual(scheme.user_cache, Path('~/.cache/test_app').expanduser())
32433338

32443339
if __name__ == '__main__':
32453340
unittest_main()
32463341

3247-
#class TestFloatOption(BaseConfigTest):
3248-
#"Unit tests for firebird.base.config.FloatOption"
3342+
#class Test<TYPE>Option(BaseConfigTest):
3343+
#"Unit tests for firebird.base.config.<TYPE>Option"
32493344
#def setUp(self):
32503345
#super().setUp()
32513346
#def test_simple(self):

0 commit comments

Comments
 (0)
0