config2py 0.1.28__tar.gz → 0.1.30__tar.gz

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.
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: config2py
3
- Version: 0.1.28
3
+ Version: 0.1.30
4
4
  Summary: Simplified reading and writing configurations from various sources and formats
5
5
  Home-page: https://github.com/i2mint/config2py
6
6
  Author: OtoSense
@@ -1,6 +1,7 @@
1
1
  """
2
2
  Base for getting configs from various sources and formats
3
3
  """
4
+
4
5
  from collections import ChainMap
5
6
  from typing import (
6
7
  Callable,
@@ -317,6 +318,15 @@ class FuncBasedGettableContainer:
317
318
  else:
318
319
  return True
319
320
 
321
+ def __iter__(self):
322
+ raise TypeError(
323
+ f'Iteration is NOT ACTUALLY implemented for {type(self).__name__}. '
324
+ 'The reason we still stuck it in the class is because python will '
325
+ 'automatically try to use __getitem__ on 0, 1, ... to iterate over the '
326
+ 'object, and we want to avoid that, since this would result in an obscure '
327
+ "error message saying that the getter function can't be called on 0"
328
+ )
329
+
320
330
 
321
331
  def gettable_containers(
322
332
  sources: Sources,
@@ -353,11 +363,19 @@ KTSaver = Callable[[KT, VT], Any]
353
363
  SaveTo = Optional[Union[MutableMapping, KTSaver]]
354
364
 
355
365
 
366
+ def is_not_empty(val) -> bool:
367
+ if isinstance(val, str):
368
+ return val != ''
369
+ else:
370
+ return val is not None
371
+
372
+
356
373
  def ask_user_for_key(
357
374
  key=None,
358
375
  *,
359
376
  prompt_template='Enter a value for {}: ',
360
377
  save_to: SaveTo = None,
378
+ save_condition=is_not_empty,
361
379
  user_asker=ask_user_for_input,
362
380
  egress: Optional[Callable] = None,
363
381
  ):
@@ -372,7 +390,7 @@ def ask_user_for_key(
372
390
  val = user_asker(prompt_template.format(key))
373
391
  if isinstance(egress, Callable):
374
392
  val = egress(key, val)
375
- if save_to is not None:
393
+ if save_to is not None and save_condition(val):
376
394
  if hasattr(save_to, '__setitem__'):
377
395
  save_to_func = save_to.__setitem__
378
396
  save_to_func(key, val)
@@ -397,7 +415,7 @@ def user_gettable(
397
415
  contain a placeholder for the key, e.g. ``"Enter a value for {}: "``.
398
416
  :param egress: A function to apply to the user's response before returning it.
399
417
  This can be used to validate the response, for example.
400
- :param user_asker: A function that asks the user for input. It should take a
418
+ :param user_asker: A function that asks the user for input. It should take a
401
419
  prompt string and return the user's response.
402
420
  :param val_is_valid: A function that takes a value and returns a boolean. If it
403
421
  returns ``False``, the user will be asked for a new value.
@@ -408,7 +426,7 @@ def user_gettable(
408
426
  it.
409
427
 
410
428
  Example:
411
-
429
+
412
430
  >>> s = user_gettable()
413
431
  >>> v = s['SOME_KEY'] # doctest: +SKIP
414
432
  'SOME_VAL'
@@ -416,8 +434,8 @@ def user_gettable(
416
434
  This will trigger a prompt for the user to enter the value of ``SOME_KEY``.
417
435
  When they do (say they entered 'SOME_VAL') it will return that value.
418
436
 
419
- And if you specify a save_to store (usually a persistent MutableMapping made with
420
- the ``dol`` package) then it will save the value to that store for future use.
437
+ And if you specify a save_to store (usually a persistent MutableMapping made with
438
+ the ``dol`` package) then it will save the value to that store for future use.
421
439
 
422
440
  >>> d = dict(some='store')
423
441
  >>> s = user_gettable(save_to=d)
@@ -21,6 +21,11 @@ def identity(x: Any) -> Any:
21
21
  return x
22
22
 
23
23
 
24
+ def is_not_empty(x: Any) -> bool:
25
+ """Function that returns True if x is not empty."""
26
+ return bool(x)
27
+
28
+
24
29
  # TODO: Make this into an open-closed mini-framework
25
30
  def ask_user_for_input(
26
31
  prompt: str,
@@ -55,9 +60,12 @@ def ask_user_for_input(
55
60
  if default:
56
61
  prompt = prompt + f' [{default}]: '
57
62
  if mask_input:
58
- response = getpass.getpass(prompt)
63
+ _prompt_func = getpass.getpass
59
64
  else:
60
- response = input(prompt)
65
+ _prompt_func = input
66
+
67
+ response = _prompt_func(prompt)
68
+
61
69
  if masking_toggle_str is not None and response == masking_toggle_str:
62
70
  return ask_user_for_input(
63
71
  _original_prompt,
@@ -292,8 +300,8 @@ def get_app_data_folder(
292
300
  >>> get_app_data_folder() # doctest: +ELLIPSIS
293
301
  '.../.config/config2py'
294
302
 
295
- You can specify a different app name though.
296
- And if you want, you can also specify a callback function to initialize the
303
+ You can specify a different app name though.
304
+ And if you want, you can also specify a callback function to initialize the
297
305
  directory.
298
306
 
299
307
  >>> path = get_app_data_folder('my_app', ensure_exists=True) # doctest: +SKIP
@@ -395,7 +403,7 @@ def is_repl():
395
403
  return False
396
404
 
397
405
 
398
- is_repl.repl_conditions: Set[Callable] = _repl_conditions
406
+ is_repl.repl_conditions: Set[Callable] = _repl_conditions # type: ignore
399
407
 
400
408
 
401
409
  def _value_node_is_instance_of(
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: config2py
3
- Version: 0.1.28
3
+ Version: 0.1.30
4
4
  Summary: Simplified reading and writing configurations from various sources and formats
5
5
  Home-page: https://github.com/i2mint/config2py
6
6
  Author: OtoSense
@@ -1,6 +1,6 @@
1
1
  [metadata]
2
2
  name = config2py
3
- version = 0.1.28
3
+ version = 0.1.30
4
4
  url = https://github.com/i2mint/config2py
5
5
  platforms = any
6
6
  description_file = README.md
File without changes
File without changes
File without changes