Converting YAML file to dataclass with nested dataclasses and optional keyword arguments

32 views Asked by At

I want to read in a YAML file and convert it into a python dataclass. The goal in this example is to be able to produce the same dataclass.

Without reading a YAML file:

from dataclasses import dataclass, field


@dataclass
class OptionsSource:
    a: str
    b: str = None
    kwargs: dict = field(default_factory=dict)

    def __post_init__(self):
        for k, v in self.kwargs.items():
            setattr(self, k, v)


@dataclass
class OptionsInput:
    file: str
    source: list[OptionsSource] = field(default_factory=list[OptionsSource], kw_only=True)


@dataclass
class Options:
    inputs: OptionsInput = field(default_factory=OptionsInput, kw_only=True)


options = Options(
    inputs=OptionsInput(
        file='file1',
        source=[
            OptionsSource(a=1, b=2, kwargs={'c': 3}),
            OptionsSource(a=10, b=20)
        ]
    ))
>>>print(options)
Options(inputs=OptionsInput(file='file1', source=[OptionsSource(a=1, b=2, kwargs={'c': 3}), OptionsSource(a=10, b=20, kwargs={})]))

>>>print(options.inputs.source[0].c)
3

Now, when I read this YAML, my output is different (i.e., OptionsSource dataclass isn't used).

yaml_input = yaml.load("""
inputs:
    file: file1
    source:
        - a: 1
          b: 2
          c: 3
        - a: 10
          b: 20
""", Loader=yaml.FullLoader)

options_from_yaml = Options(inputs=OptionsInput(**yaml_input['inputs']))
>>>print(options_from_yaml)
Options(inputs=OptionsInput(file='file1', source=[{'a': 1, 'b': 2, 'c': 3}, {'a': 10, 'b': 20}]))

My desired output is for options_from_yaml to match options.

My two problems:

  1. source isn't a list of OptionsSource
  2. I can't figure out how the kwargs piece of OptionsSource to let me provide any keyword arguments and have them stored so it can be accessed with options.inputs.source[0].c.
0

There are 0 answers