Skip to content

Conversation

@billsacks
Copy link
Member

Description

Prior to this PR, variables with uppercase characters in the namelist definition file could not be modified via user_nl files (regardless of whether the entry in the user_nl file matched the correct case or was all lowercase).

This PR fixes this behavior so that entries in the user_nl file are case-insensitive, while preserving the case as defined in the namelist definition file in the final output. (Note that the case of variable names in any explicit add_default calls will still need to match the case of the variable in the namelist definition file.)

Checklist

  • My code follows the style guidlines of this proejct (black formatting)
  • I have performed a self-review of my own code
  • My changes generate no new warnings
  • I have added tests that excerise my feature/fix and existing tests continue to pass
  • I have commented my code, particularly in hard-to-understand areas
  • I have made corresponding additions and changes to the documentation

Testing performed

(1) scripts_regression_tests on my Mac

Failures were the same as on main

(2) create_test with baseline comparisons, namelist generation/comparison only (-n flag) for these tests in a CESM context:

SMS.ne30_g17.A.green_gnu
SMS.ne30pg3_t232.B1850C_LTso.green_gnu
SMS.ne30pg3_t232.B1850C_LTso.green_gnu.allactive-defaultio--drv-asyncio1node

(3) Manual testing of setting a mixed-case variable in the user_nl file: set logFilePostFix in user_nl_cpl.

Set this as logFilePostFix, logfilepostfix and logfilepostFIX. Confirmed that all worked, and all led to the final output in nuopc.runconfig matching the case in the namelist definition file (i.e., logFilePostFix).

Prior to this commit, variables with uppercase characters in the
namelist definition file could not be modified via user_nl files
(regardless of whether the entry in the user_nl file matched the correct
case or was all lowercase).

This commit fixes this behavior so that entries in the user_nl file are
case-insensitive, while preserving the case as defined in the namelist
definition file in the final output.
Extract a function that will be helpful for other unit tests
I realized that there were two problems with my recent implementation of
case insensitivity in dict_to_namelist:
- If a variable didn't exist in the namelist definition, a cryptic error
  would be generated from the attempt to set `variable_actual_case =
  self._entry_ids_lower_to_actual[variable_name.lower()]` before getting
  a chance to generate the more user-friendly error message via
  `_expect_variable_in_definition`.
- If a variable had an array slice (e.g., `foo(3) = 4`), the earlier
  code wouldn't work right, because this full variable name with the
  slice wouldn't exist in `_entry_ids_lower_to_actual`.

This commit solves both of those problems by determining the qualified
varname before indexing into `_entry_ids_lower_to_actual`. This requires
a bit of extra complexity to then form a version of the original
variable name (with any array slice included) in the appropriate case;
this is done via a string `replace` call.
Add unit tests covering various scenarios of having mixed-case variables
in the namelist definition (which was fixed in recent commits).
@billsacks billsacks requested a review from jedwards4b October 18, 2025 14:22
@codecov
Copy link

codecov bot commented Oct 18, 2025

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 31.02%. Comparing base (d856a52) to head (4b26a74).
⚠️ Report is 23 commits behind head on master.

Additional details and impacted files
@@            Coverage Diff             @@
##           master    #4881      +/-   ##
==========================================
+ Coverage   30.98%   31.02%   +0.03%     
==========================================
  Files         264      264              
  Lines       38663    38677      +14     
  Branches     8384     8384              
==========================================
+ Hits        11979    11998      +19     
+ Misses      25459    25455       -4     
+ Partials     1225     1224       -1     

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

# 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(),
vid,
Copy link
Member Author

Choose a reason for hiding this comment

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

The removal of .lower() here and in the call from get_default_value aren't needed to get things to work, but I think could be needed in principle in the future: I think these weren't needed because (1) get_default_value doesn't seem to ever be called, and (2) it happens that the vid here is irrelevant because we always pass an entry_node into this call.

I tested removing the setting of entry_node a couple of lines above. In this case, I got an error in get_value_match unless I removed the lower here, when working with mixed-case variable names.

Copy link
Contributor

@jedwards4b jedwards4b left a comment

Choose a reason for hiding this comment

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

Thanks

@billsacks billsacks merged commit aadcea4 into ESMCI:master Nov 4, 2025
20 of 23 checks passed
@billsacks billsacks deleted the allow_usernl_for_vars_with_upcase branch November 4, 2025 22:36
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Cannot set variables containing uppercase letters in user_nl files

2 participants