diff --git a/docs/build_docs.py b/docs/build_docs.py index 444d9bff7b..fe838172b3 100755 --- a/docs/build_docs.py +++ b/docs/build_docs.py @@ -31,7 +31,7 @@ def run_command(command, dir_to_run=None): log_text = f"Running {command}" if dir_to_run: log_text += f" under {dir_to_run}" - + print(log_text) command_out = subprocess.run(shlex.split(command), cwd=dir_to_run) if command_out.returncode != 0: @@ -103,8 +103,7 @@ def main(): 'run') # run make to generate the documentation files - run_command(f"make clean html", - docs_dir) + run_command("make clean html", docs_dir) if not skip_doxygen: # build the doxygen documentation @@ -157,14 +156,14 @@ def main(): warning_file = os.path.join(docs_dir, '_build', 'warnings.log') - if os.stat(warning_file).st_size == 0: - print(f"No warnings found, removing {warning_file}") - os.remove(warning_file) - else: + if os.stat(warning_file).st_size != 0: print('ERROR: Doc build contains warnings or errors. ' f'Please review {warning_file}') sys.exit(1) + print(f"No warnings found, removing {warning_file}") + os.remove(warning_file) + print("Documentation build completed") if __name__ == "__main__": diff --git a/internal/scripts/dev_tools/compile_official_release_notes.py b/internal/scripts/dev_tools/compile_official_release_notes.py index 1b797c3f7f..c66e548ff3 100644 --- a/internal/scripts/dev_tools/compile_official_release_notes.py +++ b/internal/scripts/dev_tools/compile_official_release_notes.py @@ -19,7 +19,7 @@ items = {} # gather issues and organize them by category for line in content: - if match := re.match(r' .. dropdown:: (.*)', line): + if match := re.match(r' {2}.. dropdown:: (.*)', line): category = match.group(1) if not items.get(category): items[category] = [] @@ -43,7 +43,7 @@ if not issues.get(cat): issues[cat] = {} for issue in item_list: - match = re.match(r'.*\#(\d+).*', issue.replace('\n', '')) + match = re.match(r'.*#(\d+).*', issue.replace('\n', '')) if match: issues[cat][match.group(1)] = issue diff --git a/internal/scripts/docker/Dockerfile b/internal/scripts/docker/Dockerfile index 2df83a89c5..48931be5a3 100644 --- a/internal/scripts/docker/Dockerfile +++ b/internal/scripts/docker/Dockerfile @@ -18,7 +18,7 @@ ARG MET_DOCKER_REPO=met ARG MET_TAG=develop # if OBTAIN_SOURCE_CODE=copy, copy files from build context into image -FROM dtcenter/${MET_DOCKER_REPO}:${MET_TAG} as build_copy +FROM dtcenter/${MET_DOCKER_REPO}:${MET_TAG} AS build_copy ONBUILD WORKDIR /metplus ONBUILD RUN mkdir -p METplus ONBUILD COPY . METplus @@ -28,7 +28,7 @@ ONBUILD RUN if [ ! -e "METplus/ush/run_metplus.py" ]; then \ fi # if OBTAIN_SOURCE_CODE=clone, clone repository -FROM dtcenter/${MET_DOCKER_REPO}:${MET_TAG} as build_clone +FROM dtcenter/${MET_DOCKER_REPO}:${MET_TAG} AS build_clone ONBUILD WORKDIR /metplus ONBUILD ARG SOURCE_VERSION ONBUILD RUN echo "Cloning METplus repository"; \ @@ -40,7 +40,7 @@ ONBUILD RUN echo "Cloning METplus repository"; \ fi # if OBTAIN_SOURCE_CODE=none, do not retrieve files -FROM dtcenter/${MET_DOCKER_REPO}:${MET_TAG} as build_none +FROM dtcenter/${MET_DOCKER_REPO}:${MET_TAG} AS build_none ONBUILD WORKDIR /metplus # use build alias based on OBTAIN_SOURCE_CODE value diff --git a/internal/tests/pytests/conftest.py b/internal/tests/pytests/conftest.py index 4fdd602e8a..bf6396dcc9 100644 --- a/internal/tests/pytests/conftest.py +++ b/internal/tests/pytests/conftest.py @@ -185,7 +185,7 @@ def make_nc(tmp_path, lon, lat, z, data, variable='Temp', file_name='fake.nc'): latitude = rootgrp.createVariable("Latitude", "f4", "lat") levels = rootgrp.createVariable("Levels", "i4", "z") temp = rootgrp.createVariable(variable, "f4", ("time", "lon", "lat", "z")) - time = rootgrp.createVariable("Time", "i4", "time") + rootgrp.createVariable("Time", "i4", "time") longitude[:] = lon latitude[:] = lat diff --git a/internal/tests/pytests/util/config_metplus/test_config_metplus.py b/internal/tests/pytests/util/config_metplus/test_config_metplus.py index efb33d9b22..cb61841b0c 100644 --- a/internal/tests/pytests/util/config_metplus/test_config_metplus.py +++ b/internal/tests/pytests/util/config_metplus/test_config_metplus.py @@ -10,6 +10,10 @@ from metplus.util.config_validate import validate_config_variables +var1_levels = "LEVELS11, LEVELS12" +var2_levels = "LEVELS21, LEVELS22" +var1_options = 'ens_ssvar_bin_size = 0.1; ens_phist_bin_size = 0.05;' + @pytest.mark.parametrize( 'config_overrides,expected_logfile', [ (['config.LOG_METPLUS={LOG_DIR}/metplus.log'], '/metplus.log'), @@ -267,9 +271,9 @@ def test_get_field_config_variables_synonyms(metplus_config, def test_parse_var_list_fcst_only(metplus_config, data_type, list_created): conf = metplus_config conf.set('config', 'FCST_VAR1_NAME', "NAME1") - conf.set('config', 'FCST_VAR1_LEVELS', "LEVELS11, LEVELS12") + conf.set('config', 'FCST_VAR1_LEVELS', var1_levels) conf.set('config', 'FCST_VAR2_NAME', "NAME2") - conf.set('config', 'FCST_VAR2_LEVELS', "LEVELS21, LEVELS22") + conf.set('config', 'FCST_VAR2_LEVELS', var2_levels) # this should not occur because OBS variables are missing assert not validate_config_variables(conf)[0] @@ -303,9 +307,9 @@ def test_parse_var_list_fcst_only(metplus_config, data_type, list_created): def test_parse_var_list_obs(metplus_config, data_type, list_created): conf = metplus_config conf.set('config', 'OBS_VAR1_NAME', "NAME1") - conf.set('config', 'OBS_VAR1_LEVELS', "LEVELS11, LEVELS12") + conf.set('config', 'OBS_VAR1_LEVELS', var1_levels) conf.set('config', 'OBS_VAR2_NAME', "NAME2") - conf.set('config', 'OBS_VAR2_LEVELS', "LEVELS21, LEVELS22") + conf.set('config', 'OBS_VAR2_LEVELS', var2_levels) # this should not occur because FCST variables are missing if validate_config_variables(conf)[0]: @@ -340,9 +344,9 @@ def test_parse_var_list_obs(metplus_config, data_type, list_created): def test_parse_var_list_both(metplus_config, data_type, list_created): conf = metplus_config conf.set('config', 'BOTH_VAR1_NAME', "NAME1") - conf.set('config', 'BOTH_VAR1_LEVELS', "LEVELS11, LEVELS12") + conf.set('config', 'BOTH_VAR1_LEVELS', var1_levels) conf.set('config', 'BOTH_VAR2_NAME', "NAME2") - conf.set('config', 'BOTH_VAR2_LEVELS', "LEVELS21, LEVELS22") + conf.set('config', 'BOTH_VAR2_LEVELS', var2_levels) # this should not occur because BOTH variables are used if not validate_config_variables(conf)[0]: @@ -472,7 +476,7 @@ def test_parse_var_list_fcst_and_obs_and_both(metplus_config, data_type, list_le def test_parse_var_list_fcst_only_options(metplus_config, data_type, list_len): conf = metplus_config conf.set('config', 'FCST_VAR1_NAME', "NAME1") - conf.set('config', 'FCST_VAR1_LEVELS', "LEVELS11, LEVELS12") + conf.set('config', 'FCST_VAR1_LEVELS', var1_levels) conf.set('config', 'FCST_VAR1_THRESH', ">1, >2") conf.set('config', 'OBS_VAR1_OPTIONS', "OOPTIONS11") @@ -533,13 +537,11 @@ def test_parse_var_list_ensemble(metplus_config): config.set('config', 'FCST_VAR1_NAME', 'APCP') config.set('config', 'FCST_VAR1_LEVELS', 'A24') config.set('config', 'FCST_VAR1_THRESH', '>0.01, >=10.0') - config.set('config', 'FCST_VAR1_OPTIONS', ('ens_ssvar_bin_size = 0.1; ' - 'ens_phist_bin_size = 0.05;')) + config.set('config', 'FCST_VAR1_OPTIONS', var1_options) config.set('config', 'OBS_VAR1_NAME', 'APCP') config.set('config', 'OBS_VAR1_LEVELS', 'A24') config.set('config', 'OBS_VAR1_THRESH', '>0.01, >=10.0') - config.set('config', 'OBS_VAR1_OPTIONS', ('ens_ssvar_bin_size = 0.1; ' - 'ens_phist_bin_size = 0.05;')) + config.set('config', 'OBS_VAR1_OPTIONS', var1_options) time_info = {} expected_ens_list = [{'index': 1, @@ -567,14 +569,11 @@ def test_parse_var_list_ensemble(metplus_config): 'fcst_name': 'APCP', 'fcst_level': 'A24', 'fcst_thresh': ['>0.01', '>=10.0'], - 'fcst_extra': ('ens_ssvar_bin_size = 0.1; ' - 'ens_phist_bin_size = 0.05;'), + 'fcst_extra': var1_options, 'obs_name': 'APCP', 'obs_level': 'A24', 'obs_thresh': ['>0.01', '>=10.0'], - 'obs_extra': ('ens_ssvar_bin_size = 0.1; ' - 'ens_phist_bin_size = 0.05;') - + 'obs_extra': var1_options }, ] diff --git a/internal/tests/pytests/util/config_util/test_config_util.py b/internal/tests/pytests/util/config_util/test_config_util.py index 7409f62b4e..6054a947fc 100644 --- a/internal/tests/pytests/util/config_util/test_config_util.py +++ b/internal/tests/pytests/util/config_util/test_config_util.py @@ -3,10 +3,9 @@ import pytest import pprint -import os from datetime import datetime -from metplus.util.config_util import * +from metplus.util import config_util as cu from metplus.util.config_metplus import parse_var_list from metplus.util.time_util import ti_calculate @@ -33,7 +32,7 @@ def test_get_custom_string_list(metplus_config, conf_items, met_tool, expected_r for conf_key, conf_value in conf_items.items(): config.set('config', conf_key, conf_value) - assert get_custom_string_list(config, met_tool) == expected_result + assert cu.get_custom_string_list(config, met_tool) == expected_result @pytest.mark.parametrize( @@ -72,7 +71,7 @@ def test_get_custom_string_list(metplus_config, conf_items, met_tool, expected_r def test_get_process_list(metplus_config, input_list, expected_list): conf = metplus_config conf.set('config', 'PROCESS_LIST', input_list) - process_list = get_process_list(conf) + process_list = cu.get_process_list(conf) output_list = [item[0] for item in process_list] assert output_list == expected_list @@ -106,7 +105,7 @@ def test_get_process_list(metplus_config, input_list, expected_list): def test_get_process_list_instances(metplus_config, input_list, expected_list): conf = metplus_config conf.set('config', 'PROCESS_LIST', input_list) - output_list = get_process_list(conf) + output_list = cu.get_process_list(conf) assert output_list == expected_list @@ -159,11 +158,11 @@ def test_sub_var_list(metplus_config, input_dict, expected_list): actual_temp = parse_var_list(config) pp = pprint.PrettyPrinter() - print(f'Actual var list (before sub):') + print('Actual var list (before sub):') pp.pprint(actual_temp) - actual_list = sub_var_list(actual_temp, time_info) - print(f'Actual var list (after sub):') + actual_list = cu.sub_var_list(actual_temp, time_info) + print('Actual var list (after sub):') pp.pprint(actual_list) assert len(actual_list) == len(expected_list) diff --git a/internal/tests/pytests/util/diff_util/test_diff_util.py b/internal/tests/pytests/util/diff_util/test_diff_util.py index 9222ed3388..b26dd8b6d7 100644 --- a/internal/tests/pytests/util/diff_util/test_diff_util.py +++ b/internal/tests/pytests/util/diff_util/test_diff_util.py @@ -1,8 +1,6 @@ import pytest -from netCDF4 import Dataset import os -import shutil from unittest import mock from PIL import Image import numpy as np @@ -214,7 +212,7 @@ def test_get_file_type(path, expected): @pytest.mark.util -def test_get_file_type_netCDF4(dummy_nc1): +def test_get_file_type_netcdf4(dummy_nc1): actual = du.get_file_type(dummy_nc1) assert actual == 'netcdf' @@ -488,7 +486,7 @@ def test__handle_text_files(cmp_return, comp_txt_return, expected): @pytest.mark.parametrize( - 'colour_A, colour_B, save_diff, expected, check_print', + "colour_a, colour_b, save_diff, expected, check_print", [ ( 255, @@ -515,7 +513,7 @@ def test__handle_text_files(cmp_return, comp_txt_return, expected): ) @pytest.mark.util def test_compare_image_files( - capfd, tmp_path_factory, colour_A, colour_B, save_diff, expected, check_print + capfd, tmp_path_factory, colour_a, colour_b, save_diff, expected, check_print ): image_dir = tmp_path_factory.mktemp('images') image1 = image_dir / 'img1.jpg' @@ -528,8 +526,8 @@ def _make_test_img(file_path, col): im.save(file_path) im.close() - _make_test_img(image1, colour_A) - _make_test_img(image2, colour_B) + _make_test_img(image1, colour_a) + _make_test_img(image2, colour_b) actual = du.compare_image_files(image1, image2, save_diff) diff --git a/internal/tests/pytests/util/met_config/test_met_config.py b/internal/tests/pytests/util/met_config/test_met_config.py index c42cfef14d..848fa73cef 100644 --- a/internal/tests/pytests/util/met_config/test_met_config.py +++ b/internal/tests/pytests/util/met_config/test_met_config.py @@ -2,32 +2,34 @@ import pytest -from metplus.util.met_config import * +from metplus.util import met_config as mc from metplus.util.met_config import _read_climo_file_name, _read_climo_field from metplus.util import CLIMO_TYPES +type_lower = '' +type_upper = '' @pytest.mark.parametrize( 'config_overrides, expected_value', [ # 0 no relevant config set ({}, ''), # 1 _FIELD set - ({'APP_CLIMO__FIELD': '{name="TMP"; level="(*,*)";}'}, + ({f'APP_CLIMO_{type_upper}_FIELD': '{name="TMP"; level="(*,*)";}'}, '{name="TMP"; level="(*,*)";}'), # 2 VAR1 name/level set - ({'APP_CLIMO__VAR1_NAME': 'TMP', - 'APP_CLIMO__VAR1_LEVELS': '"(*,*)"'}, + ({f'APP_CLIMO_{type_upper}_VAR1_NAME': 'TMP', + f'APP_CLIMO_{type_upper}_VAR1_LEVELS': '"(*,*)"'}, '{ name="TMP"; level="(*,*)"; }'), # 3 VAR1/2 name/level set - ({'APP_CLIMO__VAR1_NAME': 'TMP', - 'APP_CLIMO__VAR1_LEVELS': '"(*,*)"', - 'APP_CLIMO__VAR2_NAME': 'PRES', - 'APP_CLIMO__VAR2_LEVELS': '"(0,*,*)"'}, + ({f'APP_CLIMO_{type_upper}_VAR1_NAME': 'TMP', + f'APP_CLIMO_{type_upper}_VAR1_LEVELS': '"(*,*)"', + f'APP_CLIMO_{type_upper}_VAR2_NAME': 'PRES', + f'APP_CLIMO_{type_upper}_VAR2_LEVELS': '"(0,*,*)"'}, '{ name="TMP"; level="(*,*)"; },{ name="PRES"; level="(0,*,*)"; }'), # 4 VAR1 name/level and FIELD set - prefer VAR - ({'APP_CLIMO__FIELD': '{name="TEMP"; level="(0,*,*)";}', - 'APP_CLIMO__VAR1_NAME': 'TMP', - 'APP_CLIMO__VAR1_LEVELS': '"(*,*)"'}, + ({f'APP_CLIMO_{type_upper}_FIELD': '{name="TEMP"; level="(0,*,*)";}', + f'APP_CLIMO_{type_upper}_VAR1_NAME': 'TMP', + f'APP_CLIMO_{type_upper}_VAR1_LEVELS': '"(*,*)"'}, '{ name="TMP"; level="(*,*)"; }'), ] ) @@ -40,9 +42,8 @@ def test_read_climo_field(metplus_config, config_overrides, expected_value): # set config values for key, value in config_overrides.items(): - key_sub = key.replace('', climo_type) - value_sub = value.replace('', climo_type.lower()) - config.set('config', key_sub, value_sub) + key_sub = key.replace(type_upper, climo_type) + config.set('config', key_sub, value) _read_climo_field(climo_type, config, app_name) assert config.getraw('config', expected_var) == expected_value @@ -53,75 +54,75 @@ def test_read_climo_field(metplus_config, config_overrides, expected_value): # 0 no relevant config set ({}, ''), # 1 file name single - ({'APP_CLIMO__FILE_NAME': 'some/file/path'}, - 'climo_ = {file_name = ["some/file/path"];}'), + ({f'APP_CLIMO_{type_upper}_FILE_NAME': 'some/file/path'}, + f'climo_{type_lower} = ' + '{file_name = ["some/file/path"];}'), # 2 file name multiple - ({'APP_CLIMO__FILE_NAME': 'some/file/path, other/path'}, - 'climo_ = {file_name = ["some/file/path", "other/path"];}'), + ({f'APP_CLIMO_{type_upper}_FILE_NAME': 'some/file/path, other/path'}, + f'climo_{type_lower} = ' + '{file_name = ["some/file/path", "other/path"];}'), # 3 field single - ({'APP_CLIMO__FIELD': '{name="TMP"; level="(*,*)";}'}, - 'climo_ = {field = [{name="TMP"; level="(*,*)";}];}'), + ({f'APP_CLIMO_{type_upper}_FIELD': '{name="TMP"; level="(*,*)";}'}, + f'climo_{type_lower} = ' + '{field = [{name="TMP"; level="(*,*)";}];}'), # 4 field multiple - ({'APP_CLIMO__FIELD': ('{name="TMP"; level="(*,*)";},' + ({f'APP_CLIMO_{type_upper}_FIELD': ('{name="TMP"; level="(*,*)";},' '{name="TEMP"; level="P500";}')}, - ('climo_ = {field = [{name="TMP"; level="(*,*)";}, ' + (f'climo_{type_lower} = ' + '{field = [{name="TMP"; level="(*,*)";}, ' '{name="TEMP"; level="P500";}];}')), - # 5 use fcst no other climo_ - ({'APP_CLIMO__USE_FCST': 'TRUE'}, - 'climo_ = fcst;'), - # 6 use obs no other climo_ - ({'APP_CLIMO__USE_OBS': 'TRUE'}, - 'climo_ = obs;'), - # 7 use fcst with other climo_ - ({'APP_CLIMO__REGRID_METHOD': 'NEAREST', - 'APP_CLIMO__USE_FCST': 'TRUE'}, - 'climo_ = {regrid = {method = NEAREST;}}climo_ = fcst;'), - # 8 use obs with other climo_ - ({'APP_CLIMO__REGRID_METHOD': 'NEAREST', - 'APP_CLIMO__USE_OBS': 'TRUE'}, - 'climo_ = {regrid = {method = NEAREST;}}climo_ = obs;'), + # 5 use fcst no other climo_{type_lower} + ({f'APP_CLIMO_{type_upper}_USE_FCST': 'TRUE'}, + f'climo_{type_lower} = fcst;'), + # 6 use obs no other climo_{type_lower} + ({f'APP_CLIMO_{type_upper}_USE_OBS': 'TRUE'}, + f'climo_{type_lower} = obs;'), + # 7 use fcst with other climo_{type_lower} + ({f'APP_CLIMO_{type_upper}_REGRID_METHOD': 'NEAREST', + f'APP_CLIMO_{type_upper}_USE_FCST': 'TRUE'}, + f'climo_{type_lower} = ' + '{regrid = {method = NEAREST;}}' + f'climo_{type_lower} = fcst;'), + # 8 use obs with other climo_{type_lower} + ({f'APP_CLIMO_{type_upper}_REGRID_METHOD': 'NEAREST', + f'APP_CLIMO_{type_upper}_USE_OBS': 'TRUE'}, + f'climo_{type_lower} = ' + '{regrid = {method = NEAREST;}}' + f'climo_{type_lower} = obs;'), # 9 regrid method - ({'APP_CLIMO__REGRID_METHOD': 'NEAREST', }, - 'climo_ = {regrid = {method = NEAREST;}}'), + ({f'APP_CLIMO_{type_upper}_REGRID_METHOD': 'NEAREST', }, + f'climo_{type_lower} = ' + '{regrid = {method = NEAREST;}}'), # 10 regrid width - ({'APP_CLIMO__REGRID_WIDTH': '1', }, - 'climo_ = {regrid = {width = 1;}}'), + ({f'APP_CLIMO_{type_upper}_REGRID_WIDTH': '1', }, + f'climo_{type_lower} = ' + '{regrid = {width = 1;}}'), # 11 regrid vld_thresh - ({'APP_CLIMO__REGRID_VLD_THRESH': '0.5', }, - 'climo_ = {regrid = {vld_thresh = 0.5;}}'), + ({f'APP_CLIMO_{type_upper}_REGRID_VLD_THRESH': '0.5', }, + f'climo_{type_lower} = ' + '{regrid = {vld_thresh = 0.5;}}'), # 12 regrid shape - ({'APP_CLIMO__REGRID_SHAPE': 'SQUARE', }, - 'climo_ = {regrid = {shape = SQUARE;}}'), + ({f'APP_CLIMO_{type_upper}_REGRID_SHAPE': 'SQUARE', }, + f'climo_{type_lower} = ' + '{regrid = {shape = SQUARE;}}'), # 13 time_interp_method - ({'APP_CLIMO__TIME_INTERP_METHOD': 'NEAREST', }, - 'climo_ = {time_interp_method = NEAREST;}'), + ({f'APP_CLIMO_{type_upper}_TIME_INTERP_METHOD': 'NEAREST', }, + f'climo_{type_lower} = ' + '{time_interp_method = NEAREST;}'), # 14 match_month - ({'APP_CLIMO__MATCH_MONTH': 'True', }, - 'climo_ = {match_month = TRUE;}'), + ({f'APP_CLIMO_{type_upper}_MATCH_MONTH': 'True', }, + f'climo_{type_lower} = ' + '{match_month = TRUE;}'), # 15 day_interval - int - ({'APP_CLIMO__DAY_INTERVAL': '30', }, - 'climo_ = {day_interval = 30;}'), + ({f'APP_CLIMO_{type_upper}_DAY_INTERVAL': '30', }, + f'climo_{type_lower} = ' + '{day_interval = 30;}'), # 16 day_interval - NA - ({'APP_CLIMO__DAY_INTERVAL': 'NA', }, - 'climo_ = {day_interval = NA;}'), + ({f'APP_CLIMO_{type_upper}_DAY_INTERVAL': 'NA', }, + f'climo_{type_lower} = ' + '{day_interval = NA;}'), # 17 hour_interval - ({'APP_CLIMO__HOUR_INTERVAL': '12', }, - 'climo_ = {hour_interval = 12;}'), + ({f'APP_CLIMO_{type_upper}_HOUR_INTERVAL': '12', }, + f'climo_{type_lower} = ' + '{hour_interval = 12;}'), # 18 all ({ - 'APP_CLIMO__FILE_NAME': '/some/climo_/file.txt', - 'APP_CLIMO__FIELD': '{name="CLM_NAME"; level="(0,0,*,*)";}', - 'APP_CLIMO__REGRID_METHOD': 'NEAREST', - 'APP_CLIMO__REGRID_WIDTH': '1', - 'APP_CLIMO__REGRID_VLD_THRESH': '0.5', - 'APP_CLIMO__REGRID_SHAPE': 'SQUARE', - 'APP_CLIMO__TIME_INTERP_METHOD': 'NEAREST', - 'APP_CLIMO__MATCH_MONTH': 'True', - 'APP_CLIMO__DAY_INTERVAL': '30', - 'APP_CLIMO__HOUR_INTERVAL': '12', + f'APP_CLIMO_{type_upper}_FILE_NAME': f'/some/climo_{type_lower}/file.txt', + f'APP_CLIMO_{type_upper}_FIELD': '{name="CLM_NAME"; level="(0,0,*,*)";}', + f'APP_CLIMO_{type_upper}_REGRID_METHOD': 'NEAREST', + f'APP_CLIMO_{type_upper}_REGRID_WIDTH': '1', + f'APP_CLIMO_{type_upper}_REGRID_VLD_THRESH': '0.5', + f'APP_CLIMO_{type_upper}_REGRID_SHAPE': 'SQUARE', + f'APP_CLIMO_{type_upper}_TIME_INTERP_METHOD': 'NEAREST', + f'APP_CLIMO_{type_upper}_MATCH_MONTH': 'True', + f'APP_CLIMO_{type_upper}_DAY_INTERVAL': '30', + f'APP_CLIMO_{type_upper}_HOUR_INTERVAL': '12', }, - ('climo_ = {file_name = ' - '["/some/climo_/file.txt"];' + (f'climo_{type_lower} = ' + '{file_name = ' + f'["/some/climo_{type_lower}/file.txt"];' 'field = [{name="CLM_NAME"; level="(0,0,*,*)";}];' 'regrid = {method = NEAREST;width = 1;' 'vld_thresh = 0.5;shape = SQUARE;}' @@ -141,13 +142,13 @@ def test_handle_climo_dict(metplus_config, config_overrides, expected_value): # set config values for key, value in config_overrides.items(): - key_sub = key.replace('', climo_type) - value_sub = value.replace('', climo_type.lower()) + key_sub = key.replace(type_upper, climo_type) + value_sub = value.replace(type_lower, climo_type.lower()) config.set('config', key_sub, value_sub) - handle_climo_dict(config, app_name, output_dict, sub_groups=sub_groups) + mc.handle_climo_dict(config, app_name, output_dict, sub_groups=sub_groups) print(output_dict) - expected_sub = expected_value.replace('', climo_type.lower()) + expected_sub = expected_value.replace(type_lower, climo_type.lower()) assert output_dict[expected_var] == expected_sub @@ -159,7 +160,7 @@ def test_handle_climo_dict(metplus_config, config_overrides, expected_value): ) @pytest.mark.util def test_met_config_info(name, data_type, mp_configs, extra_args): - item = METConfig(name=name, data_type=data_type) + item = mc.METConfig(name=name, data_type=data_type) item.metplus_configs = mp_configs item.extra_args = extra_args @@ -189,7 +190,7 @@ def test_met_config_info(name, data_type, mp_configs, extra_args): @pytest.mark.util def test_set_met_config_function(data_type, expected_function): try: - function_found = set_met_config_function(data_type) + function_found = mc.set_met_config_function(data_type) function_name = function_found.__name__ if function_found else None assert function_name == expected_function except ValueError: @@ -207,7 +208,7 @@ def test_set_met_config_function(data_type, expected_function): ) @pytest.mark.util def test_format_regrid_to_grid(input, output): - assert format_regrid_to_grid(input) == output + assert mc.format_regrid_to_grid(input) == output @pytest.mark.parametrize(