PEP 704 – 默认情况下要求包安装程序使用虚拟环境
- 作者:
- Pradyun Gedam <pradyunsg at gmail.com>
- 发起人:
- Brett Cannon <brett at python.org>
- PEP 代理人:
- Paul Moore <p.f.moore at gmail.com>
- 讨论至:
- Discourse 帖子
- 状态:
- 已撤回
- 类型:
- 标准跟踪
- 主题:
- 打包
- 创建日期:
- 2023年1月16日
- 发布历史:
- 2023年1月16日
摘要
此 PEP 建议,像 pip 这样的包安装程序在 Python 3.13+ 上默认要求使用虚拟环境。
PEP 撤回
在此 PEP 的讨论过程中,很明显,对 pip 用户体验的更改不受 PEP 所提议的控制。此外,还清楚地表明,相当多的用户依赖于能够将由 pip 管理的依赖项与由其他工具管理的依赖项混合使用(最显著的是在使用 Conda 时)。
此外,所提议变更的好处可以通过 PEP 668(在撰写本文时已接受并实现)来实现相当一部分。它允许 Python 解释器的再分发者控制用户是否应该被要求使用虚拟环境、向用户展示的消息以及该更改如何为他们的用户进行推广。
由于在此 PEP 中强制使用 pip 的虚拟环境是主要焦点,因此撤回此 PEP 比将其重定向到不同主题更为合适。
未来解决虚拟环境命名约定问题/挑战的 PEP 仍然是合适的,但任何此类工作都应作为一个新的 PEP 来开始,该 PEP 侧重于此类约定的好处,而不是强制执行它。
动机
Python 虚拟环境是 Python 开发工作流的重要组成部分。然而,它们需要额外的努力,因为它们是一个选择加入的功能,并且需要用户要么
- 采取明确的步骤来激活/停用虚拟环境
- 使用
<path-to-venv>/<bin-path>/<executable>来运行文件
对于新用户来说,当不使用虚拟环境时,事情似乎会正常工作——直到它们不再正常工作。此外,激活虚拟环境在不同平台上使用略有不同的语法和机制。这增加了虚拟环境的入门难度,因为现在需要解释有关其有用性、如何使用以及为何有用的信息和背景,以证明在工作流中添加额外步骤是合理的。
这还会造成出错的范围,因为用户需要记住在运行像 pip 这样的安装程序之前激活虚拟环境,或者配置这些安装程序以出错退出。在某些 Linux 发行版上,忘记这样做可能会导致安装程序修改操作系统拥有的文件(这在某种程度上通过 PEP 668 得到了缓解,前提是发行版选择将其环境标记为相应)。
基本原理
将像 pip 这样的安装程序的默认行为更改为要求激活虚拟环境,将
- 使新用户更容易开始使用 Python(因为有一个一致的体验,并且虚拟环境被理解为是必须使用的东西)
- 通过默认明确标记您没有使用虚拟环境,从而减少所有用户意外安装问题的范围。
将虚拟环境设置在项目目录中,并命名为 .venv,这消除了常见工作流中的一个决策点,并在生态系统中创建了一个清晰的约定。
规范
默认要求使用虚拟环境
当用户在没有活动虚拟环境的情况下运行安装程序时,安装程序应打印错误消息并以非零退出码退出。
错误消息应告知用户需要虚拟环境,应提供特定于 shell 的指令,说明如何创建和激活名为 .venv 的虚拟环境,并且应提供指向解释如何创建和激活虚拟环境的文档页面的链接。
有关更多详细信息,请参阅 实现说明。
选择不使用虚拟环境
安装程序也应提供一个明确的选择退出机制来禁用此要求,允许最终用户在虚拟环境外部使用它。如果安装程序不提供此功能,则应在错误消息和文档页面中提及。
变更的统一时间表
安装程序可以自行决定在任何 Python 版本上实现此默认行为,但应在 Python 3.13 或更高版本上实现。
向后兼容性
此 PEP 与用户在虚拟环境外部使用安装程序的现有工作流不兼容。此类用户将收到错误消息,并且需要要么
- 明确选择在虚拟环境外部运行安装程序,或
- 创建并使用虚拟环境
已经在使用虚拟环境的用户将不受此更改的影响。
工作流工具(在幕后为用户管理虚拟环境)应不受影响,因为它们应该已经在运行安装程序时使用虚拟环境。
安全隐患
此 PEP 不会引入任何新的安全影响。
如何教授此内容
此 PEP 要求新用户在开始使用 Python 包时创建并使用虚拟环境。然而,这是一种最佳实践,正如 Python 打包用户指南中关于“安装 Python 包的基础知识”的部分 所示,该部分在讨论使用 pip 之前解释了虚拟环境是什么以及如何使用。
参考实现
此 PEP 没有参考实现。然而,提议的行为在 pip 中已在很大程度上实现,并且可以通过将 PIP_REQUIRE_VENV 环境变量设置为 1 来激活。(将其设置为未设置则会产生不要求在安装时使用虚拟环境的提议的 opt-in 行为。)
实现说明
检测活动中的虚拟环境
如 PEP 668 中所述,可靠地检测虚拟环境的逻辑是
def is_virtual_environment():
return sys.base_prefix != sys.prefix or hasattr(sys, "real_prefix")
关于使用虚拟环境的文档
包安装程序应在错误消息中提供指向文档页面的链接。
理想情况下,此类文档页面应解释什么是虚拟环境、为什么需要它们以及如何使用 venv 创建和激活虚拟环境。它应包含最常见 shell 和平台的说明。
此类文档页面应在 Python 打包用户指南 中提供,以减少安装程序在覆盖此主题上的重复工作。
被拒绝的想法
不要为虚拟环境目录指定名称
使用一致的虚拟环境目录名称很重要,原因有几个:
- 这使得用户更容易找到虚拟环境目录并激活它。
- 这消除了新用户的一个决策点,因为他们不需要为虚拟环境目录决定名称。
- 它在生态系统中创建了一个清晰的约定,使得用户更容易找到文档。
- 它确保了不同工具之间的一致性,因此错误消息中的差异不会让用户感到困惑。
为虚拟环境目录使用不同的名称
从功能上看,只要有一个一致的建议,目录名称就没有太大区别。
选择 .venv 作为名称是因为它
- 不与任何有效的 Python 导入名称冲突
- 不与标准库中的
venv模块冲突 - 在 Python 社区中已有现有用法
- 在常见文本编辑器中支持自动检测
- 在常见的键盘布局上,无需修改键即可输入
不要将工具行为与 Python 版本挂钩
此 PEP 在安装程序行为与 Python 版本之间创建了耦合。
这已经是用于安装工具中行为更改的推出机制。例如,Python 3.11 上的 pip 将使用 importlib.metadata 而不是 pkg_resources 来解析/获取包元数据,并且将使用 sysconfig 而不是 distutils.sysconfig 来获取解压 wheel 的路径。
与这些情况不同的是,它们应该对最终用户基本透明。此 PEP 提出的行为更改对最终用户不透明,并且要求他们采取行动。
这主要的好处是,它允许再分发者及时调整他们的工具以适应新的 Python 版本,并为生态系统中的变更提供一个清晰一致的节点。它还为默认行为何时将始终要求使用虚拟环境设定了一个明确的最后期限(一旦 Python 3.12 达到生命周期结束)。
这种方法的首要问题在于,它在用户升级到新 Python 版本时强制执行行为更改,这可能会阻碍新 Python 版本的采用。然而,这是针对现有用户的迁移/升级,并且通常期望在迁移/升级过程中需要进行一些更改。
此 PEP 的作者认为,在整个生态系统中一致地应用此最佳实践并设定最后期限的好处, outweighs 了在用户升级时强制执行最佳实践的缺点。
未解决的问题
无。
版权
本文档置于公共领域或 CC0-1.0-Universal 许可证下,以更宽松者为准。
来源:https://github.com/python/peps/blob/main/peps/pep-0704.rst