Skip to content

Commit

Permalink
Add strict validation against Hydra's supported primitives (#163)
Browse files Browse the repository at this point in the history
* add initial framework for zen value conversion

* Validate that all configured values satisfy Hydra serializability

* bugfix: ref to wrong variable

* cleanup test boilerplate

* fix bug

* add support for set; normalize builds-error

* add validation/conversion to contents of supported collections: tuple,list,dict

* Validation now requires exact match against types -- subclasses no longer permitted

* add tests for zen-supported primitives

* add support for complex values

* add support for Path objects

* remove extra complex implementation

* update type-annotations to reflect supported primitives

* add frozenset support

* improve test

* relax health checks

* eliminate redundant dict copy

* ensure zen-converted values are supported by Hydra

* Add support for enum members

* add explicit tests for supported  primitives

* add support for additional primitives

* remove straggler line

* clean up import

* make test compatible with python 3.6

* remove unused imports

* dataclasses are not permitted for dict-key nodes

* inline just-if-needed; dont permit structured configs as keys

* add support for omegaconf containers

* ensure omegaconf containers not permitted as dict keys

* remove unused function

* add annotation support for range; remove redundant annotations

* remove future import

* remove unused import

* add docs for features

* wrap long line

* test that meta fields are validated too

* remove commented print

* fix bad test
  • Loading branch information
rsokl authored Nov 26, 2021
1 parent 6b39c41 commit d70d29a
Show file tree
Hide file tree
Showing 14 changed files with 938 additions and 67 deletions.
49 changes: 49 additions & 0 deletions docs/source/api_reference.rst
Original file line number Diff line number Diff line change
Expand Up @@ -96,6 +96,55 @@ The following utilities can be used to work with YAML-serialized configs.
load_from_yaml


.. _valid-types:

**********************************************************
Configuration-Value Types Supported by Hydra and hydra-zen
**********************************************************

The types of values that can be specified in configs are limited by their ability to be
serialized to a YAML format. hydra-zen provides automatic support for an additional set
of common types via its :ref:`config-creation functions <create-config>`.

Types Supported Natively by Hydra
*********************************

Values of the following types can be specified directly in configs:

- ``NoneType``
- :py:class:`bool`
- :py:class:`int`
- :py:class:`float`
- :py:class:`str`
- :py:class:`list`
- :py:class:`dict`
- :py:class:`enum.Enum`


Types Supported via hydra-zen
*****************************

.. warning::

This section refers to capabilities that are not yet available in a stable release
of hydra-zen. They will be included in the release of `v0.4.0`.

hydra-zen will automatically create targeted configs to represent values of the
following types:

- :py:class:`bytes`
- :py:class:`bytearray`
- :py:class:`complex`
- :py:class:`collections.Counter`
- :py:class:`collections.deque`
- :py:class:`pathlib.Path`
- :py:class:`pathlib.PosixPath`
- :py:class:`pathlib.WindowsPath`
- :py:class:`range`
- :py:class:`set`
- :py:class:`frozenset`


*********************
Third-Party Utilities
*********************
Expand Down
111 changes: 108 additions & 3 deletions docs/source/changes.rst
Original file line number Diff line number Diff line change
Expand Up @@ -2,16 +2,121 @@
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.
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.4.0dev:

---------------------
0.4.0dev - 2021-11-26
---------------------

.. warning::

This section refers to capabilities that are not yet available in a stable release
of hydra-zen. They will be included in the release of `v0.4.0`.

This release makes improvements to the validation performed by hydra-zen's
:ref:`config-creation functions <create-config>`. It also adds specialized support for
types that are not natively supported by Hydra.


New Features
------------

Strict (Runtime and Static) Validation of Configuration-Value Types
===================================================================

See :pull:`163` for a detailed description of these features and their implementation
details.

hydra-zen's :ref:`config-creation functions <create-config>` (e.g.
:func:`~hydra_zen.make_config` and :func:`~hydra_zen.builds`) now provide both strict
runtime and static validation of the configured values that they are fed.
That is, creating a config that contains values of unsupported types will cause
hydra-zen to raise an error. hydra-zen's internal type annotations have also be refined
so that static type-checkers will "flag" such invalid configs as well.

Consider the following example:

.. code-block:: pycon
:caption: Demonstrating hydra-zen's runtime validation of configured values.
>>> from hydra_zen import make_config
>>> class SomeClass:
... pass
>>> unsupported_value = SomeClass()
>>> make_config(a=unsupported_value) # static type-checkers will mark this as invalid
HydraZenUnsupportedPrimitiveError: ...
Previously, no such error would be raised by hydra-zen; instead, the config would
eventually cause an error when it would be used to actually configure a Hydra job.
Now, invalid configs will be caught upon construction.

Consult :ref:`valid-types` for a complete list of the supported types of configuration
values.

Specialized Support for Additional Configuration-Value Types
============================================================

See :pull:`163` for a detailed description of these features and their implementation
details.

hydra-zen's :ref:`config-creation functions <create-config>` (e.g.
:func:`~hydra_zen.make_config` and :func:`~hydra_zen.builds`) now provide automatic
support for common configuration-value types, like :py:class:`complex` and
:py:class:`pathlib.Path`, which are not natively supported by Hydra; values of these
types will automatically be transformed into structured configs.

For example, consider the following config that contains values whose types are not
natively supported by Hydra.

.. code-block:: python
:caption: Leveraging hydra-zen's built-in support for additional types.
from hydra_zen import make_config, instantiate, to_yaml
from pathlib import Path
Conf = make_config(value=1+2j, home=Path.home())
hydra-zen automatically creates nested structured configs to represent these values;
note that these configs do not carry any direct dependencies on hydra-zen.

.. code-block:: pycon
>>> print(to_yaml(Conf))
value:
real: 1.0
imag: 2.0
_target_: builtins.complex
home:
_args_:
- C:\Users\Ryan Soklaski
_target_: pathlib.Path
Instantiating ``Conf`` will produce the expected values:

.. code-block:: pycon
>>> instantiate(Conf)
{'value': (1+2j), 'home': WindowsPath('C:/Users/Ryan Soklaski')}
Consult :ref:`valid-types` for a complete list of the additional types that hydra-zen
supports in this fashion.

.. _v0.3.1:

------------------
0.3.1 - 2021-11-13
------------------

The release fixes a bug that was reported in :issue:`161`. Prior to this patch,
This release fixes a bug that was reported in :issue:`161`. Prior to this patch,
there was a bug in :func:`~hydra_zen.builds` where specifying ``populate_full_sig=True``
for a target that did not have ``**kwargs`` caused all user-specified zen-meta fields
to be excluded from the resulting config.
Expand Down
4 changes: 4 additions & 0 deletions src/hydra_zen/errors.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,3 +14,7 @@ class HydraZenDeprecationWarning(HydraZenException, FutureWarning):
This is a subclass of FutureWarning, rather than DeprecationWarning, so
that the warnings that it emits are not filtered by default.
"""


class HydraZenUnsupportedPrimitiveError(HydraZenException, ValueError):
pass
Loading

0 comments on commit d70d29a

Please sign in to comment.