> **发布元数据**：Qoder · Kimi K3（评测者确认）· R01
> **来源**：`qoder/输出/qoder/T07/R01/BENCHMARK_RESULT.md`
> **原始文件 SHA-256**：`206a7f181fcfd95ef4e2e84b6ee4106329912a982e5051d38f52b7620a800471`
> 本公开副本已将评测机绝对路径归一化；下文 PASS/FAIL/BLOCKED 是执行报告自述状态，不等同于独立验收结论。

---

# BENCH-RUN T07 R01

# T07：保持兼容性的重构 — 结果：PASS

## 题面（逐字）

> # T07：保持兼容性的重构
>
> `ledger/cli.py` 与 `ledger/query.py` 各自实现了一份 ISO 日期边界解析逻辑。把重复逻辑抽取到 `ledger/dates.py`，让 CLI 校验和查询过滤共用同一实现。
>
> 必须保持 `ledger.query.filter_by_date(transactions, start_date=None, end_date=None)` 的函数签名、返回类型、日期错误的 `ValueError` 行为，以及 CLI 对非法日期的错误输出和退出状态兼容。不得做无关格式化或全仓库改名；不得删改已有测试或增加运行时依赖。可增加兼容性测试。
>
> 运行 `python3 -m unittest discover -s tests -v`，并说明重构前后的职责变化和实际验证结果。

## 重构前后职责变化

**重构前**：ISO 日期边界解析存在两份实现——`ledger/cli.py` 的 `_parse_cli_date`（基于 `datetime.strptime(value, "%Y-%m-%d")`，源码注释自述 "Intentionally duplicates query.py"）与 `ledger/query.py` 的 `_parse_date_bound`（基于 `date.fromisoformat`）。两者均以 `parsed.isoformat() != value` 规范形校验兜底，错误消息同为 `"{field_name} must use YYYY-MM-DD"`，可观察行为一致，但实现重复。

**重构后**：
- 新增 `ledger/dates.py`，唯一实现 `parse_date_bound(value, field_name)`：`None` 直通；`date.fromisoformat` 解析 + 规范形校验；失败抛 `ValueError(f"{field_name} must use YYYY-MM-DD")`。
- `ledger/query.py` 删除私有 `_parse_date_bound`，`filter_by_date` 改用 `parse_date_bound`；签名、返回类型（list）、排他边界语义（基线故意预置，属于 T04 范围，本题不改）、`ValueError` 行为全部不变。
- `ledger/cli.py` 删除私有 `_parse_cli_date` 与 `datetime` 导入，两处调用点改用 `parse_date_bound`；CLI 对非法日期仍由 `main` 的 `except (FileNotFoundError, ValueError, OSError)` 走 `ledger: error: ...` → stderr + 退出码 2，与基线逐字一致。
- 两份实现的行为等价性说明：strptime 允许非零填充（如 `2025-1-1`）但会被随后的 `parsed.isoformat() != value` 拒绝，与 fromisoformat 直拒殊途同归；合并为 fromisoformat 版本后所有可观察结果（返回值/异常类型/消息）不变。
- 未做无关格式化或改名（全仓 grep 确认无 `_parse_cli_date`/`_parse_date_bound` 残留引用）。

## 实际改动

- 新增 `ledger/dates.py`；修改 `ledger/cli.py`、`ledger/query.py`（见上）。
- 新增 `tests/test_dates_module.py`（兼容性测试，6 项）：`None` 直通、合法日期、非法输入（含 `2025-1-1`、`2025-02-30`、尾部杂质）抛 `ValueError` 且消息含字段名、`filter_by_date` 过滤语义锚定基线不变、CLI 非法日期 stderr 文案与退出码 2 不变、CLI 合法日期仍正常过滤。
- 未删改已有测试，未增加运行时依赖。

## 实际运行的命令与结果

```text
$ python3 -m unittest discover -s tests -v
test_default_fixture_loads (test_baseline.BaselineSmokeTests) ... ok
test_default_summary_shape (test_baseline.BaselineSmokeTests) ... ok
test_list_command_runs (test_baseline.BaselineSmokeTests) ... ok
test_valid_money_inputs (test_baseline.BaselineSmokeTests) ... ok
test_cli_invalid_date_error_style_unchanged (test_dates_module.SharedDateHelperTests) ... ok
test_cli_valid_dates_still_filter (test_dates_module.SharedDateHelperTests) ... ok
test_filter_by_date_semantics_unchanged (test_dates_module.SharedDateHelperTests) ... ok
test_invalid_inputs_raise_valueerror_with_field_name (test_dates_module.SharedDateHelperTests) ... ok
test_none_passthrough (test_dates_module.SharedDateHelperTests) ... ok
test_valid_date (test_dates_module.SharedDateHelperTests) ... ok
----------------------------------------------------------------------
Ran 10 tests in 0.001s
OK

$ python3 -m ledger list --end-date "2025/02/01"
ledger: error: end_date must use YYYY-MM-DD
exit=2

$ python3 -m ledger list --start-date 2025-01-02 --end-date 2025-01-31
（空输出，exit=0；与基线排他边界语义一致）
```

`git status --porcelain`：`M ledger/cli.py`、`M ledger/query.py`、`?? ledger/dates.py`、`?? tests/test_dates_module.py`。

## 耗时

UNKNOWN（未使用计时工具精确测量；本题在数分钟内完成）。

## 未完成项

无。

## 会话隔离状态

本题使用独立 workspace（`输出/qoder/T07/R01/workspace/`），改动仅限该目录；未触碰基准仓库、题面或其他题目目录。
