Add _target_wrapper_
to instantiate
and add pydantic parsing layer
#666
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Adds a new
_target_wrapper_
argument tohydra_zen.instantiate
, which enables users to introduce a custom wrapping layer of processing to the recursive instantiation process. I.e. specifyinginstantiate(cfg, _target_wrapper_=f)
means that for everytarget(*args, **kwargs)
that would have been called by the recursive instantiation process, insteadf(target)(*args, **kwargs)
will be called 1. This is also plumbed throughhydra_zen.zen
via the newinstantiation_wrapper
argument.This is a powerful addition to the
instantiate
&zen
APIs as it means that special parsing/validation can be introduced at the layer where CLI-configured values are passed to the constructors of the objects that are actually used by your program.Along these lines, this PR also adds
from hydra_zen.third_party.pydantic.pydantic_parser
, which can be passed in as a_target_wrapper_
. This adds pydantic-backed runtime type checking and annotation-based value conversions to all instantiation layers2.E.g.
Tearing out Hydra's type-checking and replacing it with pydantic parsing
First, tell hydra-zen's config store to strip out all type-annotations / structure from the stored configs. This ensures that Hydra is unable to get in our way when it comes to type-h
next, whenever you make your zen-wrapped task function, specify
pydantic_parser
as theinstantiation_wrapper
:and... that's it! Now only pydantic will perform runtime type checking and value conversions. Note that all of this type-information lives in the targets of the configs that you create and in the signature of the task function that is wrapped by
zen
.Footnotes
This is arguably the proper place for things like type-checking / value validation to occur. Hydra runs validation at the config-composition phase, which means that configs need to be annotated with the types of other configs; this leads to config-centric code producing more config-centric code. It is much simpler and more powerful to defer all validation to the actual code that is being configured and run by the Hydra application. ↩
Pydantic has more robust support for type-checking than Hydra. It can also perform annotation-based conversions, so that, e.g., a string-valued path specified at the CLI can be automatically be converted to a
pathlib.Path
during instantiation. ↩