You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Part of #4950. Slice 4 of 5. Estimated 6 weeks. Depends on Slices 1–3B.
Goal
Decompose the Case class (case.py, 2600 lines, 63 methods) into focused
subsystems while consolidating the scattered Case-related free functions in utils.py, build.py, status.py, locked_files.py, and case_run.py.
End state: a smaller Case with clear delegation to independently testable
subsystems.
Why Case needs refactoring
Case is a god object that directly handles XML get/set across env files,
status tracking (CaseStatus), lock management (LockedFiles), build
orchestration, job submission, namelist generation, and clone/setup/test
workflows.
On top of that, many Case operations live outside the class as free
functions reaching into private attributes like case._gitinterface. Case
responsibility is smeared across ~10 files.
Two-phase approach
Phase 1 — Consolidate into Case
Bring scattered free functions back into Case (or into subsystem classes Case
will own). This temporarily makes Case bigger but gathers responsibility
in one place so the seams are visible.
Status (from status.py): append_case_status(), run_and_log_case_status(). Every caller currently extracts caseroot
and case._gitinterface.
Part of #4950. Slice 4 of 5. Estimated 6 weeks. Depends on Slices 1–3B.
Goal
Decompose the
Caseclass (case.py, 2600 lines, 63 methods) into focusedsubsystems while consolidating the scattered Case-related free functions in
utils.py,build.py,status.py,locked_files.py, andcase_run.py.End state: a smaller
Casewith clear delegation to independently testablesubsystems.
Why Case needs refactoring
Caseis a god object that directly handles XML get/set across env files,status tracking (CaseStatus), lock management (LockedFiles), build
orchestration, job submission, namelist generation, and clone/setup/test
workflows.
On top of that, many Case operations live outside the class as free
functions reaching into private attributes like
case._gitinterface. Caseresponsibility is smeared across ~10 files.
Two-phase approach
Phase 1 — Consolidate into Case
Bring scattered free functions back into Case (or into subsystem classes Case
will own). This temporarily makes Case bigger but gathers responsibility
in one place so the seams are visible.
status.py):append_case_status(),run_and_log_case_status(). Every caller currently extractscaserootand
case._gitinterface.locked_files.py):check_lockedfiles(),check_lockedfile(),diff_lockedfile(),check_diff().utils.py):is_comp_standalone(),find_system_test(),get_lids(),new_lid().case/case_run.py):_pre_run_check(),_run_model_impl(),_post_run_check(),_resubmit_check().test_scheduler.py):_get_time_est(),_order_tests_by_runtime(),_translate_test_names_for_new_pecount().Module-level
_TIME_CACHEshould be instance state.Phase 2 — Extract subsystems
Decompose Case into focused modules it delegates to:
CIME/core/status/— status tracking (CaseStatus file,append_status,run_and_log_status).CIME/core/locking/— lock management (LockedFiles,check_locked,diff_locked).CIME/core/xml/— XML value storage (env get/set/flush, the_env_entryid_filesand_env_generic_filesarrays).Case keeps its public API but each method delegates:
Other procedural modules to decompose
case/case_st_archive.py(1395 lines, ~20 free functions takingcase)→ consolidate as Case methods or extract into
CIME/core/archive/.Resolves Refactor config_archive.xml/case_st_archive.py #4792.
case/check_input_data.py(693 lines, ~12 free functions takingcase)→ consolidate.
baselines/performance.py(612 lines, ~12 free functions takingcase)→ baseline comparison subsystem.
hist_utils.py(836 lines, ~7 free functions takingcase)→ history file handling subsystem.
TestScheduler(test_scheduler.py, 1340 lines, 28 methods)→ decompose into test creation / phase mgmt / submission / results.
Move remaining
utils.pyfunctionswait_for_unlocked,normalize_case_id,parse_test_name,get_full_test_name,compute_total_time→core/.convert_to_seconds,convert_to_babylonian_time,get_time_in_seconds,format_time→CIME/core/time.py.convert_to_type,convert_to_unknown_type,convert_to_string,stringify_bool→CIME/core/convert.py.By end of this slice,
utils.pyis a thin re-export file with noimplementation code.
Definition of done
case._gitinterfaceor other privateCase state.
core/status/,core/locking/,core/xml/independently testable.utils.pyis thin re-exports only (was 2700 lines).Related
CIME/core/batch/#4997, Refactor Slice 3A: SRCROOT standardization (removeconfig_files.xml) #4998, Refactor Slice 3B: Move build logic intoCIME/core/build/#4999