Skip to content

Commit

Permalink
UW-653 controller key path (#604)
Browse files Browse the repository at this point in the history
  • Loading branch information
maddenp-noaa authored Sep 10, 2024
1 parent 38e4c7c commit 4e67e51
Show file tree
Hide file tree
Showing 2 changed files with 33 additions and 15 deletions.
37 changes: 24 additions & 13 deletions src/uwtools/drivers/driver.py
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ def __init__(
dry_run: bool = False,
key_path: Optional[list[str]] = None,
schema_file: Optional[Path] = None,
controller: Optional[str] = None,
controller: Optional[list[str]] = None,
) -> None:
config_input = config if isinstance(config, YAMLConfig) else YAMLConfig(config=config)
config_input.dereference(
Expand All @@ -65,8 +65,7 @@ def __init__(
self._config: dict = self._config_intermediate[self.driver_name()]
except KeyError as e:
raise UWConfigError("Required '%s' block missing in config" % self.driver_name()) from e
if controller:
self._config[STR.rundir] = self._config_intermediate[controller][STR.rundir]
self._delegate(controller, STR.rundir)
self.schema_file = schema_file
self._validate()
dryrun(enable=dry_run)
Expand Down Expand Up @@ -167,6 +166,19 @@ def _create_user_updated_config(
else:
log.debug(f"Failed to validate {path}")

def _delegate(self, controller: Optional[list[str]], config_key: str) -> None:
"""
Selectively delegate config to controller.
:param controller: Key(s) leading to block in config controlling run-time values.
:param config_key: Name of config item to delegate to controller.
"""
if controller:
val = self._config_intermediate[controller[0]]
for key in controller[1:]:
val = val[key]
self._config[config_key] = val[config_key]

# Public helper methods

@classmethod
Expand Down Expand Up @@ -241,7 +253,7 @@ def __init__(
dry_run: bool = False,
key_path: Optional[list[str]] = None,
schema_file: Optional[Path] = None,
controller: Optional[str] = None,
controller: Optional[list[str]] = None,
):
super().__init__(
cycle=cycle,
Expand Down Expand Up @@ -274,7 +286,7 @@ def __init__(
dry_run: bool = False,
key_path: Optional[list[str]] = None,
schema_file: Optional[Path] = None,
controller: Optional[str] = None,
controller: Optional[list[str]] = None,
):
super().__init__(
cycle=cycle,
Expand Down Expand Up @@ -314,7 +326,7 @@ def __init__(
dry_run: bool = False,
key_path: Optional[list[str]] = None,
schema_file: Optional[Path] = None,
controller: Optional[str] = None,
controller: Optional[list[str]] = None,
):
super().__init__(
config=config,
Expand All @@ -339,7 +351,7 @@ def __init__(
key_path: Optional[list[str]] = None,
batch: bool = False,
schema_file: Optional[Path] = None,
controller: Optional[str] = None,
controller: Optional[list[str]] = None,
):
super().__init__(
cycle=cycle,
Expand All @@ -351,8 +363,7 @@ def __init__(
controller=controller,
)
self._batch = batch
if controller:
self._config[STR.execution] = self.config_full[controller][STR.execution]
self._delegate(controller, STR.execution)

# Workflow tasks

Expand Down Expand Up @@ -541,7 +552,7 @@ def __init__(
key_path: Optional[list[str]] = None,
batch: bool = False,
schema_file: Optional[Path] = None,
controller: Optional[str] = None,
controller: Optional[list[str]] = None,
):
super().__init__(
cycle=cycle,
Expand Down Expand Up @@ -576,7 +587,7 @@ def __init__(
key_path: Optional[list[str]] = None,
batch: bool = False,
schema_file: Optional[Path] = None,
controller: Optional[str] = None,
controller: Optional[list[str]] = None,
):
super().__init__(
cycle=cycle,
Expand Down Expand Up @@ -618,7 +629,7 @@ def __init__(
key_path: Optional[list[str]] = None,
batch: bool = False,
schema_file: Optional[Path] = None,
controller: Optional[str] = None,
controller: Optional[list[str]] = None,
):
super().__init__(
config=config,
Expand Down Expand Up @@ -650,7 +661,7 @@ def _add_docstring(class_: type, omit: Optional[list[str]] = None) -> None:
:param key_path: Keys leading through the config to the driver's configuration block.
:param batch: Run component via the batch system?
:param schema_file: Path to schema file to use to validate an external driver.
:param controller: Name of block in config controlling run-time values.
:param controller: Key(s) leading to block in config controlling run-time values.
"""
setattr(
class_,
Expand Down
11 changes: 9 additions & 2 deletions src/uwtools/tests/drivers/test_driver.py
Original file line number Diff line number Diff line change
Expand Up @@ -195,7 +195,7 @@ def test_Assets_controller(config, controller_schema):
with raises(UWConfigError):
ConcreteAssetsTimeInvariant(config=config, schema_file=controller_schema)
assert ConcreteAssetsTimeInvariant(
config=config, schema_file=controller_schema, controller="controller"
config=config, schema_file=controller_schema, controller=["controller"]
)


Expand Down Expand Up @@ -285,6 +285,13 @@ def test_Assets__create_user_updated_config_base_file(
assert updated == expected


def test_Assets__delegate(driverobj):
assert "roses" not in driverobj.config
driverobj._config_intermediate["plants"] = {"flowers": {"roses": "red"}}
driverobj._delegate(["plants", "flowers"], "roses")
assert driverobj.config["roses"] == "red"


def test_Assets__rundir(assetsobj):
assert assetsobj.rundir == Path(assetsobj.config["rundir"])

Expand Down Expand Up @@ -342,7 +349,7 @@ def test_Driver_controller(config, controller_schema):
with raises(UWConfigError):
ConcreteDriverTimeInvariant(config=config, schema_file=controller_schema)
assert ConcreteDriverTimeInvariant(
config=config, schema_file=controller_schema, controller="controller"
config=config, schema_file=controller_schema, controller=["controller"]
)


Expand Down

0 comments on commit 4e67e51

Please sign in to comment.