Files
task_pilot/docs/decisions/0003-python-environment.md
CNWei dd7612bc74 feat: 编辑器实时探测并显示已关联虚拟环境
fix: 按系统 ANSI 代码页解码子进程输出,修复中文日志乱码
2026-10-24 22:30:10 +08:00

3.0 KiB
Raw Permalink Blame History

ADR-0003:Python 虚拟环境启动环境

  • 状态:已接受
  • 日期:2026-10-19

背景

直接执行虚拟环境中的 python.exe 只解决了当前进程使用哪个解释器,并不会自动完成命令行激活脚本所做的环境准备。脚本派生的子进程可能因此找不到虚拟环境内的工具,或受到宿主机全局 Python 环境变量污染。

决策

所有脚本任务在启动前统一经过后端 python_env 模块:

  1. 只有解释器确认为 Python 时才应用 Python 专属环境。
  2. 支持显式配置虚拟环境目录;未配置时从工作目录向上搜索 .venv、venv、env。
  3. 虚拟环境必须同时存在 pyvenv.cfg 和 Scripts/python.exe,否则显式配置在任务保存时直接拒绝,自动探测则跳过无效目录。
  4. 优先使用虚拟环境自己的 Scripts/python.exe。
  5. 将 Scripts 目录置于 PATH 最前方,同时保留用户提供的 PATH 或宿主机 PATH,并按 Windows 大小写不敏感规则去重。
  6. 注入 VIRTUAL_ENV 和 VIRTUAL_ENV_PROMPT。
  7. 清理继承的 PYTHONHOME、PYTHONPATH 和旧的 VIRTUAL_ENV 标记。
  8. 虚拟环境模式禁止用户环境重新注入 PYTHONHOME;显式配置的 PYTHONPATH 仍可在清理继承污染后重新加入。
  9. 强制设置 PYTHONUNBUFFERED=1。
  10. 未能检测到虚拟环境时,平滑回退到配置的 Python 解释器。

原因

  • PATH 是隔离子进程工具解析的关键,不只是当前 Python 解释器路径。
  • VIRTUAL_ENV 是第三方框架判断隔离环境的重要标识。
  • 继承的 Python 全局变量可能破坏 venv 的标准库解析。
  • 实时日志依赖 Python 标准流不被块缓冲。
  • 仅按目录名判断不可靠,必须验证 venv 结构。
  • Windows 环境变量大小写不敏感,必须主动处理 PATH/Path 重复。

编辑器内的环境探测

任务编辑器需要在用户填写工作目录时就显示"会关联到哪个虚拟环境",否则用户只能靠事后查看日志猜测实际使用的解释器。

  1. 新增 POST /api/v1/python/venv 探测接口,请求只包含 working_dir、interpreter 和可选的 venv。
  2. 探测与执行共用同一个 resolve_venv,解析顺序完全一致:显式配置 → 解释器路径推断 → 从工作目录向上搜索。
  3. 响应区分 linked、missing、invalid、not_applicable、incomplete 五种状态,并携带相对工作目录的展示路径,例如 .venv\Scripts\python.exe。
  4. 探测是只读的文件系统检查,属于写操作语义,因此同样要求管理令牌;工作目录不存在或非 Python 解释器时不会误报为"已关联"。

边界

  • Conda 环境不会被识别为标准 venv;当前可通过显式解释器路径运行,但不会自动设置 CONDA_PREFIX。
  • PYTHONUNBUFFERED 只影响 Python 标准流。第三方日志 Handler 或非 Python 子进程仍可能自行缓冲。
  • 虚拟环境路径必须是后端运行时可以访问的有效 Windows 目录。
  • 使用系统 Python 时不会伪造虚拟环境变量。