Skip to content

Commit

Permalink
Merge pull request #553 from mit-ll-responsible-ai/modularity
Browse files Browse the repository at this point in the history
Add customizable auto-config support to `builds` et al
  • Loading branch information
rsokl authored Oct 23, 2023
2 parents 2674fd5 + 5d4c47b commit 3be1c2c
Show file tree
Hide file tree
Showing 28 changed files with 3,015 additions and 2,377 deletions.
54 changes: 54 additions & 0 deletions docs/source/changes.rst
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,60 @@ Changelog
This is a record of all past hydra-zen releases and what went into them, in reverse
chronological order. All previous releases should still be available on pip.

.. _v0.12.0:

----------------------
0.12.0rc1 - 2023-10-23
----------------------


.. note:: This is documentation for an unreleased version of hydra-zen. You can try out this pre-release version using `pip install --pre hydra-zen`

This release makes hydra-zen's :ref:`auto-config <additional-types>` and :ref:`type-refinement <type-support>` capabilities fully customizable and extensible, while still preserving static type-checking 🎉.

It does so by exposing a customizable class – `hydra_zen.BuildsFn` – with methods that can be overridden to modify the aforementioned auto-config and type-refinement capabilities. This class then exposes the classmethods `just`, `builds`, and `make_config`, which will leverage these customized capabilities.

Here is a stripped-down example.

.. code-block:: python
:caption: Basic structure for adding custom auto-config support for a type.
from hydra_zen import BuildsFn
from hydra_zen.typing import SupportedPrimitive
# We want builds/just/make_config to be able to automatically
# configure instances of `SomeType`
class SomeType:
...
# The type parameter provided to `BuildsFn[...]` updates the type
# annotations of the config-creation functions so that type-checkers
# know that `SomeType` is now supported.
class CustomBuilds(BuildsFn[SomeType | SupportedPrimitive]):
"""
- To customize type-refinement support, override `_sanitized_type`.
- To customize auto-config support, override `_make_hydra_compatible`.
- To customize the ability to resolve import paths, override `_get_obj_path`.
"""
@classmethod
def _make_hydra_compatible(
cls, value, **kw
) -> SupportedPrimitive:
# Take some value and return a Hydra-compatible config for it.
if isinstance(value, SomeType):
return cls.builds(SomeType)
return super()._make_hydra_compatible(value, **kw)
# These config-creation functions now know how to automatically
# - and recursively - generate configs instances of `SomeType`
builds = CustomBuilds.builds
just = CustomBuilds.just
make_config = CustomBuilds.make_config
For more details and examples, see :pull:`553`.
.. _v0.11.0:
-------------------
Expand Down
4 changes: 3 additions & 1 deletion src/hydra_zen/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,12 +19,14 @@
make_custom_builds_fn,
mutable_value,
)
from .structured_configs._implementations import get_target
from .structured_configs._implementations import BuildsFn, DefaultBuilds, get_target
from .structured_configs._type_guards import is_partial_builds, uses_zen_processing
from .wrapper import ZenStore, store, zen

__all__ = [
"builds",
"BuildsFn",
"DefaultBuilds",
"hydrated_dataclass",
"just",
"mutable_value",
Expand Down
9 changes: 6 additions & 3 deletions src/hydra_zen/_hydra_overloads.py
Original file line number Diff line number Diff line change
Expand Up @@ -28,8 +28,11 @@
from hydra.utils import instantiate as hydra_instantiate
from omegaconf import MISSING, DictConfig, ListConfig, OmegaConf

from .structured_configs._just import just
from .structured_configs._value_conversion import ConfigComplex, ConfigPath
from .structured_configs._implementations import (
ConfigComplex,
ConfigPath,
DefaultBuilds,
)
from .typing import Builds, Just, Partial
from .typing._implementations import DataClass_, HasTarget, InstOrType, IsPartial

Expand Down Expand Up @@ -219,7 +222,7 @@ def _apply_just(fn: F) -> F:
@wraps(fn)
def wrapper(cfg: Any, *args: Any, **kwargs: Any):
if not is_dataclass(cfg):
cfg = just(cfg)
cfg = DefaultBuilds.just(cfg)
return fn(cfg, *args, **kwargs)

return cast(F, wrapper)
Expand Down
4 changes: 2 additions & 2 deletions src/hydra_zen/_utils/coerce.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,14 +12,14 @@
TypeVar,
Union,
cast,
get_args,
get_origin,
get_type_hints,
)

from omegaconf import ListConfig
from typing_extensions import TypeGuard

from hydra_zen.structured_configs._utils import get_args, get_origin

_T = TypeVar("_T", bound=Callable)

__all__ = ["coerce_sequences"]
Expand Down
8 changes: 4 additions & 4 deletions src/hydra_zen/structured_configs/_globals.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,7 @@

from typing_extensions import Final

from hydra_zen.funcs import get_obj, zen_processing
from hydra_zen.structured_configs import _utils
from hydra_zen.funcs import zen_processing

# Hydra-specific fields
TARGET_FIELD_NAME: Final[str] = "_target_"
Expand All @@ -30,8 +29,9 @@
del _names

# hydra-zen-specific fields
ZEN_PROCESSING_LOCATION: Final[str] = _utils.get_obj_path(zen_processing)
GET_OBJ_LOCATION: Final[str] = _utils.get_obj_path(get_obj)
ZEN_PROCESSING_LOCATION: Final[str] = ".".join(
[zen_processing.__module__, zen_processing.__name__]
)
ZEN_TARGET_FIELD_NAME: Final[str] = "_zen_target"
ZEN_PARTIAL_FIELD_NAME: Final[str] = "_zen_partial"
META_FIELD_NAME: Final[str] = "_zen_exclude"
Expand Down
Loading

0 comments on commit 3be1c2c

Please sign in to comment.