refactor(harness): 拆分校验函数降低 radon 圈复杂度至 Grade B
- _validate: 拆出 _validate_mode(mode 依赖校验)+ _validate_basic(标量/枚举校验) - _validate_gate: 拆为 _validate_gate_thresholds(e 值/净胜/方向)+ _validate_gate_ladder(阶梯/块序贯) - load_config: 提取 _apply_env_overrides 函数 - radon cc -n C 无输出(全部 Grade B 或更好) - 70 个单元测试全部通过 Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
+70
-17
@@ -141,7 +141,7 @@ class RunConfig:
|
||||
def _validate(config: RunConfig) -> None:
|
||||
"""校验 RunConfig 全部字段约束。
|
||||
|
||||
四层校验链:基础字段 → 编辑预算 → mini-batch → CE-Gate。
|
||||
六层校验链:mode → 基础标量 → 编辑预算 → mini-batch → gate 阈值 → gate 阶梯。
|
||||
|
||||
参数:
|
||||
config: 待校验的配置实例。
|
||||
@@ -149,7 +149,22 @@ def _validate(config: RunConfig) -> None:
|
||||
异常:
|
||||
ValueError: 任一字段值不合法。
|
||||
"""
|
||||
# ── 基础字段校验 ──
|
||||
_validate_mode(config)
|
||||
_validate_basic(config)
|
||||
_validate_edit_budget(config)
|
||||
_validate_minibatch(config)
|
||||
_validate_gate(config)
|
||||
|
||||
|
||||
def _validate_mode(config: RunConfig) -> None:
|
||||
"""校验运行模式及其依赖字段(run_id、version)。
|
||||
|
||||
参数:
|
||||
config: 待校验的配置实例。
|
||||
|
||||
异常:
|
||||
ValueError: mode 非法或模式依赖字段缺失。
|
||||
"""
|
||||
if config.mode not in _VALID_MODES:
|
||||
raise ValueError(f"mode 必须为 {_VALID_MODES} 之一,实际: {config.mode!r}")
|
||||
if config.mode in ("diagnose", "evolve") and not config.run_id:
|
||||
@@ -158,6 +173,17 @@ def _validate(config: RunConfig) -> None:
|
||||
raise ValueError(f"mode 为 {config.mode!r} 时必须提供 --version。")
|
||||
if config.mode == "promote" and not config.run_id:
|
||||
raise ValueError("promote 必须提供 --run-id(指定 canonical eval run)。")
|
||||
|
||||
|
||||
def _validate_basic(config: RunConfig) -> None:
|
||||
"""校验基础标量字段:枚举合法性与正整数约束。
|
||||
|
||||
参数:
|
||||
config: 待校验的配置实例。
|
||||
|
||||
异常:
|
||||
ValueError: 任一基础字段值不合法。
|
||||
"""
|
||||
if config.skill_mode not in _VALID_SKILL_MODES:
|
||||
raise ValueError(
|
||||
f"skill_mode 必须为 {_VALID_SKILL_MODES} 之一,实际: {config.skill_mode!r}"
|
||||
@@ -170,10 +196,6 @@ def _validate(config: RunConfig) -> None:
|
||||
raise ValueError(f"n_samples 必须 >= 0,实际: {config.n_samples}")
|
||||
if config.epochs <= 0:
|
||||
raise ValueError(f"epochs 必须 > 0,实际: {config.epochs}")
|
||||
|
||||
# ── 编辑预算校验 ──
|
||||
_validate_edit_budget(config)
|
||||
|
||||
if config.skill_update_mode not in _VALID_SKILL_UPDATE_MODES:
|
||||
raise ValueError(
|
||||
f"skill_update_mode 必须为 {_VALID_SKILL_UPDATE_MODES} 之一,"
|
||||
@@ -185,12 +207,6 @@ def _validate(config: RunConfig) -> None:
|
||||
f"实际: {config.appendix_consolidate_threshold}"
|
||||
)
|
||||
|
||||
# ── mini-batch 校验 ──
|
||||
_validate_minibatch(config)
|
||||
|
||||
# ── CE-Gate 校验 ──
|
||||
_validate_gate(config)
|
||||
|
||||
|
||||
def _validate_edit_budget(config: RunConfig) -> None:
|
||||
"""校验编辑预算退火的前期/后期上限约束。
|
||||
@@ -253,7 +269,7 @@ def _validate_minibatch(config: RunConfig) -> None:
|
||||
|
||||
|
||||
def _validate_gate(config: RunConfig) -> None:
|
||||
"""校验 CE-Gate 判据与阶梯参数约束。
|
||||
"""校验 CE-Gate 全部参数:判据阈值 + 信息量阶梯。
|
||||
|
||||
参数:
|
||||
config: 待校验的配置实例。
|
||||
@@ -261,6 +277,19 @@ def _validate_gate(config: RunConfig) -> None:
|
||||
异常:
|
||||
ValueError: 任一 gate 参数不合法。
|
||||
"""
|
||||
_validate_gate_thresholds(config)
|
||||
_validate_gate_ladder(config)
|
||||
|
||||
|
||||
def _validate_gate_thresholds(config: RunConfig) -> None:
|
||||
"""校验 CE-Gate 判据阈值参数(e 值、净胜数、效应量、方向拒绝)。
|
||||
|
||||
参数:
|
||||
config: 待校验的配置实例。
|
||||
|
||||
异常:
|
||||
ValueError: 任一阈值参数不合法。
|
||||
"""
|
||||
if config.gate_e_confirm <= 1:
|
||||
raise ValueError(f"gate_e_confirm 必须 > 1,实际: {config.gate_e_confirm}")
|
||||
if not (1 < config.gate_e_provisional <= config.gate_e_confirm):
|
||||
@@ -271,8 +300,21 @@ def _validate_gate(config: RunConfig) -> None:
|
||||
raise ValueError(f"gate_e_rollback 必须 > 1,实际: {config.gate_e_rollback}")
|
||||
if config.gate_w_net_min < 1:
|
||||
raise ValueError(f"gate_w_net_min 必须 >= 1,实际: {config.gate_w_net_min}")
|
||||
if config.gate_delta_min < 0:
|
||||
raise ValueError(f"gate_delta_min 必须 >= 0,实际: {config.gate_delta_min}")
|
||||
if config.gate_lambda_dir >= 0:
|
||||
raise ValueError(f"gate_lambda_dir 必须 < 0,实际: {config.gate_lambda_dir}")
|
||||
|
||||
|
||||
def _validate_gate_ladder(config: RunConfig) -> None:
|
||||
"""校验 CE-Gate 信息量阶梯与块序贯参数。
|
||||
|
||||
参数:
|
||||
config: 待校验的配置实例。
|
||||
|
||||
异常:
|
||||
ValueError: 任一阶梯参数不合法。
|
||||
"""
|
||||
if config.gate_block <= 0 or config.gate_n_max < config.gate_block:
|
||||
raise ValueError(
|
||||
f"需 0 < gate_block <= gate_n_max,"
|
||||
@@ -293,6 +335,20 @@ def _validate_gate(config: RunConfig) -> None:
|
||||
raise ValueError(f"gate_guard_err 须在 (0,1),实际: {config.gate_guard_err}")
|
||||
|
||||
|
||||
def _apply_env_overrides(data: dict) -> None:
|
||||
"""将 .env 工程配置环境变量覆盖到配置字典中(原地修改)。
|
||||
|
||||
仅覆盖 _ENV_FIELD_MAP 中声明的工程配置字段(workspace_dir、store_dir)。
|
||||
|
||||
参数:
|
||||
data: 待覆盖的配置字典。
|
||||
"""
|
||||
for env_key, field_name in _ENV_FIELD_MAP.items():
|
||||
env_val = os.environ.get(env_key)
|
||||
if env_val is not None:
|
||||
data[field_name] = env_val
|
||||
|
||||
|
||||
def load_config(
|
||||
yaml_path: Path,
|
||||
cli_overrides: dict[str, object] | None = None,
|
||||
@@ -320,10 +376,7 @@ def load_config(
|
||||
yaml_data: dict = raw.get("harness", raw)
|
||||
|
||||
# Phase 2: .env 覆盖层(仅工程配置字段)
|
||||
for env_key, field_name in _ENV_FIELD_MAP.items():
|
||||
env_val = os.environ.get(env_key)
|
||||
if env_val is not None:
|
||||
yaml_data[field_name] = env_val
|
||||
_apply_env_overrides(yaml_data)
|
||||
|
||||
# Phase 3: CLI 覆盖层(最高优先级)
|
||||
valid_fields = {f.name for f in dataclasses.fields(RunConfig)}
|
||||
|
||||
Reference in New Issue
Block a user