python ^3.7. Trying to create nested dataclasses to work with complex json response. I managed to do that with creating dataclass for every level of json and using __post_init_ to set fields as objects of other dataclasses. However that creates a lot of boilerplate code and also, there is no annotation for nested objects.
This answer helped me getting closer to the solution using wrapper:
https://stackoverflow.com/a/51565863/8325015
However it does not solve it for cases where attribute is list of objects. some_attribute: List[SomeClass]
Here is example that resembles my data:
from dataclasses import dataclass, is_dataclass
from typing import List
from copy import deepcopy
# decorator from the linked thread:
def nested_deco(*args, **kwargs):
    def wrapper(check_class):
        # passing class to investigate
        check_class = dataclass(check_class, **kwargs)
        o_init = check_class.__init__
        def __init__(self, *args, **kwargs):
            for name, value in kwargs.items():
                # getting field type
                ft = check_class.__annotations__.get(name, None)
                if is_dataclass(ft) and isinstance(value, dict):
                    obj = ft(**value)
                    kwargs[name] = obj
                o_init(self, *args, **kwargs)
        check_class.__init__ = __init__
        return check_class
    return wrapper(args[0]) if args else wrapper
#some dummy dataclasses to resemble my data structure
@dataclass
class IterationData:
    question1: str
    question2: str
@nested_deco
@dataclass
class IterationResult:
    name: str
    data: IterationData
@nested_deco
@dataclass
class IterationResults:
    iterations: List[IterationResult]
@dataclass
class InstanceData:
    date: str
    owner: str
@nested_deco
@dataclass
class Instance:
    data: InstanceData
    name: str
@nested_deco
@dataclass
class Result:
    status: str
    iteration_results: IterationResults
@nested_deco
@dataclass
class MergedInstance:
    instance: Instance
    result: Result
#example data
single_instance = {
    "instance": {
        "name": "example1",
        "data": {
            "date": "2021-01-01",
            "owner": "Maciek"
        }
    },
    "result": {
        "status": "complete",
        "iteration_results": [
            {
                "name": "first",
                "data": {
                    "question1": "yes",
                    "question2": "no"
                }
            }
        ]
    }
}
instances = [deepcopy(single_instance) for i in range(3)] #created a list just to resemble mydata
objres = [MergedInstance(**inst) for inst in instances]
As you will notice. nested_deco works perfectly for attributes of MergedInstance and for attribute data of Instance but it does not load IterationResults class on iteration_results of Result.
Is there a way to achieve it?
I attach also example with my post_init solution which creates objects of classes but there is no annotation of attributes:
@dataclass
class IterationData:
    question1: str
    question2: str
@dataclass
class IterationResult:
    name: str
    data: dict
    def __post_init__(self):
        self.data = IterationData(**self.data)
@dataclass
class InstanceData:
    date: str
    owner: str
@dataclass
class Instance:
    data: dict
    name: str
    def __post_init__(self):
        self.data = InstanceData(**self.data)
@dataclass
class Result:
    status: str
    iteration_results: list
    def __post_init__(self):
        self.iteration_results = [IterationResult(**res) for res in self.iteration_results]
@dataclass
class MergedInstance:
    instance: dict
    result: dict
    def __post_init__(self):
        self.instance = Instance(**self.instance)
        self.result = Result(**self.result)
 
     
     
    