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

49 lines
3.0 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 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 时不会伪造虚拟环境变量。