-
Notifications
You must be signed in to change notification settings - Fork 15
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
builds
trouble with OmegaConf.to_object
#242
Comments
TL;DR
Actual ResponseThanks so much for looking into this @Jasha10 ! This is due to the fact that
# repro.py
from dataclasses import dataclass, field
from omegaconf import OmegaConf
@dataclass
class InitTrue:
x: int = field(default=1, init=True)
@dataclass
class InitFalse:
x: int = field(default=1, init=False)
Conf = OmegaConf.structured(InitTrue)
print("\nAll dataclass fields included in sig:")
print(OmegaConf.to_object(Conf))
Conf = OmegaConf.structured(InitFalse)
print("\nSome dataclass fields excluded from sig:")
print(OmegaConf.to_object(Conf)) $ python repro.py
All dataclass fields included in sig:
InitTrue(x=1)
Some dataclass fields excluded from sig:
Traceback (most recent call last):
File "repro.py", line 22, in <module>
print(OmegaConf.to_object(Conf))
File "C:\Users\Ryan Soklaski\Anaconda3\envs\hydra-zen\lib\site-packages\omegaconf\omegaconf.py", line 574, in to_object
return OmegaConf.to_container(
File "C:\Users\Ryan Soklaski\Anaconda3\envs\hydra-zen\lib\site-packages\omegaconf\omegaconf.py", line 553, in to_container
return BaseContainer._to_content(
File "C:\Users\Ryan Soklaski\Anaconda3\envs\hydra-zen\lib\site-packages\omegaconf\basecontainer.py", line 249, in _to_content
return conf._to_object()
File "C:\Users\Ryan Soklaski\Anaconda3\envs\hydra-zen\lib\site-packages\omegaconf\dictconfig.py", line 752, in _to_object
result = object_type(**field_items)
TypeError: __init__() got an unexpected keyword argument 'x' SolutionsThere are two solutions that I can think of here, which are not exclusive from one another. Changing behavior / exposing new behavior in
|
Got it! This idea of distinguishing between My only reservation here is that fields with |
Thanks for pointing me to omegaconf#789. I'm happy to move this conversation to that thread if it would be useful. (For the record: I think that the OP's recommendation – that OmegaConf should only care about fields that appear in the dataclass' signature – is backwards. As I advocate for above: OmegaConf should only care about the fields present on the object, regardless of its signature.) Handling
|
Actually... I think Consider the following behavior that currently occurs in OmegaConf: from dataclasses import dataclass, field
@dataclass
class A:
a: float
b: float
def __post_init__(self) -> None:
self.a = self.a ** 2
self.b = self.b ** 2 >>> cfg = OmegaConf.create(A(a=2, b=4))
>>> cfg
{'a': 4.0, 'b': 16.0}
>>> OmegaConf.to_object(cfg)
A(a=16.0, b=256.0) The fact that this doesn't roundtrip makes me think think that, in all cases, |
So, basically I think that # to_object({"a": 2, "b": 4.0}) would do:
obj = A(a=2.0, b=4.0)
obj.a = 2.0
obj.b = 4.0 If a user wants to run >>> obj
A(a=2.0, b=4.0)
>>> obj.__post_init__() # or perhaps this can be called via `to_object(cfg, post_init=True)`
A(a=4.0, b=16.0) |
@Jasha10 if it sounds good to you, I'll close this and move the discussion to omegaconf#789, where I'll summarize the relevant parts of this discussion (but much more concisely). |
That would be great. Thanks! |
I'm having trouble when calling
OmegaConf.to_object
on DictConfig objects backed by builds-generated dataclasses. Here is an example showing the difference in behavior between a hand-coded dataclass and one generated usingbuilds
:This fundamentally comes down to a difference in type signatures between
FooConfHandCoded.__init__
andFooConfBuilds.__init__
:The text was updated successfully, but these errors were encountered: