From 6661f27de1e08e4137d76b44658c5a21decce040 Mon Sep 17 00:00:00 2001 From: Ryan Soklaski Date: Mon, 10 May 2021 23:09:28 -0400 Subject: [PATCH 1/8] remove unused interpolation util --- src/hydra_zen/structured_configs/_utils.py | 32 ---------------------- tests/test_utils.py | 29 +------------------- 2 files changed, 1 insertion(+), 60 deletions(-) diff --git a/src/hydra_zen/structured_configs/_utils.py b/src/hydra_zen/structured_configs/_utils.py index e91dc915f..204dfd492 100644 --- a/src/hydra_zen/structured_configs/_utils.py +++ b/src/hydra_zen/structured_configs/_utils.py @@ -142,38 +142,6 @@ def get_obj_path(obj: Any) -> str: return f"{module}.{name}" -def interpolated(func: Union[str, Callable], *literals: Any) -> str: - """Produces an hydra-style interpolated string for calling the provided - function on the literals - - Parameters - ---------- - func : Union[str, Callable] - The name of the function to use in the interpolation. The name - will be inferred if a function is provided. - - literals : Any - Position-only literals to be fed to the function. - - Notes - ----- - See https://omegaconf.readthedocs.io/en/latest/usage.html#custom-interpolations - for more details about leveraging custom interpolations in omegaconf/hydra. - - Examples - -------- - >>> def add(x, y): return x + y - >>> interpolated(add, 1, 2) - '${add:1,2}' - """ - if not isinstance(func, str) and not hasattr(func, "__name__"): # pragma: no cover - raise TypeError( - f"`func` must be a string or have a `__name__` field, got: {func}" - ) - name = func if isinstance(func, str) else func.__name__ - return f"${{{name}:{','.join(repr(i) for i in literals)}}}" - - NoneType = type(None) diff --git a/tests/test_utils.py b/tests/test_utils.py index ea5c16a3a..29c8de0bb 100644 --- a/tests/test_utils.py +++ b/tests/test_utils.py @@ -20,11 +20,9 @@ from typing_extensions import Final, Literal from hydra_zen import builds, instantiate, mutable_value -from hydra_zen.structured_configs._utils import interpolated, safe_name, sanitized_type +from hydra_zen.structured_configs._utils import safe_name, sanitized_type from hydra_zen.typing import Builds -from . import valid_hydra_literals - T = TypeVar("T") current_module: str = sys.modules[__name__].__name__ @@ -38,31 +36,6 @@ def pass_through_kwargs(**kwargs): return kwargs -omegaconf.OmegaConf.register_new_resolver("_test_pass_through", pass_through) - - -@given(st.lists(valid_hydra_literals)) -def test_interpolate_roundtrip(literals): - interpolated_string = interpolated("_test_pass_through", *literals) - - note(interpolated_string) - - interpolated_literals = OmegaConf.create({"x": interpolated_string}).x - - assert len(literals) == len(interpolated_literals) - - for lit, interp in zip(literals, interpolated_literals): - assert lit == interp - - -OmegaConf.register_new_resolver("len", len) - - -def test_interpolation_with_string_literal(): - cc = instantiate(builds(dict, total=interpolated(len, "9"))) - assert cc["total"] == 1 - - class C: def __repr__(self): return "C as a repr" From 26c2ff5d4804e6f52e2cbc43d2620dd3d820be4e Mon Sep 17 00:00:00 2001 From: Ryan Soklaski Date: Mon, 10 May 2021 23:40:05 -0400 Subject: [PATCH 2/8] attempt fix of compatibility-breaking change from hydra-core 1.1.0dev7 --- setup.cfg | 2 +- setup.py | 2 +- src/hydra_zen/experimental/_implementations.py | 10 +++++++--- 3 files changed, 9 insertions(+), 5 deletions(-) diff --git a/setup.cfg b/setup.cfg index 7efd87aed..ac8456b60 100644 --- a/setup.cfg +++ b/setup.cfg @@ -41,7 +41,7 @@ commands = pytest \ [testenv:min-hydra] # test against earliest supported version of hydra -deps = hydra-core==1.1.0dev5 +deps = hydra-core==1.1.0dev7 {[testenv]deps} basepython = python3.7 diff --git a/setup.py b/setup.py index 336cab30b..549d28cf2 100644 --- a/setup.py +++ b/setup.py @@ -22,7 +22,7 @@ ] KEYWORDS = "machine learning research configuration scalable reproducible" INSTALL_REQUIRES = [ - "hydra-core >= 1.1.0dev5", + "hydra-core >= 1.1.0dev7", "typing-extensions >= 3.7.4.1", ] TESTS_REQUIRE = [ diff --git a/src/hydra_zen/experimental/_implementations.py b/src/hydra_zen/experimental/_implementations.py index 118cd49f8..1677429ac 100644 --- a/src/hydra_zen/experimental/_implementations.py +++ b/src/hydra_zen/experimental/_implementations.py @@ -3,13 +3,15 @@ from pathlib import Path from typing import Any, Callable, List, Mapping, Optional, Union +from hydra import compose, initialize +from hydra._internal.callbacks import Callbacks from hydra._internal.hydra import Hydra from hydra._internal.utils import create_config_search_path from hydra.core.config_store import ConfigStore from hydra.core.global_hydra import GlobalHydra from hydra.core.utils import JobReturn, run_job -from hydra.experimental import compose, initialize from hydra.plugins.sweeper import Sweeper +from hydra.types import HydraContext from omegaconf import DictConfig from .._hydra_overloads import instantiate @@ -323,7 +325,7 @@ def hydra_multirun( # Only the hydra overrides are needed to extract the Hydra configuration for # the launcher and sweepers. - # The sweeper handles the overides for each experiment + # The sweeper handles the overrides for each experiment config_name = _store_config(config, config_name) task_cfg = _load_config(config_name=config_name, overrides=hydra_overrides) @@ -338,7 +340,9 @@ def hydra_multirun( assert isinstance(sweeper, Sweeper) sweeper.setup( config=task_cfg, - config_loader=hydra.config_loader, + hydra_context=HydraContext( + hydra.config_loader, callbacks=Callbacks(task_cfg) + ), task_function=task_function, ) From 02b211a40f5528990074224b3064643a51225e21 Mon Sep 17 00:00:00 2001 From: Justin Goodwin Date: Tue, 11 May 2021 13:20:00 -0400 Subject: [PATCH 3/8] fix depcrations --- .../experimental/_implementations.py | 32 ++++++++++++++++--- 1 file changed, 28 insertions(+), 4 deletions(-) diff --git a/src/hydra_zen/experimental/_implementations.py b/src/hydra_zen/experimental/_implementations.py index 1677429ac..12db82ab9 100644 --- a/src/hydra_zen/experimental/_implementations.py +++ b/src/hydra_zen/experimental/_implementations.py @@ -78,7 +78,7 @@ def _load_config( .. [3] https://hydra.cc/docs/advanced/override_grammar/basic """ - with initialize(): + with initialize(config_path="."): task_cfg = compose( config_name, overrides=[] if overrides is None else overrides, @@ -92,7 +92,9 @@ def hydra_run( config: Union[DataClass, DictConfig, Mapping], task_function: Callable[[DictConfig], Any], overrides: Optional[List[str]] = None, + config_dir: Optional[Union[str, Path]] = None, config_name: str = "hydra_run", + job_name: str = "hydra_run", ) -> JobReturn: """Launch a Hydra job defined by `task_function` using the configuration provided in `config`. @@ -123,6 +125,9 @@ def hydra_run( config_dir: Optional[Union[str, Path]] (default: None) Add configuration directories if needed. + config_name: str (default: "hydra_run") + Name of the stored configuration in Hydra's ConfigStore API. + job_name: str (default: "hydra_run") Returns @@ -188,14 +193,28 @@ def hydra_run( config_name = _store_config(config, config_name) task_cfg = _load_config(config_name=config_name, overrides=overrides) + if config_dir is not None: + config_dir = str(Path(config_dir).absolute()) + search_path = create_config_search_path(config_dir) + + hydra = Hydra.create_main_hydra2(task_name=job_name, config_search_path=search_path) + try: + callbacks = Callbacks(task_cfg) + callbacks.on_run_start(config=task_cfg, config_name=config_name) + job = run_job( + hydra_context=HydraContext( + config_loader=hydra.config_loader, callbacks=callbacks + ), config=task_cfg, task_function=task_function, job_dir_key="hydra.run.dir", job_subdir_key=None, configure_logging=False, ) + + callbacks.on_run_end(config=task_cfg, config_name=config_name, job_return=job) finally: GlobalHydra.instance().clear() return job @@ -246,6 +265,9 @@ def hydra_multirun( config_dir: Optional[Union[str, Path]] (default: None) Add configuration directories if needed. + config_name: str (default: "hydra_run") + Name of the stored configuration in Hydra's ConfigStore API. + job_name: str (default: "hydra_multirun") Returns @@ -335,14 +357,15 @@ def hydra_multirun( hydra = Hydra.create_main_hydra2(task_name=job_name, config_search_path=search_path) try: + callbacks = Callbacks(task_cfg) + callbacks.on_multirun_start(config=task_cfg, config_name=config_name) + # Instantiate sweeper without using Hydra's Plugin discovery sweeper = instantiate(task_cfg.hydra.sweeper) assert isinstance(sweeper, Sweeper) sweeper.setup( config=task_cfg, - hydra_context=HydraContext( - hydra.config_loader, callbacks=Callbacks(task_cfg) - ), + hydra_context=HydraContext(hydra.config_loader, callbacks=callbacks), task_function=task_function, ) @@ -352,6 +375,7 @@ def hydra_multirun( # just ensures repeats are removed _overrides = list(set(_overrides)) job = sweeper.sweep(arguments=_overrides) + callbacks.on_multirun_end(config=task_cfg, config_name=config_name) finally: GlobalHydra.instance().clear() return job From ec965ef21dd619a09cc2eb1845bf370923cc80d9 Mon Sep 17 00:00:00 2001 From: Justin Goodwin Date: Tue, 11 May 2021 13:45:23 -0400 Subject: [PATCH 4/8] change default; update test for coverage --- src/hydra_zen/experimental/_implementations.py | 2 +- tests/experimental/test_implementations.py | 10 ++++++++-- 2 files changed, 9 insertions(+), 3 deletions(-) diff --git a/src/hydra_zen/experimental/_implementations.py b/src/hydra_zen/experimental/_implementations.py index 12db82ab9..86dc46a05 100644 --- a/src/hydra_zen/experimental/_implementations.py +++ b/src/hydra_zen/experimental/_implementations.py @@ -78,7 +78,7 @@ def _load_config( .. [3] https://hydra.cc/docs/advanced/override_grammar/basic """ - with initialize(config_path="."): + with initialize(config_path=None): task_cfg = compose( config_name, overrides=[] if overrides is None else overrides, diff --git a/tests/experimental/test_implementations.py b/tests/experimental/test_implementations.py index ac19a6705..9aad85701 100644 --- a/tests/experimental/test_implementations.py +++ b/tests/experimental/test_implementations.py @@ -39,7 +39,10 @@ def test_store_config(as_dataclass, as_dictconfig): @pytest.mark.parametrize( "as_dictconfig, with_hydra", [(True, True), (True, False), (False, False)] ) -def test_hydra_run_job(overrides, as_dataclass, as_dictconfig, with_hydra): +@pytest.mark.parametrize("use_default_dir", [True, False]) +def test_hydra_run_job( + overrides, as_dataclass, as_dictconfig, with_hydra, use_default_dir +): if not as_dataclass: cfg = dict(a=1, b=1) else: @@ -55,7 +58,10 @@ def test_hydra_run_job(overrides, as_dataclass, as_dictconfig, with_hydra): cfg = _load_config(cn, overrides=overrides) overrides = [] - job = hydra_run(cfg, task_function=instantiate, overrides=overrides) + additl_kwargs = {} if use_default_dir else dict(config_dir=Path.cwd()) + job = hydra_run( + cfg, task_function=instantiate, overrides=overrides, **additl_kwargs + ) assert job.return_value == {"a": 1, "b": 1} if override_exists == 1: From c2fcda96877cf3d71568ff8aa3b3ef612b87b7ed Mon Sep 17 00:00:00 2001 From: Justin Goodwin Date: Tue, 11 May 2021 16:15:06 -0400 Subject: [PATCH 5/8] added tests --- .../experimental/_implementations.py | 11 ++-- tests/experimental/test_callbacks.py | 56 +++++++++++++++++++ tests/experimental/test_implementations.py | 24 ++++++-- 3 files changed, 81 insertions(+), 10 deletions(-) create mode 100644 tests/experimental/test_callbacks.py diff --git a/src/hydra_zen/experimental/_implementations.py b/src/hydra_zen/experimental/_implementations.py index 86dc46a05..1dabd8a74 100644 --- a/src/hydra_zen/experimental/_implementations.py +++ b/src/hydra_zen/experimental/_implementations.py @@ -339,11 +339,12 @@ def hydra_multirun( # Separate Hydra overrides from experiment overrides hydra_overrides = [] _overrides = [] - for o in overrides: - if o.startswith("hydra"): - hydra_overrides.append(o) - else: - _overrides.append(o) + if overrides is not None: + for o in overrides: + if o.startswith("hydra"): + hydra_overrides.append(o) + else: + _overrides.append(o) # Only the hydra overrides are needed to extract the Hydra configuration for # the launcher and sweepers. diff --git a/tests/experimental/test_callbacks.py b/tests/experimental/test_callbacks.py new file mode 100644 index 000000000..947684392 --- /dev/null +++ b/tests/experimental/test_callbacks.py @@ -0,0 +1,56 @@ +import pytest + +from omegaconf import DictConfig +from hydra.experimental.callback import Callback +from hydra.core.utils import JobReturn +from hydra.core.config_store import ConfigStore + +from hydra_zen import instantiate, builds +from hydra_zen.experimental import hydra_run, hydra_multirun + + +class CustomCallback(Callback): + def __init__(self, callback_name): + self.name = callback_name + + def on_job_start(self, config: DictConfig, **kwargs) -> None: + ... + + def on_job_end(self, config: DictConfig, job_return: JobReturn, **kwargs) -> None: + ... + + def on_run_start(self, config: DictConfig, **kwargs) -> None: + ... + + def on_run_end(self, config: DictConfig, **kwargs) -> None: + ... + + def on_multirun_start(self, config: DictConfig, **kwargs) -> None: + ... + + def on_multirun_end(self, config: DictConfig, **kwargs) -> None: + ... + + +cs = ConfigStore.instance() +cs.store( + group="hydra/callbacks", + name="test_callback", + node=dict(test_callback=builds(CustomCallback, callback_name="test")), +) + + +@pytest.mark.usefixtures("cleandir") +@pytest.mark.parametrize("fn", [hydra_run, hydra_multirun]) +def test_hydra_run_with_callback(fn): + cfg = dict(a=1, b=1) + job = fn( + cfg, task_function=instantiate, overrides=["hydra/callbacks=test_callback"] + ) + + if fn == hydra_run: + assert "test_callback" in job.hydra_cfg.hydra.callbacks + + if fn == hydra_multirun: + job = job[0][0] + assert "test_callback" in job.hydra_cfg.hydra.callbacks diff --git a/tests/experimental/test_implementations.py b/tests/experimental/test_implementations.py index 9aad85701..bbc690001 100644 --- a/tests/experimental/test_implementations.py +++ b/tests/experimental/test_implementations.py @@ -73,19 +73,27 @@ def test_hydra_run_job( "overrides", [None, [], ["hydra.sweep.dir=test_hydra_overrided"]], ) +@pytest.mark.parametrize( + "multirun_overrides", + [None, ["a=1,2"]], +) @pytest.mark.parametrize("as_dataclass", [True, False]) @pytest.mark.parametrize( "as_dictconfig, with_hydra", [(True, True), (True, False), (False, False)] ) @pytest.mark.parametrize("use_default_dir", [True, False]) def test_hydra_multirun( - overrides, as_dataclass, as_dictconfig, with_hydra, use_default_dir + overrides, + multirun_overrides, + as_dataclass, + as_dictconfig, + with_hydra, + use_default_dir, ): if not as_dataclass: cfg = dict(a=1, b=1) else: cfg = builds(dict, a=1, b=1) - multirun_overrides = ["a=1,2"] override_exists = overrides and len(overrides) > 1 if as_dictconfig: @@ -97,9 +105,15 @@ def test_hydra_multirun( overrides = [] additl_kwargs = {} if use_default_dir else dict(config_dir=Path.cwd()) - _overrides = ( - multirun_overrides if overrides is None else (overrides + multirun_overrides) - ) + + _overrides = overrides + if multirun_overrides is not None: + _overrides = ( + multirun_overrides + if overrides is None + else (overrides + multirun_overrides) + ) + job = hydra_multirun( cfg, task_function=instantiate, overrides=_overrides, **additl_kwargs ) From a795a1f0b570073d7c32144de7896b1962253be0 Mon Sep 17 00:00:00 2001 From: Justin Goodwin Date: Tue, 11 May 2021 16:54:17 -0400 Subject: [PATCH 6/8] fixed return type for multirun; docstring updates --- .../experimental/_implementations.py | 31 ++++++++----------- 1 file changed, 13 insertions(+), 18 deletions(-) diff --git a/src/hydra_zen/experimental/_implementations.py b/src/hydra_zen/experimental/_implementations.py index 1dabd8a74..563cf2435 100644 --- a/src/hydra_zen/experimental/_implementations.py +++ b/src/hydra_zen/experimental/_implementations.py @@ -21,7 +21,7 @@ def _store_config( cfg: Union[DataClass, DictConfig, Mapping], config_name: str = "hydra_launch" ) -> str: - """Generates a Structured Config and registers it in the ConfigStore. + """Stores configuration object in Hydra's ConfigStore. Parameters ---------- @@ -29,7 +29,7 @@ def _store_config( A configuration as a dataclass, configuration object, or a dictionary. config_name: str (default: hydra_launch) - A default configuration name if available, otherwise a new object is + The configuration name used to store the configuration. Returns ------- @@ -66,6 +66,7 @@ def _load_config( Returns ------- config: DictConfig + The configuration object including Hydra configuration. Notes ----- @@ -73,9 +74,9 @@ def _load_config( References ---------- - .. [1] https://hydra.cc/docs/experimental/compose_api - .. [2] https://hydra.cc/docs/configure_hydra/intro - .. [3] https://hydra.cc/docs/advanced/override_grammar/basic + .. [1] https://hydra.cc/docs/next/advanced/compose_api + .. [2] https://hydra.cc/docs/next/configure_hydra/intro + .. [3] https://hydra.cc/docs/next/advanced/override_grammar/basic """ with initialize(config_path=None): @@ -143,8 +144,8 @@ def hydra_run( References ---------- - .. [1] https://hydra.cc/docs/advanced/override_grammar/basic - .. [2] https://hydra.cc/docs/configure_hydra/intro + .. [1] https://hydra.cc/docs/next/advanced/override_grammar/basic + .. [2] https://hydra.cc/docs/next/configure_hydra/intro Examples -------- @@ -227,7 +228,7 @@ def hydra_multirun( config_dir: Optional[Union[str, Path]] = None, config_name: str = "hydra_multirun", job_name: str = "hydra_multirun", -) -> List[JobReturn]: +) -> List[Any]: """Launch a Hydra multi-run ([1]_) job defined by `task_function` using the configuration provided in `config`. @@ -272,20 +273,14 @@ def hydra_multirun( Returns ------- - result: List[List[JobReturn]] - The object storing the results of each Hydra experiment. - - overrides: From `overrides` and `multirun_overrides` - - return_value: The return value of the task function - - cfg: The configuration object sent to the task function - - hydra_cfg: The hydra configuration object - - working_dir: The experiment working directory - - task_name: The task name of the Hydra job + result: List[List[Any]] + The return values of all launched jobs (depends on the Sweeper implementation). References ---------- .. [1] https://hydra.cc/docs/tutorials/basic/running_your_app/multi-run - .. [2] https://hydra.cc/docs/advanced/override_grammar/basic - .. [3] https://hydra.cc/docs/configure_hydra/intro + .. [2] https://hydra.cc/docs/next/advanced/override_grammar/basic + .. [3] https://hydra.cc/docs/next/configure_hydra/intro Examples -------- From 3d6e7e9f8d489d6d6f5311cd48c9e2a1fd9bc23f Mon Sep 17 00:00:00 2001 From: Ryan Soklaski Date: Tue, 11 May 2021 17:53:50 -0400 Subject: [PATCH 7/8] test that callback methods are called in order --- tests/experimental/test_callbacks.py | 101 +++++++++++++++++++++------ 1 file changed, 80 insertions(+), 21 deletions(-) diff --git a/tests/experimental/test_callbacks.py b/tests/experimental/test_callbacks.py index 947684392..e75c68fcb 100644 --- a/tests/experimental/test_callbacks.py +++ b/tests/experimental/test_callbacks.py @@ -1,35 +1,54 @@ -import pytest +from typing import NamedTuple -from omegaconf import DictConfig -from hydra.experimental.callback import Callback -from hydra.core.utils import JobReturn +import pytest from hydra.core.config_store import ConfigStore +from hydra.core.utils import JobReturn +from hydra.experimental.callback import Callback +from omegaconf import DictConfig + +from hydra_zen import builds, instantiate +from hydra_zen.experimental import hydra_multirun, hydra_run + -from hydra_zen import instantiate, builds -from hydra_zen.experimental import hydra_run, hydra_multirun +class Tracker(NamedTuple): + job_start: bool = False + job_end: bool = False + run_start: bool = False + run_end: bool = False + multirun_start: bool = False + multirun_end: bool = False class CustomCallback(Callback): + JOB_START_CALLED = False + JOB_END_CALLED = False + + RUN_START_CALLED = False + RUN_END_CALLED = False + + MULTIRUN_START_CALLED = False + MULTIRUN_END_CALLED = False + def __init__(self, callback_name): self.name = callback_name def on_job_start(self, config: DictConfig, **kwargs) -> None: - ... + CustomCallback.JOB_START_CALLED = True def on_job_end(self, config: DictConfig, job_return: JobReturn, **kwargs) -> None: - ... + CustomCallback.JOB_END_CALLED = True def on_run_start(self, config: DictConfig, **kwargs) -> None: - ... + CustomCallback.RUN_START_CALLED = True def on_run_end(self, config: DictConfig, **kwargs) -> None: - ... + CustomCallback.RUN_END_CALLED = True def on_multirun_start(self, config: DictConfig, **kwargs) -> None: - ... + CustomCallback.MULTIRUN_START_CALLED = True def on_multirun_end(self, config: DictConfig, **kwargs) -> None: - ... + CustomCallback.MULTIRUN_END_CALLED = True cs = ConfigStore.instance() @@ -40,17 +59,57 @@ def on_multirun_end(self, config: DictConfig, **kwargs) -> None: ) +def tracker(x=CustomCallback): + # this will get called after the job and run have started + # but before they end + return Tracker( + job_start=x.JOB_START_CALLED, + job_end=x.JOB_END_CALLED, + run_start=x.RUN_START_CALLED, + run_end=x.RUN_END_CALLED, + multirun_start=x.MULTIRUN_START_CALLED, + multirun_end=x.MULTIRUN_END_CALLED, + ) + + @pytest.mark.usefixtures("cleandir") @pytest.mark.parametrize("fn", [hydra_run, hydra_multirun]) def test_hydra_run_with_callback(fn): - cfg = dict(a=1, b=1) - job = fn( - cfg, task_function=instantiate, overrides=["hydra/callbacks=test_callback"] - ) + # Tests that callback methods are called during appropriate + # stages + try: + is_multirun = fn is hydra_multirun + + cfg = builds(tracker) + + assert not any(tracker()) # ensures all flags are false + + job = fn( + cfg, task_function=instantiate, overrides=["hydra/callbacks=test_callback"] + ) + + if is_multirun: + job = job[0][0] + + tracked_mid_run: Tracker = job.return_value + assert tracked_mid_run.job_start is True + assert tracked_mid_run.run_start is not is_multirun + assert tracked_mid_run.multirun_start is is_multirun + + assert tracked_mid_run.job_end is False + assert tracked_mid_run.run_end is False + assert tracked_mid_run.multirun_end is False + + assert CustomCallback.JOB_END_CALLED is True + assert CustomCallback.RUN_END_CALLED is not is_multirun + assert CustomCallback.MULTIRUN_END_CALLED is is_multirun + + finally: + CustomCallback.JOB_START_CALLED = False + CustomCallback.JOB_END_CALLED = False - if fn == hydra_run: - assert "test_callback" in job.hydra_cfg.hydra.callbacks + CustomCallback.RUN_START_CALLED = False + CustomCallback.RUN_END_CALLED = False - if fn == hydra_multirun: - job = job[0][0] - assert "test_callback" in job.hydra_cfg.hydra.callbacks + CustomCallback.MULTIRUN_START_CALLED = False + CustomCallback.MULTIRUN_END_CALLED = False From 0450662398f9e3e1e3de14d3bb79685e64781bdc Mon Sep 17 00:00:00 2001 From: Ryan Soklaski Date: Tue, 11 May 2021 21:12:55 -0400 Subject: [PATCH 8/8] remove return_job from callbacks.on_run_end --- src/hydra_zen/experimental/_implementations.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/hydra_zen/experimental/_implementations.py b/src/hydra_zen/experimental/_implementations.py index 563cf2435..11abcbe71 100644 --- a/src/hydra_zen/experimental/_implementations.py +++ b/src/hydra_zen/experimental/_implementations.py @@ -215,7 +215,7 @@ def hydra_run( configure_logging=False, ) - callbacks.on_run_end(config=task_cfg, config_name=config_name, job_return=job) + callbacks.on_run_end(config=task_cfg, config_name=config_name) finally: GlobalHydra.instance().clear() return job