diff --git a/scripts/lib/CIME/XML/entry_id.py b/scripts/lib/CIME/XML/entry_id.py
index d02e88680bb..2e16e339f38 100644
--- a/scripts/lib/CIME/XML/entry_id.py
+++ b/scripts/lib/CIME/XML/entry_id.py
@@ -43,29 +43,45 @@ def set_default_value(self, vid, val):
return val
- def get_value_match(self, vid, attributes=None, exact_match=False, entry_node=None):
- # Handle this case:
- #
- #
- # X
- # Y
- # Z
- #
- #
+ def get_value_match(self, vid, attributes=None, exact_match=False, entry_node=None,
+ replacement_for_none=None):
+ """Handle this case:
+
+
+ X
+ Y
+ Z
+
+
+
+ If replacement_for_none is provided, then: if the found text value would give a
+ None value, instead replace it with the value given by the replacement_for_none
+ argument. (However, still return None if no match is found.) This may or may not
+ be needed, but is in place to maintain some old logic.
+
+ """
if entry_node is not None:
- value = self._get_value_match(entry_node, attributes, exact_match)
+ value = self._get_value_match(entry_node, attributes, exact_match,
+ replacement_for_none=replacement_for_none)
else:
node = self.get_optional_child("entry", {"id":vid})
value = None
if node is not None:
- value = self._get_value_match(node, attributes, exact_match)
+ value = self._get_value_match(node, attributes, exact_match,
+ replacement_for_none=replacement_for_none)
logger.debug("(get_value_match) vid {} value {}".format(vid, value))
return value
- def _get_value_match(self, node, attributes=None, exact_match=False):
+ def _get_value_match(self, node, attributes=None, exact_match=False,
+ replacement_for_none=None):
'''
Note that the component class has a specific version of this function
+
+ If replacement_for_none is provided, then: if the found text value would give a
+ None value, instead replace it with the value given by the replacement_for_none
+ argument. (However, still return None if no match is found.) This may or may not
+ be needed, but is in place to maintain some old logic.
'''
# if there is a element - check to see if there is a match attribute
# if there is NOT a match attribute, then set the default to "first"
@@ -125,7 +141,12 @@ def _get_value_match(self, node, attributes=None, exact_match=False):
expect(False,
"match attribute can only have a value of 'last' or 'first', value is %s" %match_type)
- return self.text(mnode)
+ text = self.text(mnode)
+ if text is None:
+ # NOTE(wjs, 2021-06-03) I'm not sure when (if ever) this can happen, but I'm
+ # putting this logic here to maintain some old logic, to be safe.
+ text = replacement_for_none
+ return text
def get_node_element_info(self, vid, element_name):
node = self.get_optional_child("entry", {"id":vid})
diff --git a/scripts/lib/CIME/XML/namelist_definition.py b/scripts/lib/CIME/XML/namelist_definition.py
index 3a50d35dc25..39c2427eb7e 100644
--- a/scripts/lib/CIME/XML/namelist_definition.py
+++ b/scripts/lib/CIME/XML/namelist_definition.py
@@ -156,6 +156,10 @@ def get_group(self, name):
def add_attributes(self, attributes):
self._attributes = attributes
+ def get_attributes(self):
+ """Return this object's attributes dictionary"""
+ return self._attributes
+
def get_entry_nodes(self):
return self._entry_nodes
@@ -174,6 +178,9 @@ def set_value(self, vid, value, subgroup=None, ignore_type=True):
"""This function is not implemented."""
raise TypeError("NamelistDefinition does not support `set_value`.")
+ # In contrast to the entry_id version of this method, this version doesn't support the
+ # replacement_for_none argument, because it is hard-coded to ''.
+ # pylint: disable=arguments-differ
def get_value_match(self, vid, attributes=None, exact_match=True, entry_node=None):
"""Return the default value for the variable named `vid`.
@@ -190,11 +197,12 @@ def get_value_match(self, vid, attributes=None, exact_match=True, entry_node=Non
if entry_node is None:
entry_node = self._nodes[vid]
+ # NOTE(wjs, 2021-06-04) In the following call, replacement_for_none='' may not
+ # actually be needed, but I'm setting it to maintain some old logic, to be safe.
value = super(NamelistDefinition, self).get_value_match(vid.lower(),attributes=all_attributes, exact_match=exact_match,
- entry_node=entry_node)
- if value is None:
- value = ''
- else:
+ entry_node=entry_node,
+ replacement_for_none='')
+ if value is not None:
value = self._split_defaults_text(value)
return value
@@ -445,4 +453,4 @@ def get_default_value(self, item, attribute=None):
all_attributes.update(attribute)
value = self.get_value_match(item.lower(), all_attributes, True)
- return self._split_defaults_text(value)
+ return value
diff --git a/scripts/lib/CIME/namelist.py b/scripts/lib/CIME/namelist.py
index cc76117da85..d6c7647ed66 100644
--- a/scripts/lib/CIME/namelist.py
+++ b/scripts/lib/CIME/namelist.py
@@ -953,7 +953,9 @@ def get_variable_value(self, group_name, variable_name):
if gn:
vn = string_in_list(variable_name,self._groups[gn])
if vn:
- return self._groups[gn][vn]
+ # Make a copy of the list so that any modifications done by the caller
+ # don't modify the internal values.
+ return self._groups[gn][vn][:]
return ['']
def get_value(self, variable_name):
diff --git a/scripts/lib/CIME/nmlgen.py b/scripts/lib/CIME/nmlgen.py
index 153a58c260c..c823f92ff57 100644
--- a/scripts/lib/CIME/nmlgen.py
+++ b/scripts/lib/CIME/nmlgen.py
@@ -629,6 +629,8 @@ def add_default(self, name, value=None, ignore_abs_path=None):
have_value = False
# Check for existing value.
current_literals = self._namelist.get_variable_value(group, name)
+ if current_literals != [""]:
+ have_value = True
# Check for input argument.
if value is not None:
@@ -643,7 +645,8 @@ def add_default(self, name, value=None, ignore_abs_path=None):
have_value = True
default_literals = self._to_namelist_literals(name, default)
current_literals = merge_literal_lists(default_literals, current_literals)
- expect(have_value, "No default value found for {}.".format(name))
+ expect(have_value, "No default value found for {} with attributes {}.".format(
+ name, self._definition.get_attributes()))
# Go through file names and prepend input data root directory for
# absolute pathnames.
diff --git a/src/drivers/mct/cime_config/namelist_definition_modelio.xml b/src/drivers/mct/cime_config/namelist_definition_modelio.xml
index 660bc93dee3..ce0275e59bf 100644
--- a/src/drivers/mct/cime_config/namelist_definition_modelio.xml
+++ b/src/drivers/mct/cime_config/namelist_definition_modelio.xml
@@ -172,6 +172,7 @@
$GLC_PIO_NETCDF_FORMAT
$WAV_PIO_NETCDF_FORMAT
$IAC_PIO_NETCDF_FORMAT
+ $ESP_PIO_NETCDF_FORMAT