Skip to content
Open
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
41 changes: 41 additions & 0 deletions CIME/XML/env_run.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
"""
Interface to the env_run.xml file. This class inherits from EnvBase
"""
from itertools import zip_longest
from CIME.XML.standard_module_setup import *

from CIME.XML.env_base import EnvBase
Expand Down Expand Up @@ -66,5 +67,45 @@ def set_value(self, vid, value, subgroup=None, ignore_type=False):
self._pio_async_interface[comp] = convert_to_type(
value, "logical", vid
)
# PIO_NETCDF_FORMAT=64bit_data is not compatible with PIO_TYPENAME=netcdf4p
# make sure that this combination of options is not set
if "PIO_TYPENAME" in vid or "PIO_NETCDF_FORMAT" in vid:
nvid, comp, iscompvar = self.check_if_comp_var(vid, None)
pio_netcdf_formats = []
pio_typenames = []

if nvid == "PIO_TYPENAME":
if comp:
pio_netcdf_formats = [
self.get_value("PIO_NETCDF_FORMAT_{}".format(comp.upper()))
]
else:
pio_netcdf_formats = self.get_values("PIO_NETCDF_FORMAT")
pio_typenames = [value]
elif nvid == "PIO_NETCDF_FORMAT":
if comp:
pio_typenames = [
self.get_value("PIO_TYPENAME_{}".format(comp.upper()))
]
Copy link

Copilot AI Jan 30, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If get_value() returns None (which can happen if the entry is not found), this will create a list containing None [None]. Later when the validation tries to check "64bit_data" in pio_netcdf_format (line 105), it will raise a TypeError because the in operator cannot be used with None. Consider adding a check to handle the case where get_value returns None, or provide a default value.

Copilot uses AI. Check for mistakes.
else:
pio_typenames = self.get_values("PIO_TYPENAME")
pio_netcdf_formats = [value]

Copy link

Copilot AI Jan 30, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This code will raise an IndexError if either pio_netcdf_formats or pio_typenames is an empty list, since it tries to access [-1] index. This could happen if get_values() returns an empty list when the variable is not found or has no values. Consider adding a check to ensure the lists are not empty before accessing the last element, or handle the case where no values are found.

Suggested change
# If either list is empty, we cannot perform a meaningful compatibility
# check. In that case, skip the check and proceed with setting the value.
if not pio_netcdf_formats or not pio_typenames:
return EnvBase.set_value(self, vid, value, subgroup, ignore_type)

Copilot uses AI. Check for mistakes.
last_format = pio_netcdf_formats[-1]
last_typename = pio_typenames[-1]
for pio_typename, pio_netcdf_format in zip_longest(
pio_typenames, pio_netcdf_formats
):
if pio_typename is None:
pio_typename = last_typename
if pio_netcdf_format is None:
pio_netcdf_format = last_format

expect(
not ("4" in pio_typename and "64bit_data" in pio_netcdf_format),
"pio_typename {} is not compatible with pio_netcdf_format {}".format(
pio_typename, pio_netcdf_format
),
)
Comment on lines +72 to +119
Copy link

Copilot AI Jan 30, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The new validation logic for incompatible PIO_TYPENAME and PIO_NETCDF_FORMAT combinations lacks test coverage. Given that this repo has comprehensive automated testing (as seen in the CIME/tests directory), consider adding unit tests to verify that:

  1. The validation correctly prevents setting netcdf4p/netcdf4c with 64bit_data format
  2. The validation works for both component-specific and general PIO settings
  3. Edge cases like None values or empty lists are handled properly
  4. The validation allows valid combinations to pass through

Copilot uses AI. Check for mistakes.

return EnvBase.set_value(self, vid, value, subgroup, ignore_type)
6 changes: 4 additions & 2 deletions CIME/build_scripts/buildlib.pio
Original file line number Diff line number Diff line change
Expand Up @@ -191,9 +191,9 @@ def buildlib(bldroot, installpath, case):
installed_file_time = os.path.getmtime(installed_file)
if item_time > installed_file_time:
safe_copy(item, installed_file)
expect_string = "NetCDF_C_LIBRARY-ADVANCED"
expect_string = "NetCDF_C_FOUND:BOOL=TRUE"
pnetcdf_string = "WITH_PNETCDF:BOOL=ON"
netcdf4_string = "NetCDF_C_HAS_PARALLEL:BOOL=TRUE"
netcdf4_string = "HAVE_NETCDF_PAR:INTERNAL=1"

# make sure case pio_typename valid_values is set correctly
expect_string_found = False
Expand All @@ -204,6 +204,8 @@ def buildlib(bldroot, installpath, case):
for line in cache_file:
if re.search(expect_string, line):
expect_string_found = True
elif re.search("NetCDF_C_LIBRARY-ADVANCED", line):
expect_string_found = True
if re.search(pnetcdf_string, line):
pnetcdf_found = True
if re.search(netcdf4_string, line):
Expand Down
11 changes: 10 additions & 1 deletion CIME/case/preview_namelists.py
Original file line number Diff line number Diff line change
Expand Up @@ -103,7 +103,16 @@ def create_namelists(self, component=None):
compname,
case=self,
)

pio_typename = self.get_value("PIO_TYPENAME_{}".format(model_str.upper()))
pio_netcdf_format = self.get_value(
"PIO_NETCDF_FORMAT_{}".format(model_str.upper())
)
expect(
not ("4" in pio_typename and pio_netcdf_format == "64bit_data"),
"Cannot use pio_netcdf_format {} with pio_typename {}".format(
pio_netcdf_format, pio_typename
),
)
logger.debug(
"Finished creating component namelists, component {} models = {}".format(
component, models
Expand Down
Loading