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