Skip to content

Refactor core foundation (exceptions and bootstrap)#4982

Merged
jasonb5 merged 11 commits into
masterfrom
feat/refactor-core-foundation
Jul 8, 2026
Merged

Refactor core foundation (exceptions and bootstrap)#4982
jasonb5 merged 11 commits into
masterfrom
feat/refactor-core-foundation

Conversation

@jasonb5

@jasonb5 jasonb5 commented May 27, 2026

Copy link
Copy Markdown
Collaborator

Description

  • Adds CIME/core/exceptions.py with typed exception hierarchy extending CIMEError
  • Adds CIME/core/config/bootstrap.py for centralized sys.path management
  • Migrates internal CIMEError imports to use new location
  • Adds 26 unit tests for exception hierarchy

Motivation

CIME's foundation has accumulated two recurring pain points that this PR addresses as the first slice of a broader CIME/core/ refactor:

Typed exceptions. Today there is a single CIMEError in CIME/utils.py, so callers can't distinguish a configuration problem from a build failure from a transient subprocess error without string-matching on messages. The new hierarchy (ConfigurationError, BuildError, SubmitError, SystemTestError, LockingError, ExternalCommandError, RetryableExternalCommandError, InputError) enables:

  • Granular except clauses in callers (e.g. retry only transient subprocess errors)
  • Clearer log and traceback context
  • ExternalCommandError modeled on subprocess.CalledProcessError, carrying returncode, cmd, output, and stderr so run_cmd failures preserve diagnostic context

CIME.utils.CIMEError is re-exported from the new location so existing imports (internal or downstream) continue to work.

Centralized sys.path bootstrap. CIME is not pip-installed; every entry script (xmlchange, case.setup, create_newcase, etc.) does its own sys.path.insert to make import CIME... work. This duplicated logic has drifted in subtle ways. bootstrap_cime() provides:

  • A single source of truth for path setup
  • Three-way CIMEROOT resolution (explicit arg, env var, walk-up from __file__)
  • Idempotent insertion (no duplicates, deterministic ordering)
  • The Python version check previously in standard_script_setup.py

Existing call sites are intentionally unchanged in this PR — the module is standalone so subsequent slices can adopt it incrementally.

Why these two pieces first. They are dependency-free building blocks that the planned CIME/core/ DI-based abstractions (filesystem, process, env, clock) will rely on, so they need to land before the higher-level work.

Related

Checklist

  • My code follows the style guidelines of this project (black formatting)
  • I have performed a self-review of my own code
  • My changes generate no new warnings
  • I have added tests that exercise 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

jasonb5 added 5 commits May 1, 2026 12:48
…ails

Rewrite plan.md, implementation.md, and README.md to reflect the
reorganize-don't-rewrite philosophy, utils.py distribution strategy,
cross-cutting issues inventory, and Case two-phase refactoring approach.
…trap module

Add CIME.core.exceptions with CIMEError and typed subclasses
(ConfigurationError, BuildError, SubmitError, etc.). CIMEError preserves
dual SystemExit+Exception inheritance for traceback suppression.

Add CIME.core.config.bootstrap with centralized sys.path management
(bootstrap_cime, find_cimeroot, check_minimum_python_version).

Include 40 unit tests with 98% coverage.
Replace the CIMEError class definition in utils.py with a re-export from
CIME.core.exceptions for backward compatibility. Update 19 internal
callers to import CIMEError directly from CIME.core.exceptions.

External consumers using 'from CIME.utils import CIMEError' or
'utils.CIMEError' continue to work unchanged via the re-export.
@github-actions

Copy link
Copy Markdown
Contributor

jasonb5 added 2 commits June 17, 2026 08:29
Refactor planning and slice breakdowns previously kept in
doc/dev/refactor/ are now tracked in GitHub issues to keep
discussion, status, and cross-linking in one place.

Master tracker: #4950
Slices:
  - #4996 Slice 1: Core foundation
  - #4997 Slice 2: Batch system extraction
  - #4998 Slice 3A: SRCROOT feature
  - #4999 Slice 3B: Build system extraction
  - #5000 Slice 4: Case decomposition

Closes the now-superseded planning issue #4528.
@jasonb5 jasonb5 marked this pull request as ready for review June 18, 2026 20:39
@jasonb5 jasonb5 requested review from billsacks and jgfouca June 24, 2026 16:53

@jgfouca jgfouca left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Looks good to me. Can you add motivation for this change in the description?

@billsacks billsacks left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

I like the direction you're taking things here - thank you for this work! I have reviewed the production code and did a cursory look at the unit tests. I have a few comments. I appreciate the added testing here.

Comment thread CIME/core/config/bootstrap.py Outdated
Comment thread CIME/core/config/bootstrap.py
Comment thread CIME/core/__init__.py Outdated
Comment thread CIME/tests/test_unit_core_bootstrap.py

@billsacks billsacks left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Thank you for the fixes! See the comment I made about the algorithm for inserting paths, but as I note there, I'm fine with either approach. So I'm approving here and will let you decide which way to go.

@jasonb5

jasonb5 commented Jul 8, 2026

Copy link
Copy Markdown
Collaborator Author

Test failures are unrelated.

@jasonb5 jasonb5 merged commit 8d9e27d into master Jul 8, 2026
16 of 18 checks passed
@jasonb5 jasonb5 deleted the feat/refactor-core-foundation branch July 8, 2026 17:38
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.

3 participants