config2py 0.1.40__py3-none-any.whl → 0.1.42__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- config2py/__init__.py +2 -0
- config2py/util.py +39 -17
- {config2py-0.1.40.dist-info → config2py-0.1.42.dist-info}/METADATA +6 -4
- {config2py-0.1.40.dist-info → config2py-0.1.42.dist-info}/RECORD +7 -7
- {config2py-0.1.40.dist-info → config2py-0.1.42.dist-info}/LICENSE +0 -0
- {config2py-0.1.40.dist-info → config2py-0.1.42.dist-info}/WHEEL +0 -0
- {config2py-0.1.40.dist-info → config2py-0.1.42.dist-info}/top_level.txt +0 -0
config2py/__init__.py
CHANGED
|
@@ -15,7 +15,9 @@ from config2py.base import get_config, user_gettable, sources_chainmap
|
|
|
15
15
|
from config2py.util import (
|
|
16
16
|
envvar, # os.environ, but with dict display override to hide secrets
|
|
17
17
|
ask_user_for_input,
|
|
18
|
+
get_app_config_folder,
|
|
18
19
|
get_app_data_folder,
|
|
20
|
+
get_app_folder,
|
|
19
21
|
get_configs_folder_for_app,
|
|
20
22
|
is_repl,
|
|
21
23
|
parse_assignments_from_py_source,
|
config2py/util.py
CHANGED
|
@@ -1,10 +1,14 @@
|
|
|
1
|
-
"""
|
|
1
|
+
"""
|
|
2
|
+
Utility functions for config2py.
|
|
3
|
+
|
|
4
|
+
"""
|
|
2
5
|
|
|
3
6
|
import re
|
|
4
7
|
import os
|
|
5
8
|
import ast
|
|
6
9
|
from collections import ChainMap, namedtuple
|
|
7
10
|
from pathlib import Path
|
|
11
|
+
from functools import partial
|
|
8
12
|
from typing import Optional, Union, Any, Callable, Set, Literal, get_args
|
|
9
13
|
from types import SimpleNamespace
|
|
10
14
|
import getpass
|
|
@@ -340,7 +344,16 @@ def get_app_rootdir(
|
|
|
340
344
|
- 'runtime': %TEMP%
|
|
341
345
|
|
|
342
346
|
Args:
|
|
343
|
-
folder_kind:
|
|
347
|
+
folder_kind (str): The kind of folder to get. One of 'config', 'data', 'cache', 'state', 'runtime'.
|
|
348
|
+
Defaults to 'config'.
|
|
349
|
+
Here are concise explanations for each folder kind:
|
|
350
|
+
**config**: User preferences and settings files (e.g., API keys, theme preferences, editor settings). Files users might edit manually or that define how the app behaves.
|
|
351
|
+
**data**: Essential user-created content and application state (e.g., databases, saved games, user documents, session files). Data that should be backed up and persists across updates.
|
|
352
|
+
**cache**: Temporary, regeneratable files (e.g., downloaded images, compiled assets, web cache). Can be safely deleted to free space without losing user work.
|
|
353
|
+
**state**: Application state and logs that persist between sessions but aren't critical user data (e.g., command history, undo history, recently opened files, log files). Unlike cache, shouldn't be auto-deleted.
|
|
354
|
+
**runtime**: Temporary runtime files that only exist while the app runs (e.g., PID files, Unix sockets, lock files, named pipes). Typically cleared on logout/reboot.
|
|
355
|
+
**TL;DR**: config = settings, data = user files, cache = disposable, state = logs/history, runtime = process files.
|
|
356
|
+
|
|
344
357
|
ensure_exists: Whether to create the directory if it doesn't exist
|
|
345
358
|
|
|
346
359
|
Returns:
|
|
@@ -355,6 +368,7 @@ def get_app_rootdir(
|
|
|
355
368
|
- If neither is set, uses platform defaults
|
|
356
369
|
|
|
357
370
|
Examples:
|
|
371
|
+
|
|
358
372
|
>>> get_app_rootdir('config') # doctest: +SKIP
|
|
359
373
|
'/Users/.../.config'
|
|
360
374
|
>>> get_app_rootdir('data') # doctest: +SKIP
|
|
@@ -395,7 +409,7 @@ def _default_folder_setup(directory_path: str) -> None:
|
|
|
395
409
|
(Path(directory_path) / ".config2py").write_text("Created by config2py.")
|
|
396
410
|
|
|
397
411
|
|
|
398
|
-
def
|
|
412
|
+
def get_app_folder(
|
|
399
413
|
app_name: str = DFLT_APP_NAME,
|
|
400
414
|
*,
|
|
401
415
|
setup_callback: Callable[[str], None] = _default_folder_setup,
|
|
@@ -403,45 +417,49 @@ def get_app_data_folder(
|
|
|
403
417
|
folder_kind: AppFolderKind = DFLT_APP_FOLDER_KIND,
|
|
404
418
|
) -> str:
|
|
405
419
|
"""
|
|
406
|
-
Retrieve or create the app
|
|
420
|
+
Retrieve or create the app directory specific to the given app name and folder kind.
|
|
407
421
|
|
|
408
422
|
The folder kind determines where the app's files are stored:
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
423
|
+
Here are concise explanations for each folder kind:
|
|
424
|
+
**config**: User preferences and settings files (e.g., API keys, theme preferences, editor settings). Files users might edit manually or that define how the app behaves.
|
|
425
|
+
**data**: Essential user-created content and application state (e.g., databases, saved games, user documents, session files). Data that should be backed up and persists across updates.
|
|
426
|
+
**cache**: Temporary, regeneratable files (e.g., downloaded images, compiled assets, web cache). Can be safely deleted to free space without losing user work.
|
|
427
|
+
**state**: Application state and logs that persist between sessions but aren't critical user data (e.g., command history, undo history, recently opened files, log files). Unlike cache, shouldn't be auto-deleted.
|
|
428
|
+
**runtime**: Temporary runtime files that only exist while the app runs (e.g., PID files, Unix sockets, lock files, named pipes). Typically cleared on logout/reboot.
|
|
429
|
+
**TL;DR**: config = settings, data = user files, cache = disposable, state = logs/history, runtime = process files.
|
|
412
430
|
|
|
413
431
|
Args:
|
|
414
|
-
app_name: Name of the app for which the
|
|
432
|
+
app_name: Name of the app for which the directory is needed.
|
|
415
433
|
setup_callback: A callback function to initialize the directory.
|
|
416
434
|
Default is _default_folder_setup.
|
|
417
435
|
ensure_exists: Whether to ensure the directory exists.
|
|
418
|
-
folder_kind: Type of folder ('config', 'data', or '
|
|
436
|
+
folder_kind: Type of folder ('config', 'data', 'cache', 'state', or 'runtime').
|
|
419
437
|
Default is 'config' for backward compatibility.
|
|
420
438
|
|
|
421
439
|
Returns:
|
|
422
|
-
str: Path to the app
|
|
440
|
+
str: Path to the app directory.
|
|
423
441
|
|
|
424
442
|
By default, the app will be "config2py" and folder_kind will be "config":
|
|
425
443
|
|
|
426
|
-
>>>
|
|
444
|
+
>>> get_app_folder() # doctest: +ELLIPSIS
|
|
427
445
|
'.../.config/config2py'
|
|
428
446
|
|
|
429
447
|
You can specify a different app name and folder kind:
|
|
430
448
|
|
|
431
|
-
>>>
|
|
449
|
+
>>> get_app_folder('my_app', folder_kind='data') # doctest: +SKIP
|
|
432
450
|
'/Users/.../.local/share/my_app'
|
|
433
|
-
>>>
|
|
451
|
+
>>> get_app_folder('my_app', folder_kind='cache') # doctest: +SKIP
|
|
434
452
|
'/Users/.../.cache/my_app'
|
|
435
453
|
|
|
436
454
|
You can also specify a path relative to the app root directory:
|
|
437
455
|
|
|
438
|
-
>>>
|
|
456
|
+
>>> get_app_folder('another/app/subfolder', folder_kind='data') # doctest: +SKIP
|
|
439
457
|
'/Users/.../.local/share/another/app/subfolder'
|
|
440
458
|
|
|
441
459
|
If ensure_exists is True, the directory will be created and initialized
|
|
442
460
|
with the setup_callback:
|
|
443
461
|
|
|
444
|
-
>>> path =
|
|
462
|
+
>>> path = get_app_folder('my_app', ensure_exists=True) # doctest: +SKIP
|
|
445
463
|
>>> os.path.exists(path) # doctest: +SKIP
|
|
446
464
|
True
|
|
447
465
|
"""
|
|
@@ -456,10 +474,14 @@ def get_app_data_folder(
|
|
|
456
474
|
return app_data_path
|
|
457
475
|
|
|
458
476
|
|
|
477
|
+
get_app_config_folder = partial(get_app_folder, folder_kind="config")
|
|
478
|
+
get_app_data_folder = partial(get_app_folder, folder_kind="data")
|
|
479
|
+
|
|
459
480
|
DFLT_CONFIGS_NAME = "configs"
|
|
460
481
|
|
|
461
482
|
|
|
462
483
|
# TODO: is "get" the right word, since it makes the folder too?
|
|
484
|
+
# TODO: Merge get_configs_folder_for_app and get_app_config_folder
|
|
463
485
|
def get_configs_folder_for_app(
|
|
464
486
|
app_name: str = DFLT_APP_NAME,
|
|
465
487
|
*,
|
|
@@ -478,13 +500,13 @@ def get_configs_folder_for_app(
|
|
|
478
500
|
- config_dir_setup_callback (Callable[[str], None]): A callback function to initialize the configs directory.
|
|
479
501
|
Default is _default_folder_setup.
|
|
480
502
|
"""
|
|
481
|
-
app_dir =
|
|
503
|
+
app_dir = get_app_config_folder(app_name, setup_callback=app_dir_setup_callback)
|
|
482
504
|
configs_dir = os.path.join(app_dir, configs_name)
|
|
483
505
|
config_dir_setup_callback(configs_dir)
|
|
484
506
|
return configs_dir
|
|
485
507
|
|
|
486
508
|
|
|
487
|
-
get_app_data_directory =
|
|
509
|
+
get_app_data_directory = get_app_config_folder # backwards compatibility alias
|
|
488
510
|
get_configs_directory_for_app = (
|
|
489
511
|
get_configs_folder_for_app # backwards compatibility alias
|
|
490
512
|
)
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.1
|
|
2
2
|
Name: config2py
|
|
3
|
-
Version: 0.1.
|
|
3
|
+
Version: 0.1.42
|
|
4
4
|
Summary: Simplified reading and writing configurations from various sources and formats
|
|
5
5
|
Home-page: https://github.com/i2mint/config2py
|
|
6
6
|
License: apache-2.0
|
|
@@ -110,7 +110,7 @@ In fact, `simple_config_getter` is a function to make configuration getters that
|
|
|
110
110
|
|
|
111
111
|
<img width="341" alt="image" src="https://github.com/i2mint/config2py/assets/1906276/09f287a8-05f9-4590-8664-10feda9ad617">
|
|
112
112
|
|
|
113
|
-
But where you can control what the central store (by default
|
|
113
|
+
But where you can control what the central store (by default a local configuration files store) is, and whether to first search in environment variables or not, and whether to ask the user for the value, if not found before, or not.
|
|
114
114
|
|
|
115
115
|
```python
|
|
116
116
|
from config2py import simple_config_getter, get_configs_local_store
|
|
@@ -130,7 +130,7 @@ print(*str(Sig(simple_config_getter)).split(','), sep='\n')
|
|
|
130
130
|
`ask_user_if_key_not_found` specifies whether to ask the user if a configuration key is not found. The default is `None`, which will result in checking if you're running in an interactive environment or not.
|
|
131
131
|
When you use `config2py` in production though, you should definitely specify `ask_user_if_key_not_found=False` to make that choice explicit.
|
|
132
132
|
|
|
133
|
-
The `configs_src` default is automatically set to be the `config2py/configs` folder of your
|
|
133
|
+
The `configs_src` default is automatically set to be the `config2py/configs` folder of your system's config directory (following XDG standards on Unix/Linux/macOS). You can override this with environment variables like `CONFIG2PY_CONFIG_DIR`, `CONFIG2PY_DATA_DIR`, etc., or the standard XDG variables.
|
|
134
134
|
|
|
135
135
|
Your central store will be `config_store_factory(configs_src)`, and since you can also specify `config_store_factory`, you have total control over the store.
|
|
136
136
|
|
|
@@ -215,7 +215,9 @@ user again.
|
|
|
215
215
|
* `get_config`: Get a config value from a list of sources. See more below.
|
|
216
216
|
* `user_gettable`: Create a ``GettableContainer`` that asks the user for a value, optionally saving it.
|
|
217
217
|
* `ask_user_for_input`: Ask the user for input, optionally masking, validating and transforming the input.
|
|
218
|
-
* `
|
|
218
|
+
* `get_app_folder`: Returns the full path of a directory suitable for storing application-specific data for a given app name and folder kind (config, data, cache, state, runtime).
|
|
219
|
+
* `get_app_config_folder`: Specialized version of `get_app_folder` for configuration files.
|
|
220
|
+
* `get_app_data_folder`: Specialized version of `get_app_folder` for application data.
|
|
219
221
|
* `get_configs_local_store`: Get a local store (mapping interface of local files) of configs for a given app or package name
|
|
220
222
|
* `configs`: A default store instance for configs, defaulting to a local store under a default configuration local directory.
|
|
221
223
|
|
|
@@ -1,15 +1,15 @@
|
|
|
1
|
-
config2py/__init__.py,sha256=
|
|
1
|
+
config2py/__init__.py,sha256=cxBsWlH6hy_xWP5pWUGN6ASfdz6LRwwxTleqqCVRcwg,891
|
|
2
2
|
config2py/base.py,sha256=eQpRQjZYT-z6GhBemepaPUEyVVP8e_l04dghYeBBJdI,15880
|
|
3
3
|
config2py/errors.py,sha256=QdwGsoJhv6LHDHp-_yyz4oUg1Fgu4S-S7O2nuA0a5cw,203
|
|
4
4
|
config2py/s_configparser.py,sha256=-Sl2-J-QOLUiahwhCTiPsmjs4cKc79JuTbQ9gQcOiGY,15871
|
|
5
5
|
config2py/tools.py,sha256=goDuHHXKJzdFgmHzDnLBGMZEhp0kKU-aK47c1-MpJT8,9199
|
|
6
|
-
config2py/util.py,sha256=
|
|
6
|
+
config2py/util.py,sha256=B4hhPH3DJSME7HfgOBYjnhDRU0pO8lvfwDhE3VX68VI,23290
|
|
7
7
|
config2py/scrap/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
8
8
|
config2py/tests/__init__.py,sha256=sk-yGJQOZES2z70M4xmZB57tsxSktX_84ybDuV8Cz5Q,297
|
|
9
9
|
config2py/tests/test_tools.py,sha256=sdiBNTavuzxW2AsqBRTO9U21iWig5DEyV38r6lmaZak,3728
|
|
10
10
|
config2py/tests/utils_for_testing.py,sha256=RcMiVtKK39rc8BsgIXQH3RCkd8qKo2o2MT7Rt0dJF2E,162
|
|
11
|
-
config2py-0.1.
|
|
12
|
-
config2py-0.1.
|
|
13
|
-
config2py-0.1.
|
|
14
|
-
config2py-0.1.
|
|
15
|
-
config2py-0.1.
|
|
11
|
+
config2py-0.1.42.dist-info/LICENSE,sha256=xx0jnfkXJvxRnG63LTGOxlggYnIysveWIZ6H3PNdCrQ,11357
|
|
12
|
+
config2py-0.1.42.dist-info/METADATA,sha256=Cd00j8Y99fIxAf3rvVogrINNp_3PNrrMcBzwy9Cyrv8,14880
|
|
13
|
+
config2py-0.1.42.dist-info/WHEEL,sha256=tZoeGjtWxWRfdplE7E3d45VPlLNQnvbKiYnx7gwAy8A,92
|
|
14
|
+
config2py-0.1.42.dist-info/top_level.txt,sha256=DFnlOIKMIGWQRROr3voJFhWFViHaWgTTeWZjC5YC9QQ,10
|
|
15
|
+
config2py-0.1.42.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|
|
File without changes
|