我读开源项目的 bug 修复时,会把想不通的地方写下来,攒成了这里的笔记。这些补丁大多很短:一个 +1、删掉的五行、一层 try/finally。可要讲清它为什么非这样改不可,往往得绕一大圈,翻论文、写复现、找反例。我也写错过,错了就在原文后面补上更正。
|
从 2000 年 1 月 1 日取第 366 天,dateutil 返回的还是 12 月 30 日,和第 365 天同一个日期。 2026-11-03 · English |
|
|
把 PDF 末尾的 2026-11-01 · English |
|
|
2026-11-01 · English |
|
|
2026-11-01 · English |
|
|
2026-10-31 · English |
|
|
2026-10-31 · English |
|
|
锁文件里的名字还是 2026-10-31 · English |
|
|
前面多放一些注释,pypdf 连后面的 42 都读不到。我的初稿用循环修好了递归,按 review 抽出公共工具后,却碰到了另一份优化留下的调用预算。我把三版放在一起,追到函数入口和流指针,看两份改动怎样把各自的理由都留在代码里。 2026-10-31 · English |
|
|
同一条忽略大小写的正则,装上原生加速库后,匹配反而从 True 变成 False。我的初稿靠退回 Python 修好了答案,维护者却要求让能表达的参数继续走原生后端;改版期间,另一份补丁又先合入了重叠的加固。我把三版放在一起,不只看答案,也看它究竟选了哪个引擎。 2026-10-31 · English |
|
|
1 月 31 日到 3 月 1 日,Nushell 算出「1 个月 −2 天」。我的初稿消掉了负号,review 却发现它把原来正确的「28 天」换成了「1 个月」。我把修复前、送审版和最终版一起留下,看一个补丁如何既修正错误,又不改掉原来的约定。 2026-10-30 · English |
|
|
tomlkit 为保真给每个字符串存两份:逻辑值和源文本。给值追加一个引号,值是对的,序列化出来却成了它自己的解析器都读不回的 TOML。2022 年那行拼接保住了左半边,右半边这一洞开了四年,直到 #612 把普通文本也领过转义那道刷子。 2026-10-29 · English |
|
|
一行挂着 2026-10-29 · English |
|
|
2026-10-29 · English |
|
|
给 2026-10-28 · English |
|
|
quinn 遇到持久拥塞时,把已经乘过 0.7 的窗口又乘了一遍, 2026-10-27 · English |
|
|
2026-10-23 · English |
|
|
PostgreSQL 代理 pgdog 连续跑了 12 天以后,定时任务全都不再触发了,既不报错,也不 panic。问题出在 tokio-util 的时间轮里,修复只是把扫描起点往后挪了一格。为了弄懂这一格,我回头读了 1987 年那篇时间轮论文。 2026-09-29 · English |
|
|
上一篇写完后,review 里又冒出两组反例: 2026-10-24 · English |
能跑的小工程放在各自的专题文件夹里,怎么跑写在它们的 README 里。
| 工程 | 跑出来的是什么 |
|---|---|
| yearday_demo | 两份固定源码快照对照 yearday=366 的返回日期与 relativedelta 字段,并逐日枚举 2000–2399 的 146,097 个日期 |
| negative_startxref_demo | 两份完整 pypdf 源码读同一份把 startxref 改成负数的 PDF,看修前在哪一处 seek 抛 ValueError、合并版如何归一化后重建 xref |
| rotate_demo | 两版 pottery 在 fakeredis 上跑 369 组旋转,对照最终列表和实际发出的 LPUSH/RPUSH/LTRIM 参数 |
| local_time_demo | 两版 tomlkit 序列化同一个带时区的 time,看写出的文本、自己的解析器能否读回,以及不带时区时是否逐字节不变 |
| math_log_demo | 从三个固定提交里提取 math log 的底数检查与输入判断,看 1、NaN 与 ∞ 各在哪一版被拦下,域内算术是否逐位不变 |
| bytes_demo | 从五个固定提交里提取 remove_impl,看未命中时丢了哪几个字节、panic 在哪一版消失,以及首稿与最终版在 882 组输入上是否逐字相同 |
| subdirectory_demo | 同一份含三个项目的 ZIP 交给两版 PDM 走完导入、导出、重新读入,看子目录在哪一版没写进 archive 表,新 candidate 的元数据来自哪个目录 |
| comments_demo | 真实三版 pypdf 解析同一组对象字节,对照连续注释边界、流位置和无注释数组的函数调用预算 |
| flags_demo | 三份固定源码交给真实 RE2 / Hyperscan,对照编译参数丢失、初稿回退和最终映射,同时检查匹配结果与实际后端 |
| datetime_demo | 三份固定源码交给同一个真实 Nu 执行,对照负天数、初稿的语义变化与最终兼容拆分,并独立检查闰日输入解析 |
| hash_demo | 同一份归档哈希经过两版 PDM 读入函数,再导出 requirements / pylock,看它在哪一步丢失或保留 |
| backpressure_demo | 修复前后两版 AnyIO 各连一条真实的 TCP,看取消之后数据有没有继续堆进队列,连接还能不能接着用 |
| cubic_demo | 同一次持久拥塞,修复前后的 ssthresh,以及之后每个 RTT 的窗口变化 |
| variance_demo | 六种方差算法在同一批输入上的误差,包括反例和数量级扫描 |
| wheel_demo | 原实现、首篇引用的初稿、最终修复,三版放在一起跑,也包括那两组级联反例 |
| isort_demo | 同一份带 noqa 的导入交给修复前后两版 isort 快照,看注释在哪一版丢失、flake8 如何当场翻脸,折行与无注释场景两版逐字一致 |
| tomlkit_demo | 同一组追加操作喂给修复前后两版 tomlkit 快照,看引号与反斜杠在哪一版把源文本拼坏、文档级往返哪一版当场翻车,String 拼 String 与追加普通文本两版逐字一致 |