Coverage for src/configuraptor/dump.py: 100%
31 statements
« prev ^ index » next coverage.py v7.2.7, created at 2023-06-20 10:44 +0200
« prev ^ index » next coverage.py v7.2.7, created at 2023-06-20 10:44 +0200
1"""
2Method to dump classes to other formats.
3"""
5import json
6import typing
8import tomli_w
9import yaml
11from .core import instance_of_custom_class, is_custom_class
12from .helpers import camel_to_snake
15def asdict(inst: typing.Any, _level: int = 0, /, with_top_level_key: bool = True) -> dict[str, typing.Any]:
16 """
17 Dump a config instance to a dictionary (recursively).
18 """
19 data = {}
21 for key, value in inst.__dict__.items():
22 cls = value.__class__
23 if is_custom_class(cls):
24 value = asdict(value, _level + 1)
25 elif isinstance(value, list):
26 value = [asdict(_, _level + 1) if instance_of_custom_class(_) else _ for _ in value]
27 elif isinstance(value, dict):
28 value = {k: asdict(v, _level + 1) if instance_of_custom_class(v) else v for k, v in value.items()}
30 data[key] = value
32 if _level == 0 and with_top_level_key:
33 # top-level: add an extra key indicating the class' name
34 cls_name = camel_to_snake(inst.__class__.__name__)
35 return {cls_name: data}
37 return data
40def astoml(inst: typing.Any, multiline_strings: bool = False) -> str:
41 """
42 Dump a config instance to toml (recursively).
43 """
44 data = asdict(inst)
45 return tomli_w.dumps(data, multiline_strings=multiline_strings)
48def asjson(inst: typing.Any, **kw: typing.Any) -> str:
49 """
50 Dump a config instance to json (recursively).
51 """
52 data = asdict(inst)
53 return json.dumps(data, **kw)
56def asyaml(inst: typing.Any, **kw: typing.Any) -> str:
57 """
58 Dump a config instance to yaml (recursively).
59 """
60 data = asdict(inst)
61 output = yaml.dump(data, encoding=None, **kw)
62 # output is already a str but mypy doesn't know that
63 return typing.cast(str, output)