Skip to content
This repository has been archived by the owner on Aug 19, 2023. It is now read-only.

Nested unions are not (de-)serialized correctly #133

Open
jonasehrlich opened this issue Jul 31, 2020 · 0 comments
Open

Nested unions are not (de-)serialized correctly #133

jonasehrlich opened this issue Jul 31, 2020 · 0 comments

Comments

@jonasehrlich
Copy link

jonasehrlich commented Jul 31, 2020

When using nested Unions, deserialization does not happen correctly.
Consider the following structure:

class StatusEnum(Enum):
    IDLE = auto() 
    RUNNING = auto()

@dataclass
class Cfg(JsonSchemaMixin):
    status: ty.Dict[str, ty.Union[ty.List[StatusEnum], ty.List[str], str]] = field(default_factory=lambda: {
        'name': 'orchestrator',
        'worker_state': [StatusEnum.IDLE, StatusEnum.IDLE],
        'worker_names': ['worker1', 'worker2']
    })

# Just for reference using a different type hint order
@dataclass
class Cfg2(JsonSchemaMixin):
    status: ty.Dict[str, ty.Union[str, ty.List[StatusEnum], ty.List[str]]] = field(default_factory=lambda: {
        'name': 'orchestrator',
        'worker_state': [StatusEnum.IDLE, StatusEnum.IDLE],
        'worker_names': ['worker1', 'worker2']
    })

Serialization

print(Cfg().to_dict())
{'status': {'name': 'orchestrator', 'worker_state': [<StatusEnum.IDLE: 1>, <StatusEnum.IDLE: 1>], 'worker_names': ['worker1', 'worker2']}}

print(Cfg2().to_dict())
{'status': {'name': 'orchestrator', 'worker_state': [<StatusEnum.IDLE: 1>, <StatusEnum.IDLE: 1>], 'worker_names': ['worker1', 'worker2']}}

# expected output
{'status': {'name': 'orchestrator', 'worker_state': [1, 1], 'worker_names': ['worker1', 'worker2']}}

Deserialization

d = {"status": {"name": ['orchestrator'], "worker_state": [1, 1], "worker_names": ["worker1", "worker2"]}}
print(Cfg.from_dict(d))
Cfg(status={'name': ['orchestrator'], 'worker_state': [1, 1], 'worker_names': ['worker1', 'worker2']})

print(Cfg.from_dict(d))
Cfg(status={'name': ['orchestrator'], 'worker_state': [1, 1], 'worker_names': ['worker1', 'worker2']})

# expected output
Cfg(status={'name': ['orchestrator'], 'worker_state': [<StatusEnum.IDLE: 1>, <StatusEnum.IDLE: 1>], 'worker_names': ['worker1', 'worker2']})

I assume the better solutions for nested structures would be, to use another dataclass, but this is not possible, because we are on the transition to use dataclasses-jsonschema. Is there another way this kind of nested union could be achieved?

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant