Skip to content

Commit

Permalink
Merge pull request #77 from valentingol/logo
Browse files Browse the repository at this point in the history
🔊 Add Info/Warning logging
  • Loading branch information
valentingol authored Jan 8, 2024
2 parents d9a83e6 + 3f678c2 commit 65fca6c
Show file tree
Hide file tree
Showing 6 changed files with 37 additions and 47 deletions.
2 changes: 0 additions & 2 deletions cliconfig/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,6 @@ class Config:
Examples
--------
```python
>>> config = Config({"a": 1, "b": {"c": 2}})
>>> config.dict
{"a": 1, "b": {"c": 2}}
Expand All @@ -35,7 +34,6 @@ class Config:
Config({"c": 2}, [])
>>> config.b.c
2
```
"""

def __init__(
Expand Down
17 changes: 11 additions & 6 deletions cliconfig/config_routines.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
# Copyright (c) 2023 Valentin Goldite. All Rights Reserved.
"""Low-level and high-level functions to manipulate config."""
import logging
import sys
from copy import deepcopy
from typing import Any, Dict, List, Optional, Union
Expand Down Expand Up @@ -66,8 +67,8 @@ def make_config(
the processing list (config.process_list) which can be used to apply
further processing routines.
Note
----
Notes
-----
Setting additional arguments from CLI that are not in default configs
does NOT raise an error but only a warning. This ensures the compatibility
with other CLI usage (e.g notebook, argparse, etc.)
Expand Down Expand Up @@ -124,20 +125,24 @@ def make_config(
del cli_params_dict[key]
if new_keys:
new_keys_message = " - " + "\n - ".join(new_keys)
print(
message = (
"[CONFIG] Warning: New keys found in CLI parameters "
f"that will not be merged:\n{new_keys_message}"
)
logging.warning(message)
print(message)
# Merge CLI parameters
cli_params_config = Config(cli_params_dict, [])
config = merge_flat_processing(
config, cli_params_config, allow_new_keys=False, preprocess_first=False
)
print(
message = (
f"[CONFIG] Info: Merged {len(default_config_paths)} default config(s), "
f"{len(additional_config_paths)} additional config(s) and "
f"{len(cli_params_dict)} CLI parameter(s)."
)
logging.info(message)
print(message)
config = end_build_processing(config)
config.dict = unflatten(config.dict)
return config
Expand Down Expand Up @@ -179,8 +184,8 @@ def load_config(
the processing list (config.process_list) which can be used to apply
further processing routines.
Note
----
Notes
-----
If default configs are provided, the function does not allow new keys
for the loaded config. This is for helping the user to see how to
adapt the config file if the default configs have changed.
Expand Down
27 changes: 8 additions & 19 deletions cliconfig/dict_routines.py
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,6 @@ def merge_flat(
Examples
--------
```python
>>> merge_dict({'a.b': 1, 'a': {'c': 2}}, {'c': 3}, allow_new_keys=True)
{'a.b': 1, 'a.c': 2, 'c': 3}
>>> merge_dict({'a.b': 1, 'a': {'c': 2}}, {'c': 3}, allow_new_keys=False)
Expand All @@ -64,7 +63,6 @@ def merge_flat(
ValueError: duplicated key 'a.b'.
The above exception was the direct cause of the following exception:
ValueError: You may consider calling 'clean_pre_flat' on dict 1 before merging.
```
"""
# Flatten dicts
flat_dict1, flat_dict2 = _flat_before_merge(dict1, dict2)
Expand Down Expand Up @@ -162,11 +160,8 @@ def flatten(in_dict: Dict[str, Any]) -> Dict[str, Any]:
Work even if in_dict is a mix of nested and flat dictionaries.
For instance like this:
```python
>>> flatten({'a.b': {'c': 1}, 'a': {'b.d': 2}, 'a.e': {'f.g': 3}})
{'a.b.c': 1, 'a.b.d': 2, 'a.e.f.g': 3}
```
Parameters
----------
Expand All @@ -183,8 +178,8 @@ def flatten(in_dict: Dict[str, Any]) -> Dict[str, Any]:
flat_dict : Dict[str, Any]
The flattened dict.
Note
----
Notes
-----
Nested empty dict are ignored even if they are conflicting (see last example).
Examples
Expand Down Expand Up @@ -226,13 +221,11 @@ def unflatten(flat_dict: Dict[str, Any]) -> Dict[str, Any]:
Examples
--------
```python
>>> unflatten({'a.b': 1, 'a.c': 2, 'c': 3})
{'a': {'b': 1, 'c': 2}, 'c': 3}
>>> unflatten({'a.b': 1, 'a': {'c': 2}})
ValueError: duplicated key 'a'
The dict must be flatten before calling unflatten function.
```
"""
try:
unflat_dict = _unflatten(flat_dict, splitter="dot")
Expand Down Expand Up @@ -269,8 +262,8 @@ def clean_pre_flat(in_dict: Dict[str, Any], priority: str) -> Dict[str, Any]:
Dict[str, Any]
The cleansed dict.
Warning
-------
Warns
-----
* No flat key can contain a dict. Then, dicts like `{'a.b': {'c': 1}}`
are not supported.
* All the keys that contain dots (the flat keys) must be at the root.
Expand All @@ -280,14 +273,12 @@ def clean_pre_flat(in_dict: Dict[str, Any], priority: str) -> Dict[str, Any]:
Examples
--------
```python
>>> clean_pre_flat({'a.b': 1, 'a': {'b': 2}, 'c': 3}, priority='flat')
{'a.b': 1, 'c': 3}
>>> clean_pre_flat({'a.b': 1, 'a': {'b': 2}, 'c': 3}, priority='unflat')
{'a': {'b': 2}, 'c': 3}
>>> clean_pre_flat({'a.b': 1, 'a': {'b': 2}, 'c': 3}, priority='error')
ValueError: duplicated key 'a.b'
```
"""
if priority in ("flat", "unflat"):
# Check that there are no conflicts
Expand Down Expand Up @@ -339,8 +330,8 @@ def _del_key(
ValueError
If the key is not found in the dict.
Warning
-------
Warns
-----
* No flat key can contain a dict. Then, dicts like `{'a.b': {'c': 1}}`
are not supported.
* All the keys that contain dots (the flat keys) must be at the root.
Expand All @@ -350,7 +341,6 @@ def _del_key(
Examples
--------
```python
>>> in_dict = {'a': {'b': {'c': 1}, 'd': 2}, 'a.b.c': 4}
>>> _del_key(in_dict, 'a.b.c'); in_dict
{'a': {'d': 2}}
Expand All @@ -362,7 +352,6 @@ def _del_key(
ValueError: Key 'a.b.z' not found in dict.
>>> _del_key(in_dict, 'a.z.c')
ValueError: Key 'a.z.c' not found in dict.
```
"""
found_key = False
if not keep_flat and flat_key in in_dict:
Expand Down Expand Up @@ -437,8 +426,8 @@ def load_dict(path: str) -> Dict[str, Any]:
out_dict : Dict[str, Any]
The nested (unflatten) loaded dict.
Note
----
Notes
-----
* If multiple yaml files are in the same document, they are merged
from the first to the last.
* To use multiple yaml tags, separate them with "@". E.g. `!tag1@tag2`.
Expand Down
4 changes: 2 additions & 2 deletions cliconfig/processing/_type_parser.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,8 +25,8 @@ def _parse_type(type_desc: str) -> Tuple:
ValueError
If the type description is not valid or not recognized.
Note
----
Notes
-----
The type description is lowercased and spaces are removed before parsing.
"""
# Clean up
Expand Down
28 changes: 14 additions & 14 deletions cliconfig/processing/builtin.py
Original file line number Diff line number Diff line change
Expand Up @@ -195,8 +195,8 @@ class ProcessCopy(Processing):
{'a': {'b': 1, 'c': 1}}
```
Note
----
Notes
-----
* The copy key is protected against any modification and will raise an error
if you try to modify it but will be updated if the copied key is updated.
* If the key to copy does not exist in the config on post-merge, no error
Expand Down Expand Up @@ -330,8 +330,8 @@ class ProcessDef(Processing):
Now the parameter d is automatically updated if a.b or a.c changes
while also remaining editable by it-self.
Note
----
Notes
-----
* Unlike @copy processing you can change the value by setting
an other value or an other definition with @def.
* Unlike copy processing all the keys used in expression
Expand Down Expand Up @@ -421,8 +421,8 @@ class ProcessTyping(Processing):
End-build order: 20.0
Pre-save order: 0.0
Note
----
Notes
-----
* The conversion into union type is from left to right. For instance,
`param@type:List[str|float]: [True]` is converted to `["True"]`.
* The type is not checked on pre-merge or post-merge to allow the parameter
Expand Down Expand Up @@ -554,8 +554,8 @@ class ProcessSelect(Processing):
Result in deleting `models.model2` (`param1` and `param2`) and
`models.model4.param`, and keeping the rest.
Warning
-------
Warns
-----
For security reasons, this processing prevents from deleting
the configuration at the root, which is the case when the
selected key doesn't contain a dot. It raises an error in this case.
Expand Down Expand Up @@ -671,8 +671,8 @@ class ProcessDelete(Processing):
random names like "1", "2", "3", we use the `@delete` tag to delete the
keys after the pre-merge processing.
Warning
-------
Warns
-----
The sub-config/parameter is deleted on pre-merge. Therefore, if the parameter
also exists on the other configuration during merge (without the tag),
this parameter will be remain as it is. This processing is more used
Expand Down Expand Up @@ -730,8 +730,8 @@ class ProcessNew(Processing):
Without the `@new` tag, an error is raised because param2 is not present in
the default configuration.
Note
----
Notes
-----
* Tag a subconfig by adding `@new` at the end of the key containing
the sub-config dict in your yaml file.
* When a parameter is added with this processing, it is possible to modify it
Expand Down Expand Up @@ -821,8 +821,8 @@ class ProcessDict(Processing):
The `swep` parameter is considered as a single dict object
and not as a sub-config for merging.
Warning
-------
Warns
-----
* Processings are not applied in the dict keys. In particular,
the tags are not used and not removed.
* The tag `@dict` must be added at the key containing
Expand Down
6 changes: 2 additions & 4 deletions cliconfig/tag_routines.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,16 +25,14 @@ def clean_tag(flat_key: str, tag_name: str) -> str:
flat_key : str
The cleaned flat key.
Note
----
Notes
-----
`tag_name` is supposed to be the exact name of the tag.
Examples
--------
```python
>>> clean_tag('abc@tag.def@tag_2.ghi@tag', 'tag')
abc.def@tag_2.ghi
```
"""
if tag_name[0] == "@":
tag_name = tag_name[1:]
Expand Down

0 comments on commit 65fca6c

Please sign in to comment.