From 7fd2f698a8cbbaa815ab9d06a17aae63a2d9ce49 Mon Sep 17 00:00:00 2001 From: George McCabe <23407799+georgemccabe@users.noreply.github.com> Date: Wed, 23 Mar 2022 12:06:19 -0600 Subject: [PATCH 1/7] per #1534, add unit test for properly adding a trailing semi-colon for extra field options if not found (currently fails) --- .../command_builder/test_command_builder.py | 24 +++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/internal_tests/pytests/command_builder/test_command_builder.py b/internal_tests/pytests/command_builder/test_command_builder.py index 98aed81ff..27c45cedb 100644 --- a/internal_tests/pytests/command_builder/test_command_builder.py +++ b/internal_tests/pytests/command_builder/test_command_builder.py @@ -833,3 +833,27 @@ def test_add_met_config_dict_nested(metplus_config): cbw.add_met_config_dict(dict_name, items) print(f"env_var_dict: {cbw.env_var_dict}") assert cbw.env_var_dict.get('METPLUS_OUTER_DICT') == expected_value + +@pytest.mark.parametrize( + 'extra, expected_value', [ + # trailing semi-colon should be added at end automatically + ('file_type = NETCDF_NCCF', + "'name=\"name\"; level=\"(*,*)\"; file_type = NETCDF_NCCF;'"), + ('file_type = NETCDF_NCCF;', + "'name=\"name\"; level=\"(*,*)\"; file_type = NETCDF_NCCF;'"), + ] +) +def test_get_field_info_extra(metplus_config, extra, expected_value): + d_type = 'FCST' + name = 'name' + level = '"(*,*)"' + config = metplus_config() + wrapper = CommandBuilder(config) + actual_value = wrapper.get_field_info( + d_type=d_type, + v_name=name, + v_level=level, + v_extra=extra, + add_curly_braces=False + )[0] + assert actual_value == expected_value From 2e0331d4f213a1442f5f8dc3f458a4707dcd8542 Mon Sep 17 00:00:00 2001 From: George McCabe <23407799+georgemccabe@users.noreply.github.com> Date: Wed, 23 Mar 2022 12:07:21 -0600 Subject: [PATCH 2/7] per #1534, add unit test for properly preserving trailing semi-colon from list if it is not following square brackets []s (currently fails) --- .../pytests/util/string_manip/test_util_string_manip.py | 3 +++ 1 file changed, 3 insertions(+) diff --git a/internal_tests/pytests/util/string_manip/test_util_string_manip.py b/internal_tests/pytests/util/string_manip/test_util_string_manip.py index 8678831f3..e0c5527b8 100644 --- a/internal_tests/pytests/util/string_manip/test_util_string_manip.py +++ b/internal_tests/pytests/util/string_manip/test_util_string_manip.py @@ -61,6 +61,9 @@ def test_remove_quotes(before, after): # 12: list with square braces and ending semi-colon (MET format) no quotes ('[MET_BASE/poly/LMV.poly];', ["MET_BASE/poly/LMV.poly"]), + # 13: single item ending with semi-colon should keep semi-colon + ('file_type = NETCDF_NCCF;', + ["file_type = NETCDF_NCCF;"]), ] ) def test_getlist(string_list, output_list): From fd0341825437d2ab67f3831cb4fb3c5f4367b4e3 Mon Sep 17 00:00:00 2001 From: George McCabe <23407799+georgemccabe@users.noreply.github.com> Date: Wed, 23 Mar 2022 12:21:05 -0600 Subject: [PATCH 3/7] added test for specifying multiple extra field options, ci-run-all-diff --- internal_tests/pytests/command_builder/test_command_builder.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/internal_tests/pytests/command_builder/test_command_builder.py b/internal_tests/pytests/command_builder/test_command_builder.py index 27c45cedb..e0a79733a 100644 --- a/internal_tests/pytests/command_builder/test_command_builder.py +++ b/internal_tests/pytests/command_builder/test_command_builder.py @@ -841,6 +841,8 @@ def test_add_met_config_dict_nested(metplus_config): "'name=\"name\"; level=\"(*,*)\"; file_type = NETCDF_NCCF;'"), ('file_type = NETCDF_NCCF;', "'name=\"name\"; level=\"(*,*)\"; file_type = NETCDF_NCCF;'"), + ('file_type = NETCDF_NCCF; other_opt = "opt"', + "'name=\"name\"; level=\"(*,*)\"; file_type = NETCDF_NCCF; other_opt = \"opt\";'"), ] ) def test_get_field_info_extra(metplus_config, extra, expected_value): From c46767e8db4665d6de785d80347dec4dc9c8c58b Mon Sep 17 00:00:00 2001 From: George McCabe <23407799+georgemccabe@users.noreply.github.com> Date: Wed, 23 Mar 2022 12:47:15 -0600 Subject: [PATCH 4/7] per #1534, added a test to ensure lists with line breaks (especially at the beginning of the input string) are handled properly --- .../pytests/util/string_manip/test_util_string_manip.py | 3 +++ 1 file changed, 3 insertions(+) diff --git a/internal_tests/pytests/util/string_manip/test_util_string_manip.py b/internal_tests/pytests/util/string_manip/test_util_string_manip.py index e0c5527b8..0442ecc72 100644 --- a/internal_tests/pytests/util/string_manip/test_util_string_manip.py +++ b/internal_tests/pytests/util/string_manip/test_util_string_manip.py @@ -64,6 +64,9 @@ def test_remove_quotes(before, after): # 13: single item ending with semi-colon should keep semi-colon ('file_type = NETCDF_NCCF;', ["file_type = NETCDF_NCCF;"]), + # 14: list with line break at beginning + ('\nsome_value,\n some_other_value', + ["some_value", "some_other_value"]), ] ) def test_getlist(string_list, output_list): From e2798a44c435f28e633cbe03aef8d506c174d3fd Mon Sep 17 00:00:00 2001 From: George McCabe <23407799+georgemccabe@users.noreply.github.com> Date: Wed, 23 Mar 2022 12:08:15 -0600 Subject: [PATCH 5/7] per #1534, fix logic to properly preserving trailing semi-colon from list if it is not following square brackets []s --- metplus/util/string_manip.py | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/metplus/util/string_manip.py b/metplus/util/string_manip.py index af1d71901..7e6fc581c 100644 --- a/metplus/util/string_manip.py +++ b/metplus/util/string_manip.py @@ -33,8 +33,15 @@ def getlist(list_str, expand_begin_end_incr=True): if not list_str: return [] - # FIRST remove surrounding comma, and spaces, form the string. - list_str = list_str.strip(';[] ').strip().strip(',').strip() + # remove surrounding comma and spaces from the string + list_str = list_str.strip(', ') + + # remove trailing semi-colon IF found after []s + if list_str.endswith('];'): + list_str = list_str.strip('; ') + + # remove [ from start (left) and ] from end (right) + list_str = list_str.lstrip('[ ').rstrip('] ') # remove space around commas list_str = re.sub(r'\s*,\s*', ',', list_str) From 2a42d30f01fbc02c75a1434e78193e9ca39cde4f Mon Sep 17 00:00:00 2001 From: George McCabe <23407799+georgemccabe@users.noreply.github.com> Date: Wed, 23 Mar 2022 12:48:21 -0600 Subject: [PATCH 6/7] per #1534, add additional strip commands to ensure that all whitespace is removed properly, ci-run-all-diff --- metplus/util/string_manip.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/metplus/util/string_manip.py b/metplus/util/string_manip.py index 7e6fc581c..c0d1042f7 100644 --- a/metplus/util/string_manip.py +++ b/metplus/util/string_manip.py @@ -34,14 +34,14 @@ def getlist(list_str, expand_begin_end_incr=True): return [] # remove surrounding comma and spaces from the string - list_str = list_str.strip(', ') + list_str = list_str.strip(', ').strip() # remove trailing semi-colon IF found after []s if list_str.endswith('];'): - list_str = list_str.strip('; ') + list_str = list_str.strip('; ').strip() # remove [ from start (left) and ] from end (right) - list_str = list_str.lstrip('[ ').rstrip('] ') + list_str = list_str.lstrip('[ ').rstrip('] ').strip() # remove space around commas list_str = re.sub(r'\s*,\s*', ',', list_str) From 6e956152b98f9098f94914833c98af05686f70b5 Mon Sep 17 00:00:00 2001 From: George McCabe <23407799+georgemccabe@users.noreply.github.com> Date: Wed, 23 Mar 2022 12:08:37 -0600 Subject: [PATCH 7/7] per #1534, fix logic to properly adding a trailing semi-colon for extra field options if not found --- metplus/wrappers/command_builder.py | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/metplus/wrappers/command_builder.py b/metplus/wrappers/command_builder.py index bec31ba31..05b66f89b 100755 --- a/metplus/wrappers/command_builder.py +++ b/metplus/wrappers/command_builder.py @@ -1234,7 +1234,11 @@ def get_field_info(self, d_type='', v_name='', v_level='', v_thresh=None, # handle extra options if set if v_extra: - field += f' {v_extra}' + extra = v_extra.strip() + # if trailing semi-colon is not found, add it + if not extra.endswith(';'): + extra = f"{extra};" + field += f' {extra}' # add curly braces around field info if add_curly_braces: