diff --git a/docs/sections/user_guide/yaml/components/upp.rst b/docs/sections/user_guide/yaml/components/upp.rst index 359e66498..8c6c85fe5 100644 --- a/docs/sections/user_guide/yaml/components/upp.rst +++ b/docs/sections/user_guide/yaml/components/upp.rst @@ -45,7 +45,7 @@ The following namelists and variables can be customized: * - Namelist - Variables * - ``model_inputs`` - - ``datestr``, ``filename``, ``filenameflat``, ``filenameflux``, ``grib``, ``ioform``, ``modelname`` + - ``datestr``, ``filename``, ``filenameflat``, ``filenameflux``, ``grib``, ``ioform``, ``modelname``, ``submodelname`` * - ``nampgb`` - ``aqf_on``, ``d2d_chem``, ``d3d_on``, ``filenameaer``, ``gccpp_on``, ``gocart_on``, ``gtg_on``, ``hyb_sigp``, ``kpo``, ``kpv``, ``kth``, ``method_blsn``, ``nasa_on``, ``numx``, ``po``, ``popascal``, ``pv``, ``rdaod``, ``slrutah_on``, ``th``, ``vtimeunits``, ``write_ifi_debug_files`` diff --git a/docs/shared/upp.yaml b/docs/shared/upp.yaml index 7bb92efa3..f46d0654c 100644 --- a/docs/shared/upp.yaml +++ b/docs/shared/upp.yaml @@ -27,6 +27,7 @@ upp: grib: grib2 ioform: netcdf modelname: FV3R + submodelname: RTMA nampgb: kpo: 3 numx: 1 diff --git a/recipe/meta.json b/recipe/meta.json index 5b52efd27..9a1af522d 100644 --- a/recipe/meta.json +++ b/recipe/meta.json @@ -32,5 +32,5 @@ "pyyaml =6.0.*" ] }, - "version": "2.3.3" + "version": "2.3.4" } diff --git a/src/uwtools/config/jinja2.py b/src/uwtools/config/jinja2.py index 3d6181e07..d3358626b 100644 --- a/src/uwtools/config/jinja2.py +++ b/src/uwtools/config/jinja2.py @@ -170,7 +170,7 @@ def render( :param searchpath: Paths to search for extra templates. :param values_needed: Just report variables needed to render the template? :param dry_run: Run in dry-run mode? - :return: The rendered template, or None. + :return: The unrendered template if values_needed is True, the rendered template, or None. """ _report(locals()) values = _supplement_values( @@ -180,11 +180,11 @@ def render( undeclared_variables = template.undeclared_variables # If a report of variables required to render the template was requested, make that report and - # then return. + # then return the unrendered template. if values_needed: _values_needed(undeclared_variables) - return None + return str(template) # Render the template. If there are missing values, report them and return an error to the # caller. diff --git a/src/uwtools/resources/info.json b/src/uwtools/resources/info.json index 456c6a2e9..cb46b1472 100644 --- a/src/uwtools/resources/info.json +++ b/src/uwtools/resources/info.json @@ -1,4 +1,4 @@ { - "version": "2.3.3", + "version": "2.3.4", "buildnum": "0" } diff --git a/src/uwtools/resources/jsonschema/upp.jsonschema b/src/uwtools/resources/jsonschema/upp.jsonschema index 1acda1641..b0878652e 100644 --- a/src/uwtools/resources/jsonschema/upp.jsonschema +++ b/src/uwtools/resources/jsonschema/upp.jsonschema @@ -74,6 +74,13 @@ "NMM" ], "type": "string" + }, + "submodelname": { + "enum": [ + "MPAS", + "RTMA" + ], + "type": "string" } }, "type": "object" diff --git a/src/uwtools/tests/api/test_template.py b/src/uwtools/tests/api/test_template.py index a46e4cc97..337a67b0f 100644 --- a/src/uwtools/tests/api/test_template.py +++ b/src/uwtools/tests/api/test_template.py @@ -1,5 +1,6 @@ # pylint: disable=missing-function-docstring,redefined-outer-name +import logging import os from pathlib import Path from unittest.mock import patch @@ -8,6 +9,8 @@ from uwtools.api import template from uwtools.exceptions import UWTemplateRenderError +from uwtools.logging import log +from uwtools.tests.support import logged @fixture @@ -25,6 +28,14 @@ def kwargs(): } +@fixture +def template_file(tmp_path): + path = tmp_path / "template.jinja2" + with open(path, "w", encoding="utf-8") as f: + f.write("roses are {{roses_color}}, violets are {{violets_color}}") + return path + + def test_render(kwargs): with patch.object(template, "_render") as _render: template.render(**kwargs) @@ -51,6 +62,13 @@ def test_render_to_str(kwargs): render.assert_called_once_with(**{**kwargs, "output_file": Path(os.devnull)}) +def test_render_values_needed(caplog, template_file): + log.setLevel(logging.INFO) + template.render(input_file=template_file, values_needed=True) + for var in ("roses_color", "violets_color"): + assert logged(caplog, f" {var}") + + def test_translate(): kwargs: dict = { "input_file": "path1", diff --git a/src/uwtools/tests/test_schemas.py b/src/uwtools/tests/test_schemas.py index 2e425dab8..4f3882ba1 100644 --- a/src/uwtools/tests/test_schemas.py +++ b/src/uwtools/tests/test_schemas.py @@ -1248,6 +1248,10 @@ def test_schema_upp_namelist(upp_prop): assert "not one of ['FV3R', '3DRTMA', 'GFS', 'RAPR', 'NMM']" in errors( {"update_values": {"model_inputs": {"modelname": "foo"}}} ) + # model_inputs: Only certain submodelname values are supported: + assert "not one of ['MPAS', 'RTMA']" in errors( + {"update_values": {"model_inputs": {"submodelname": "foo"}}} + ) # model_inputs: No other keys are supported: assert "Additional properties are not allowed" in errors( {"update_values": {"model_inputs": {"something": "else"}}}