fix(data): clean.py 轻度修复 + 摘掉 5 条已修好的 xfail
Codex 直接改的(格式 / 死代码 / 纯 bug,不动接口与语义): - winsorize(Series) 直接崩:select_dtypes 在 Series 上不存在,Series 分支提到最前并加数值 dtype 守卫 - winsorize 的分位数改为只在数值列上算,含文本列的赛题表不再崩(与已有 numeric_cols 判断对齐) - 删掉 detect_outliers 里已成空操作的 df = pd.DataFrame(data),去掉 df 别名 - clean_missing 的嵌套 if 合并(ruff SIM102),清掉 W293 行尾空白与函数内连续空行 测试: - 5 条 xfail 经 XPASS 信号确认已修好,摘掉 mark 转正式用例 (detect_outliers 4 条 + winsorize 混合类型 1 条) - 53 passed / 7 xfailed -> 58 passed / 2 xfailed - 剩 2 条 xfail 保留,且不是漏改而是设计没定: detect_outliers 遇文本列返回什么、impute_missing 的 mode 分支要不要就地改调用方的表 - ruff: 1 error -> All checks passed;pyright: 0 errors 不变 文档: - STATUS.md:L0 进度 4/12、验证结果表、下一步重写、新增决策 31 (Codex 可直接改 src 的范围:纯 bug / 格式 / 死代码;要选语义的留给用户) - CHANGELOG.md:本轮变更,并修掉 [Unreleased] 里被重复追加撑坏的一句 - docs/dev/personal-pitfalls.md:只追加第 7 条(守卫子句要排在类型分派之后)
This commit is contained in:
1 parent
c2595b6d07
commit
319b16b17c
5 files changed
+89
-66
No files matched your search
@@ -98,3 +98,19 @@
|
||||
想看全貌就偶尔跑一次 `ruff check --select ALL --preview`(只当参考,别直接开进 CI,
|
||||
会淹没在噪声里);纯格式问题交给 `ruff format`,它是 formatter,不受 `select` 影响。
|
||||
- 首次:2026-10-01|复发:0
|
||||
|
||||
### 7. 写"守卫子句"时,忘了不是所有入参都长一样
|
||||
|
||||
- 现象:`winsorize` 开头先算 `numeric_cols = data.select_dtypes(include=['number']).columns`
|
||||
挡"空数值列",但 `winsorize` 同时收 `DataFrame` 和 `Series` ——
|
||||
**`Series` 上没有 `select_dtypes`**,传 Series 直接 `AttributeError`,
|
||||
而且报错就报在守卫那一行(全函数看起来最"安全"的地方)。
|
||||
- 为什么会错:写的时候只想"要防住空数值列",顺手把守卫放在函数最上面,
|
||||
没回头确认**这个函数还收哪些类型**。守卫本身没错,错的是它的**位置**:
|
||||
它对 `DataFrame` 成立、对 `Series` 根本不合法,所以必须排在
|
||||
`isinstance(data, pd.Series)` 的类型分派**之后**。
|
||||
本质是:**先做类型分派,再写只对其中一支成立的逻辑**。
|
||||
- 以后怎么防:写"开头集中校验"之前,先把入参的**全部类型**列一遍,
|
||||
逐条问"这句话对每种类型都成立吗";不成立的往后挪,
|
||||
挪进 `if isinstance(...)` 里面,让它只有对应的那一支能走到。
|
||||
- 首次:2026-10-02|复发:0
|
||||
Reference in new issue
Block a user