[Bug] test_detect_file_encodings fails on Windows: cannot reopen an open NamedTemporaryFile

该报错通常出现在 Windows 上运行 Dify API 单元测试 test_detect_file_encodings 时:测试代码在 NamedTemporaryFile 仍打开的情况下调用 detect_file_encodings ,后者通过 charset_normalizer.from

快速结论:该报错通常出现在 Windows 上运行 Dify API 单元测试 test_detect_file_encodings 时:测试代码在 NamedTemporaryFile 仍打开的情况下调用 detect_file_encodings,后者通过 charset_normalizer.from_path 再次打开同一路径,Windows 不允许这样做,于是抛出 PermissionError。优先排查测试文件是否在检测前已关闭临时文件。

适用环境:Issue 已确认:Dify main @ b6824334cf(源码安装,API 1.16.x)、Self Hosted(Source)、Windows;Python 与依赖版本未在 Issue 中给出。Linux/macOS 下该测试通过。

最快修复方案:暂无确认的一步修复方案(Issue 中未合并修复 PR;社区回复确认了诊断并给出建议代码,属于可优先尝试的修改)。

注意事项:这是仅涉及测试的可移植性问题,生产代码 api/core/rag/extractor/helpers.py 无需改动;改为 delete=False 后必须自行清理临时文件,否则会残留 .txt 文件。

问题场景

在 Windows 上以源码方式安装并运行 Dify API 单元测试,执行 test_helpers.py 中的 TestHelpers::test_detect_file_encodings。该测试会写入一个小文本文件并检测其编码,预期在生产 helper 中重新打开该路径。Linux/macOS 上可通过,Windows 上失败。

报错原文

[Bug] test_detect_file_encodings fails on Windows: cannot reopen an open NamedTemporaryFile
PermissionError: [Errno 13] Permission denied: 'C:\\Users\\...\\Temp\\tmpxxx.txt'

原因分析

最可能原因:测试在 with tempfile.NamedTemporaryFile(mode="w+t") as temp 块内、文件仍处于打开状态时调用 detect_file_encodings(temp_path)。该 helper 内部使用 charset_normalizer.from_path() 重新打开文件,而 Windows 上同一 NamedTemporaryFile 在关闭前无法被另一个句柄重新打开(平台差异,已有文档说明),因此触发 PermissionError。这是测试代码的可移植性 bug,不是生产逻辑错误。

环境排查

  • 确认操作系统为 Windows,且测试在本地源码环境下运行。
  • 确认 Dify 代码版本接近 Issue 中提到的 main @ b6824334cf 或 API 1.16.x。
  • 确认执行的命令为 uv run --project api pytest api/tests/unit_tests/core/rag/extractor/test_helpers.py::TestHelpers::test_detect_file_encodings。
  • 对比同测试在 Linux/macOS 上的结果,用于区分平台差异。
  • Python 版本、依赖版本在本 Issue 中未明确,排查时如遇到其他报错再单独记录。

解决步骤

  1. 打开 api/tests/unit_tests/core/rag/extractor/test_helpers.py,定位 test_detect_file_encodings 中的 NamedTemporaryFile 用法。
  2. 将文件写入与编码检测拆分为两步:在 with 块内只写入内容并 flush,块退出后文件已关闭,再调用 detect_file_encodings(可优先尝试)。
  3. 创建临时文件时增加 delete=False,并在 finally 中显式 os.unlink(temp_path) 清理,避免残留文件(可优先尝试)。
  4. 保存后重新执行上述 pytest 命令验证。

验证方法

在 Windows 上重新运行 test_detect_file_encodings,不再出现 PermissionError,且断言 len(encodings) == 1、编码属于 utf_8 或 ascii 均通过;同时检查临时目录中没有遗留测试生成的 .txt 文件。

参考来源

langgenius/dify #39891

GamsGo AI

AI 工具推荐

想把多个 AI 模型放在一个入口?

GamsGo AI 集成 ChatGPT、DeepSeek、Gemini、Claude、Midjourney、Veo 等常用模型,适合写作、绘图、视频和日常 AI 工作流。

了解 GamsGo AI

推广链接:通过此链接购买,我可能获得佣金,不影响你的价格。

这个方案解决了吗?

celebrityanime
celebrityanime
文章: 33094

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注