-
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
Infer from type-annotations for auto-config support #294
Comments
Interesting use case. The configuration for >>> instantiate(builds(Car, populate_full_signature=True))
...
MissingMandatoryValue: Missing mandatory value: driver
full_key: driver
object_type=Builds_Car This is why the If we provide a default for driver, >>> instantiate(builds(Car, populate_full_signature=True))
...
HydraZenUnsupportedPrimitiveError: Building: Car ..
The configured value <__main__.Driver object at 0x000001AE702572B0>, for field `driver`, is not supported by Hydra -- serializing or instantiating this config would ultimately result in an error.
Consider using `hydra_zen.builds(<class '__main__.Driver'>, ...)` create a config for this particular value. I'm thinking the best approach is to configure if __name__ == "__main__":
cs = ConfigStore.instance()
cs.store(
name="config",
node=builds(
Car,
driver=builds(Driver, populate_full_signature=True),
populate_full_signature=True,
)
)
my_app() Here the output would be what you expect: _target_: __main__.Car
driver:
_target_: __main__.Driver
name: Bob
age: 16 |
Oh, just playing around with this idea. I'm guessing you'd want swapable configs for if __name__ == "__main__":
cs = ConfigStore.instance()
cs.store(
name="default", group="car", node=builds(Car, populate_full_signature=True)
)
cs.store(
name="default",
group="car/driver",
node=builds(Driver, populate_full_signature=True),
)
cs.store(
name="config",
node=make_config(
hydra_defaults=["_self_", {"car": "default"}, {"car/driver": "default"}]
),
)
my_app() Here the _target_: __main__.Car
driver:
_target_: __main__.Driver
name: Bob
age: 16 |
To clarify, I understand why this fails from a technical standpoint. My question is more around the use-ability of displaying Therefore I'm left with the decision to either
Neither option is completely satisfactory, so I was hoping this might spark additional brainstorming. Perhaps there is no win-win solution though, in which case I would opt for the first approach since I think use-ability is more important than conciseness |
I agree that it would be nice to have the
Indeed you have! I had never considered leveraging type-annotations to help populate a hierarchical config (e.g. where a
I wouldn't want hydra-zen to lead people down this sort of design path, where you are designing a class that only works properly in the context of Hydra, via recursive instantiation. Something like the solution you proposed would be much nicer. I am currently working on my write up for #293, but I will be thinking about your proposal in the meantime, and will get back to you ASAP. Thanks for sharing your thoughts and ideas on this! |
Sorry, my comments were mostly me thinking out loud on the issue. I was definitely intrigued and frustrated that there didn't seem to be an approach to provide configuration information about this type of interface. It's been ingrained in me that I have to provide configs.
I think this would be very powerful. |
builds(populate_full_signature=True)
When
builds(..., populate_full_signature=True)
is used on an object that expects recursive instantiation, the example config from a script's--help
doesn't provide the user with any insight about the nested fields (and their potential defaults). To demonstrate, I've adapted this Hydra example to use Zen for the config creationThe help output is
The correct CLI override syntax would be something like
driver='{name:Bob, age:25}'
, but a user cannot discern this without reading the source code which is rather unfortunate. As an alternative, I can switch the type-hint inCar
to have a default like soThis provides a much more informative help output which lets the user see that they must provide
driver.name
, butdriver.age
is optional and defaults to 16Would it be reasonable to propagate the
populate_full_signature
kwarg frombuilds(Car)
through to the recursiveDriver
parameter automatically? It seems oddly redundant to have to specify it both withcs.store()
and then again in the type-hints. Especially if the signature ofCar
required multiple nested objectsThe text was updated successfully, but these errors were encountered: