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 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
- """Utility functions for config2py."""
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: Type of folder ('config', 'data', 'cache', 'state', or 'runtime')
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 get_app_data_folder(
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 data directory specific to the given app name and folder kind.
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
- - 'config': For configuration/settings files
410
- - 'data': For essential user data, databases, sessions
411
- - 'cache': For temporary/regeneratable data
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 data directory is needed.
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 'cache').
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 data directory.
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
- >>> get_app_data_folder() # doctest: +ELLIPSIS
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
- >>> get_app_data_folder('my_app', folder_kind='data') # doctest: +SKIP
449
+ >>> get_app_folder('my_app', folder_kind='data') # doctest: +SKIP
432
450
  '/Users/.../.local/share/my_app'
433
- >>> get_app_data_folder('my_app', folder_kind='cache') # doctest: +SKIP
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
- >>> get_app_data_folder('another/app/subfolder', folder_kind='data') # doctest: +SKIP
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 = get_app_data_folder('my_app', ensure_exists=True) # doctest: +SKIP
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 = get_app_data_folder(app_name, setup_callback=app_dir_setup_callback)
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 = get_app_data_folder # backwards compatibility alias
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.40
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 "Local App Data 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.
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 systems's "App Data" folder (also configurable via a `CONFIG2PY_APP_DATA_FOLDER` environment variable).
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
- * `get_app_data_folder`: Returns the full path of a directory suitable for storing application-specific data for a given app name.
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=GZ8lkm8TOKrV-zVd_Tc_8XVXDzFePECacjhOSGe2xcs,844
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=pnYRq7OnjOJfa3u0vhRXrleybJ6JCr39tByDsyB_qfA,20917
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.40.dist-info/LICENSE,sha256=xx0jnfkXJvxRnG63LTGOxlggYnIysveWIZ6H3PNdCrQ,11357
12
- config2py-0.1.40.dist-info/METADATA,sha256=5HPEIPtjVwB-QsYyNtgIRjACB4OKGPyrBAl48i-h_Ik,14541
13
- config2py-0.1.40.dist-info/WHEEL,sha256=tZoeGjtWxWRfdplE7E3d45VPlLNQnvbKiYnx7gwAy8A,92
14
- config2py-0.1.40.dist-info/top_level.txt,sha256=DFnlOIKMIGWQRROr3voJFhWFViHaWgTTeWZjC5YC9QQ,10
15
- config2py-0.1.40.dist-info/RECORD,,
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,,