From 3ea79b349f57f09b5744da63590af0327a9a9794 Mon Sep 17 00:00:00 2001 From: Courtney Peverley Date: Wed, 25 Sep 2024 14:04:12 -0600 Subject: [PATCH] address review comments --- cime_config/hist_config.py | 95 +++++++++++++++++++---------------- src/dynamics/utils/hycoef.F90 | 5 +- src/history/cam_hist_file.F90 | 18 +++++-- src/utils/cam_abortutils.F90 | 5 +- src/utils/cam_filenames.F90 | 13 +++++ test/run_unit_tests.sh | 2 + test/unit/test_hist_config.py | 3 +- 7 files changed, 88 insertions(+), 53 deletions(-) diff --git a/cime_config/hist_config.py b/cime_config/hist_config.py index 46c4f2af..79b7f28a 100644 --- a/cime_config/hist_config.py +++ b/cime_config/hist_config.py @@ -44,7 +44,9 @@ _OUT_PRECS = ['REAL32', 'REAL64'] _TRUE_VALUES = {"true", "t", ".true."} _FALSE_VALUES = {"false", "f", ".false."} -_NETCDF_ID_RE = re.compile(r"^[a-z]\w{0,62}$", re.IGNORECASE) +# NetCDF variable name requirements: +# https://docs.unidata.ucar.edu/netcdf-c/current/programming_notes.html#object_name +_NETCDF_ID_RE = re.compile(r"^[a-z][\w._@+]{0,256}$", re.IGNORECASE) ############################################################################## ### @@ -125,14 +127,12 @@ def _list_of_idents(entry, sep=','): (['foo', 'BA2r3'], None) >>> _list_of_idents("foo, 3bar") (None, 'Found invalid identifiers:\\n 3bar') - >>> _list_of_idents("foo.3bar") - (None, 'Found invalid identifiers:\\n foo.3bar') - >>> _list_of_idents("foo3bariendnaadfasdfbasdlkfap983rasdfvalsda938qjnasdasd98adfasxd") - (None, 'Found invalid identifiers:\\n foo3bariendnaadfasdfbasdlkfap983rasdfvalsda938qjnasdasd98adfasxd') - >>> _list_of_idents("foo.3bar, foo3bariendnaadfasdfbasdlkfap983rasdfvalsda938qjnasdasd98adfasxd") - (None, 'Found invalid identifiers:\\n foo.3bar\\n foo3bariendnaadfasdfbasdlkfap983rasdfvalsda938qjnasdasd98adfasxd') - >>> _list_of_idents("foo.3bar; foo", sep=';') - (None, 'Found invalid identifiers:\\n foo.3bar') + >>> _list_of_idents("foo,3bar", sep=';') + (None, 'Found invalid identifiers:\\n foo,3bar') + >>> _list_of_idents("foo#3bar, foo3baifijeowfjeiofjewiofjeiwofjewiofejifwjoefdfewfefdfdkjokmcdioanicdiaoilfejieojwiefjidojfioejsiofdjkljnxpoiadjfioenskcodiafkamd199fd9a0fdjkldajfdfjiodanckdalirhgieoskjcdskdfieowfidjfslk129dkjfaiocsriendnaadfasdfbasdlkfap983rasdfvalsda938qjnasdasd98adfasxd") + (None, 'Found invalid identifiers:\\n foo#3bar\\n foo3baifijeowfjeiofjewiofjeiwofjewiofejifwjoefdfewfefdfdkjokmcdioanicdiaoilfejieojwiefjidojfioejsiofdjkljnxpoiadjfioenskcodiafkamd199fd9a0fdjkldajfdfjiodanckdalirhgieoskjcdskdfieowfidjfslk129dkjfaiocsriendnaadfasdfbasdlkfap983rasdfvalsda938qjnasdasd98adfasxd') + >>> _list_of_idents("foo,3bar; foo", sep=';') + (None, 'Found invalid identifiers:\\n foo,3bar') >>> _list_of_idents(" ") (None, 'No identifiers found') """ @@ -140,7 +140,7 @@ def _list_of_idents(entry, sep=','): potential_list = [x.strip() for x in entry.split(sep)] bad_list = [sample for sample in potential_list if _NETCDF_ID_RE.match(sample) is None] if len(bad_list) > 0: - return (None, f"Found invalid identifiers:\n " + '\n '.join(bad_list)) + return (None, "Found invalid identifiers:\n " + "\n ".join(bad_list)) # end if return (potential_list, None) # end if @@ -161,52 +161,50 @@ def _is_mult_period(entry): >>> _is_mult_period("3 * nmonths") ((3, 'nmonths'), None) >>> _is_mult_period("2*fortnights") - (None, 'period must be one of nsteps, nstep, nseconds, nsecond, nminutes, nminute, nhours, nhour, ndays, nday, nmonths, nmonth, nyears, nyear, steps, seconds, minutes, hours, days, months, years') + (None, 'period ("fortnights") must be one of nsteps, nstep, nseconds, nsecond, nminutes, nminute, nhours, nhour, ndays, nday, nmonths, nmonth, nyears, nyear, steps, seconds, minutes, hours, days, months, years') >>> _is_mult_period("7*nhours of day") - (None, 'period must be one of nsteps, nstep, nseconds, nsecond, nminutes, nminute, nhours, nhour, ndays, nday, nmonths, nmonth, nyears, nyear, steps, seconds, minutes, hours, days, months, years') + (None, 'period ("nhours of day") must be one of nsteps, nstep, nseconds, nsecond, nminutes, nminute, nhours, nhour, ndays, nday, nmonths, nmonth, nyears, nyear, steps, seconds, minutes, hours, days, months, years') >>> _is_mult_period(" ") - (None, 'a frequency ([*]period) is required') + (None, 'frequency ([*]period) is required, found " "') >>> _is_mult_period("1*nyear") ((1, 'nyear'), None) >>> _is_mult_period("-6*nhours") - (None, "multiplier '-6' in '-6*nhours' must be a positive integer") + (None, 'multiplier ("-6") must be a positive integer') >>> _is_mult_period("7h*nhours") - (None, "multiplier '7h' in '7h*nhours' must be a positive integer") + (None, '"7h" in "7h*nhours" is not a valid integer') >>> _is_mult_period("5*nhours*ndays") - (None, "multiplier '5*nhours' in '5*nhours*ndays' must be a positive integer") + (None, 'frequency must be of the form ([*]period), found "5*nhours*ndays". Do you have too many multipliers or periods?') """ - if not entry.strip(): - errmsg = "a frequency ([*]period) is required" - return (None, errmsg) + if not entry or not entry.strip(): + return (None, f"frequency ([*]period) is required, found \"{entry}\"") # end if - _OPTIONAL_MULTIPLIER_TOKEN = r"((?P.*)\*)" - _REQUIRED_PERIOD_TOKEN = "(?P.*)" - _MULT_PERIOD_REGEX = f"^{_OPTIONAL_MULTIPLIER_TOKEN}?\s*{_REQUIRED_PERIOD_TOKEN}$" - match = re.match(_MULT_PERIOD_REGEX, entry.strip()) - group_dict = match.groupdict() - if len(group_dict) == 0 or 'period' not in group_dict: - errmsg = f"Bad formatting of frequency, '{entry}' must be in the form of '[*]