fileutils.rotate_file(keep=1) 删除刚刚旋转的文件; keep=N 保留 N-1 代
作者: ArtJack创建于 2026年9月7日更新于 2026年9月7日
复现 (在 967864f、Python 3.13 和 3.14 中,所有内容都在一个临时目录中):
import os, tempfile
from boltons.fileutils import rotate_file
with tempfile.TemporaryDirectory() as d:
p = os.path.join(d, "f.txt")
open(p, "w").write("CRITICAL DATA")
rotate_file(p, keep=1)
print(sorted(os.listdir(d))) # [] — 文件已删除,没有保留任何内容
with tempfile.TemporaryDirectory() as d:
p = os.path.join(d, "f.txt")
for i in range(1, 6):
open(os.path.join(d, f"f.{i}.txt"), "w").write(f"gen {i}")
open(p, "w").write("current")
rotate_file(p, keep=5)
print(sorted(os.listdir(d))) # ['f.1.txt', 'f.2.txt', 'f.3.txt', 'f.4.txt'] — 要求 5 个文件,保留了 4 个机制 — boltons/fileutils.py、rotate_file:
fns = [filename] + kept_names
for orig_name, kept_name in reversed(list(zip(fns, fns[1:]))): # 行 720-723: f.4 → f.5, …, f → f.1
if not os.path.exists(orig_name):
continue
os.rename(orig_name, kept_name)
if os.path.exists(kept_names[-1]): # 行 725-726: 然后 f.5 — 刚写入 — 将被删除
os.remove(kept_names[-1])文档说明 "删除超过 keep 的任何文件";代码删除文件在 keep 处。删除操作应在梯子之前进行(删除当前的 ".keep" 以便梯子有空间),或者梯子应停止在 keep-1 处。
注意,tests/test_fileutils.py::test_rotate_file_full_rotation(以及其 _no_ext 双胞胎)目前会断言 not (tmp_path / 'test_file.5.txt').exists() 在 keep=5 时,即它们固定了偏移量,因此在更新这两个测试之前可以修复。该行为自 3bfcfdd(2024-11-28)引入该函数以来一直如此;在 HEAD 的 git describe 是 26.1.0-24-g…,因此仍然可以在 26.1.1 之前修复。
通过对仓库的自动 QA 测试发现了此问题(Verdict);在提交之前,通过手动重新运行上述复现来验证了结果。
内容来源: mahmoud/boltons