Skip to content

quast_decisiontree.core.data_handling

quast_decisiontree.core.data_handling

logger module-attribute

logger = logging.getLogger('dt_logger')

load_config

load_config(filename)

Loads a yaml file into a dictionary as required by all configuration routines.

Parameters:

Name Type Description Default
filename str | Path

The file path of the yaml file.

required

Returns:

Type Description
dict

A dictionary with the content of the yaml file, or an empty dict if the file is not found.

Source code in src/quast_decisiontree/core/data_handling.py
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
def load_config(filename: str | Path) -> dict:
    """Loads a yaml file into a dictionary as required by all configuration routines.

    Args:
        filename: The file path of the yaml file.

    Returns:
        A dictionary with the content of the yaml file, or an empty dict if the file is not found.
    """
    try:
        with open(filename) as stream:
            out = yaml.safe_load(stream)
        return out
    except FileNotFoundError:
        return {}

save_dict

save_dict(
    dict_to_save,
    folder,
    filename="dict.json",
    filetype="json",
    no_save_keys=None,
)

Will save the dictionary in question as far as possible, skipping keys that can't be put into a JSON-compatible format.

Parameters:

Name Type Description Default
dict_to_save dict

the dictionary to save

required
folder str

the folder where to save the dictionary to

required
filename str

the filename

'dict.json'
filetype str

json or yaml

'json'
no_save_keys list

Any keys at the top level that will not be saved

None

Returns:

Type Description
set

the set of top-level keys that couldn't be serialized

Source code in src/quast_decisiontree/core/data_handling.py
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
def save_dict(
    dict_to_save: dict,
    folder: str,
    filename: str = "dict.json",
    filetype: str = "json",
    no_save_keys: list | None = None,
) -> set:
    """Will save the dictionary in question as far as possible, skipping keys that can't be put
    into a JSON-compatible format.

    Args:
        dict_to_save (dict): the dictionary to save
        folder (str): the folder where to save the dictionary to
        filename (str, optional): the filename
        filetype (str, optional): json or yaml
        no_save_keys (list, optional): Any keys at the top level that will not be saved

    Returns:
        the set of top-level keys that couldn't be serialized
    """
    file_path = os.path.join(folder, filename)

    if no_save_keys is None:
        no_save_keys = []

    safe_dictionary = dict_to_save.copy()
    for key in no_save_keys:
        safe_dictionary.pop(key, None)

    safe_dictionary = deep_convert(safe_dictionary)

    with open(file_path, "w", encoding="utf8") as file:
        if filetype == "json":
            json.dump(safe_dictionary, file, indent=4)
        elif filetype == "yaml":
            yaml.dump(safe_dictionary, file, default_flow_style=False)

    skipped_keys = (
        set(dict_to_save.keys()).difference(safe_dictionary.keys()).difference(no_save_keys)
    )
    if skipped_keys:
        logger.info(
            "Could not serialize the following top-level keys, they were skipped: %s.",
            ", ".join(repr(key) for key in sorted(skipped_keys, key=str)),
        )

    return skipped_keys

register_serializer

register_serializer(func)

Register a converter.

The converter must return a JSON-safe value or raise NotSerializableError if it does not handle the given item.

Source code in src/quast_decisiontree/core/data_handling.py
91
92
93
94
95
96
97
98
def register_serializer(func: Callable[[Any], Any]) -> None:
    """Register a converter.

    The converter must return a JSON-safe value or raise
    NotSerializableError if it does not handle the given item.
    """
    if func not in _SERIALIZERS:
        _SERIALIZERS.append(func)

convert_to_serializable

convert_to_serializable(item)

Convert a single item to a JSON-safe value using registered serializers.

Raises NotSerializableError if no registered serializer handles the item.

Source code in src/quast_decisiontree/core/data_handling.py
101
102
103
104
105
106
107
108
109
110
111
def convert_to_serializable(item: Any) -> Any:
    """Convert a single item to a JSON-safe value using registered serializers.

    Raises NotSerializableError if no registered serializer handles the item.
    """
    for serializer in _SERIALIZERS:
        try:
            return serializer(item)
        except NotSerializableError:
            continue
    raise NotSerializableError

deep_convert

deep_convert(obj)

Recursively convert a nested structure into a JSON-safe equivalent.

Mapping entries that cannot be serialized are skipped and logged at debug level.

Source code in src/quast_decisiontree/core/data_handling.py
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
def deep_convert(obj: Any) -> Any:
    """Recursively convert a nested structure into a JSON-safe equivalent.

    Mapping entries that cannot be serialized are skipped and logged at debug level.
    """
    if isinstance(obj, dict):
        converted = {}
        for key, value in obj.items():
            try:
                converted[key] = deep_convert(value)
            except NotSerializableError:
                logger.debug("Skipping non-serializable entry for key %r.", key)
        return converted
    if isinstance(obj, list | tuple):
        return [deep_convert(value) for value in obj]
    if isinstance(obj, str | int | float | bool) or obj is None:
        return obj
    return convert_to_serializable(obj)