Closed zhiruiluo closed 1 year ago
Hey there @zhiruiluo , I'm unable to reproduce the issue:
from __future__ import annotations
from dataclasses import dataclass, field
import functools
import pytest
from simple_parsing.helpers.serialization import from_dict, to_dict
from simple_parsing.utils import Dataclass
@dataclass
class Level1:
arg: int = 1
@dataclass
class Level2:
arg: int = 1
prev: Level1 = field(default_factory=Level1)
@pytest.mark.parametrize("config", [Level1(arg=2), Level2(arg=2, prev=Level1(arg=3)),])
def test_nested_dataclass(config: Dataclass):
_from_dict = functools.partial(from_dict, type(config))
assert _from_dict(to_dict(config)) == config
assert _from_dict(to_dict(config), drop_extra_fields=True)
assert to_dict(_from_dict(to_dict(config))) == to_dict(config)
assert _from_dict(to_dict(_from_dict(to_dict(config)))) == _from_dict(to_dict(config))
Do you have an example that doesn't work?
Hmm actually I am getting some errors when using your tests directly. I'll investigate.
The tests raise the following UserWarning:
UserWarning: Unable to find a decoding function for the annotation <class 'test_issue_210.Level2'> (of type <class 'type'>). Will try to use the type as a constructor. Consider registering a decoding function using `register_decoding_fn`, or posting an issue on GitHub.
This is somewhat expected, given that the dataclasses don't inherit from Serializable.
However, it makes sense that we should be able to create dataclasses from dictionaries, even if they don't inherit from Serializable
.
I'll take a closer look at how we can fix this.
Hey there @zhiruiluo , I'm unable to reproduce the issue:
from __future__ import annotations from dataclasses import dataclass, field import functools import pytest from simple_parsing.helpers.serialization import from_dict, to_dict from simple_parsing.utils import Dataclass @dataclass class Level1: arg: int = 1 @dataclass class Level2: arg: int = 1 prev: Level1 = field(default_factory=Level1) @pytest.mark.parametrize("config", [Level1(arg=2), Level2(arg=2, prev=Level1(arg=3)),]) def test_nested_dataclass(config: Dataclass): _from_dict = functools.partial(from_dict, type(config)) assert _from_dict(to_dict(config)) == config assert _from_dict(to_dict(config), drop_extra_fields=True) assert to_dict(_from_dict(to_dict(config))) == to_dict(config) assert _from_dict(to_dict(_from_dict(to_dict(config)))) == _from_dict(to_dict(config))
Do you have an example that doesn't work?
One layer of nesting will work, but two layers or more nesting will fail.
The tests raise the following UserWarning:
UserWarning: Unable to find a decoding function for the annotation <class 'test_issue_210.Level2'> (of type <class 'type'>). Will try to use the type as a constructor. Consider registering a decoding function using `register_decoding_fn`, or posting an issue on GitHub.
This is somewhat expected, given that the dataclasses don't inherit from Serializable. However, it makes sense that we should be able to create dataclasses from dictionaries, even if they don't inherit from
Serializable
. I'll take a closer look at how we can fix this.
After adding serializable to all dataclasses, the test passed. I misunderstood the actual behivor of the Serializable
. Something might be wrong for #211. I was naturally thinking that to_dict
and from_dict
will work without Serializable
.
Yes you're right @zhiruiluo , from_dict
and to_dict
are supposed to work with all dataclasses, not just those that subclass Serializable
.
I'll make a bugfix PR for this soon. Thanks for pointing it out.
Describe the bug A clear and concise description of what the bug is.
To Reproduce
Expected behavior A clear and concise description of what you expected to happen.
Actual behavior A clear and concise description of what is happening.
Desktop (please complete the following information):
Additional context Add any other context about the problem here.