Skip to content
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

Provide support for functools.partial within config-creation funcs #197

Closed
rsokl opened this issue Jan 12, 2022 · 0 comments · Fixed by #199
Closed

Provide support for functools.partial within config-creation funcs #197

rsokl opened this issue Jan 12, 2022 · 0 comments · Fixed by #199
Labels
enhancement New feature or request

Comments

@rsokl
Copy link
Contributor

rsokl commented Jan 12, 2022

Note that this issue is not describing support for creating a partial-config; we already have this capability:

>>> instantiate(builds(dict, a=1, zen_partial=True))
functools.partial(dict, a=1)

rather it is about accommodating user-supplied/default values and builds-targets that are themselves partial'd targets.

Supporting builds(functools.partial(<target>, ...), ...)

Currently, attempting to use builds on a "partial'd" target raises an error because the __name__ of the object cannot be resolved (which is needed to determine _target_):

from hydra_zen import builds

from functools import partial
>>> builds(partial(dict))
---------------------------------------------------------------------------
AttributeError 
AttributeError: functools.partial(<class 'dict'>) does not have a `__name__` attribute

We can actually support this by "unpacking" the partial'd object. Under the hood, builds can detect if target "looks like" a partial and do:

 return builds(target.func, *target.args, **target.kwargs)

so that we get:

>>> Conf = builds(partial(dict, a=2))
>>> Conf
types.Builds_dict
>>> instantiate(Conf)  # should produce same result as `partial(dict, a=2)()`
{'a': 2}

As an aside, we should improve our error-reporting in this case. The reported attribute error will likely not lead users to a solution.

Supporting builds(target, x=functools.partial(func, a=1))

We can also support cases where a configured field is itself a partial'd object. We can similarly "unpack" the partial, but this time we will apply zen_partial=True so that the config instantiates back to the partial'd object.

E.g.

Conf = make_config(x=functools.partial(dict, a=1))

will effectively be equivalent to

Conf = make_config(x=builds(dict, a=1, zen_partial=True))

so that

>>> obj = instantiate(make_config(x=functools.partial(dict, a=1)))
>>> obj.x
functools.partial(dict, a=1)
@rsokl rsokl added the enhancement New feature or request label Jan 12, 2022
@rsokl rsokl changed the title Provide support for builds(functools.partial(target, ...), ...) Provide support for functools.partial within config-creation funcs Jan 12, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request
Projects
None yet
Development

Successfully merging a pull request may close this issue.

1 participant