Back to Blog

为 pip 贡献:修复 zsh 自动补全 compdef not found (PR #13805)

Open Source
pip
Python
zsh
CLI
Autocomplete

让 pip 的 zsh completion 输出在 compdef 不可用时按需初始化 compinit,并更新文档推荐写入 ~/.zshrc,避免启动时报错。

Published on 2/13/2026

这单来自一个很典型的 macOS + zsh 场景:用户按 pip 文档把 pip completion --zsh 追加进 ~/.zprofile 后,开启新 shell 会直接报错 command not found: compdef,自动补全也无法使用。

🔍 分析 (Analyze)

compdef 由 zsh 的 completion system(compinit)提供;而 ~/.zprofile 会在 login shell 启动时先于 ~/.zshrc 执行。很多用户是在 ~/.zshrc 里初始化 compinit,因此把 pip 的 completion 脚本放进 ~/.zprofile 时,就会在 compinit 尚未运行的阶段触发 compdef,导致启动报错。

这个问题的本质不是 pip completion 逻辑本身,而是“脚本运行时机”和“依赖的 zsh completion 基础设施”之间没有对齐。

📍 定位 (Locate)

  • completion 输出:src/pip/_internal/commands/completion.py
  • 文档指引:docs/html/user_guide.rst(Command Completion 章节)
  • 回归测试:tests/functional/test_completion.py

🛠️ 执行 (Execute)

  • 在 zsh completion 输出里增加保护逻辑:当交互式 shell 下 compdef 不可用时,先 autoload -Uz compinit && compinit
  • 只有在 compdef 可用时才执行 compdef __pip ... 注册(避免继续抛错);
  • 同步更新文档:把 zsh 的安装指引从 ~/.zprofile 调整为 ~/.zshrc,并补一句 compinit 的前置要求;
  • 更新对应功能测试的期望片段,并添加 NEWS fragment(bugfix)。

✅ 总结 (Summary)

这一改动的目标是把“按文档配置就报错”的坑填平:不要求用户了解 zsh 启动顺序细节,也尽量避免在不合适的时机硬调用 compdef。对最终用户来说,结果就是新 shell 不再出现 compdef not found,而且补全更稳定。