PEP 453 – 在 Python 安装中显式引导 pip
- 作者:
- Donald Stufft <donald at stufft.io>, Alyssa Coghlan <ncoghlan at gmail.com>
- BDFL 代表:
- Martin von Löwis
- 状态:
- 最终
- 类型:
- 标准跟踪
- 创建:
- 2013 年 8 月 10 日
- 发布历史:
- 2013 年 8 月 30 日,2013 年 9 月 15 日,2013 年 9 月 18 日,2013 年 9 月 19 日,2013 年 9 月 23 日,2013 年 9 月 29 日,2013 年 10 月 13 日,2013 年 10 月 20 日
- 决议:
- Python-Dev 消息
摘要
本 PEP 建议更新 Python 2.7、3.3 和 3.4 中的 安装 Python 模块 指南,以正式推荐使用 pip
作为 Python 包的默认安装程序,并在 Python 3.4 中进行适当的技术更改,以默认提供 pip
来支持该建议。
PEP 接受
Martin von Löwis 于 2013 年 10 月 22 日星期二接受了将本 PEP 纳入 Python 3.4 的提案。
问题 19347 已创建来跟踪本 PEP 的实施。
基本原理
本 PEP 中的提案有两个相关但不同的基本原理。第一个与新用户的体验有关,第二个与更好地支持更广泛的 Python 包生态系统的演进有关。
改进新用户体验
目前,在没有平台包管理器和存储库的系统上,将第三方 Python 包安装到新安装的 Python 中需要首先识别合适的包管理器,然后安装它。
即使在确实具有平台包管理器的系统上,它也不太可能包含 Python 包索引上可用的每个包,即使所需的第三方包可用,平台包管理器中的正确名称也可能不清楚。
这意味着,要有效地使用 Python 包索引生态系统,用户必须知道要安装哪个包管理器,在哪里获取它以及如何安装它。这导致第三方 Python 项目目前需要在各种不理想的替代方案中进行选择。
- 假设用户已经安装了合适的跨平台包管理器。
- 复制说明并告诉他们的用户如何安装包管理器。
- 完全放弃使用依赖项以减轻用户的安装问题。
所有这些可用选项都存在重大缺点。
如果一个项目简单地假设用户已经拥有了这些工具,那么当安装命令不起作用时,初学者可能会收到一条令人困惑的错误消息。某些操作系统可能会通过提供一个全局钩子来缓解这种痛苦,该钩子会查找不存在的命令并建议他们可以安装的操作系统包以使该命令工作,但这仅适用于具有包含提供相关跨平台安装程序命令的包的平台包管理器的系统(例如许多主要的 Linux 发行版)。Windows 和 Mac OS X 用户或更保守的 Linux 发行版无法获得此类帮助。解决此问题对于初学者(他们通常也完全不熟悉编程、使用命令行工具和编辑系统环境变量)的挑战是核心 Python 开发人员从专业教育工作者和其他向新用户介绍 Python 的人那里收到的反馈的常见特征。
如果一个项目选择复制安装说明并告诉他们的用户如何在告诉他们如何安装自己的项目之前安装包管理器,那么每当这些说明需要更新时,每个复制了它们的项目都需要更新它们。当有多个竞争的安装工具可用并且不同的项目推荐不同的工具时,这一点尤其成问题。
通过强烈推广 pip
作为默认安装程序并建议其他项目引用 pip 自身的引导说明 而不是复制它们,可以部分缓解此特定问题。但是,这种方法创建的用户体验仍然不是很好(尽管目前正在努力为 pip
及其依赖项创建一个组合的 Windows 安装程序,这应该可以改善该平台上的情况,并且 Mac OS X 和 *nix 平台通常都有 wget
,因此能够轻松地从命令行下载并运行引导脚本)。
那些决定完全放弃依赖项的项目被迫要么通过发明自己的解决方案来重复其他项目的努力,要么被迫简单地将其自己的源代码树中包含其他项目。这两种选项都存在自己的问题,要么重复整个生态系统中的维护工作,要么可能让用户容易受到安全问题的攻击,因为包含的代码或重复的努力在上游发布新版本时不会自动更新。
通过正式推荐并默认提供特定的跨平台包管理器,将使尝试安装这些第三方包的用户更容易,并且使分发它们的人更容易,因为他们现在应该能够安全地假设大多数用户将拥有合适的安装工具可用(或访问如何获取它们的明确说明)。随着 Wheel 包格式(有意地)没有以 setup.py
形式内置“安装程序”,因此希望从 wheel 文件安装的用户将需要一个安装程序,即使是最简单的情况也是如此,这预计在未来会变得越来越重要。
减少实际安装第三方包的负担也应该减少将每个有用的模块添加到标准库的压力。这将允许对标准库的添加更多地关注 Python 为什么应该开箱即用地提供特定工具,以及为什么该包合理地采用标准库的 18-24 个月的功能发布周期,而不是将安装第三方包的一般难度作为包含的理由。
提供标准安装系统还有助于引导替代构建和安装系统,例如 zc.buildout
、hashdist
和 conda
。只要 pip install <tool>
可以工作,那么标准的 Python 特定安装程序就提供了一种相当安全、跨平台的机制来访问这些实用程序。
支持更广泛的 Python 包生态系统的演进
由于没有新的打包标准可以在没有涵盖 Python 广泛当前使用的版本的过渡策略的情况下获得广泛采用(而不仅仅是未来的版本,就像大多数语言特性一样),因此本 PEP 中提出的更改被认为是 Python 包生态系统演进的必要步骤。
更广泛的社区已经将 Python 包索引作为分发和安装 Python 软件的机制所接受,但语言演进和安全软件分发的不同关注点意味着需要一个涵盖旧版本的更快功能发布周期来正确支持后者。
此外,核心 CPython 开发团队有权在社区的其余部分之前很久就放弃对早期 Python 版本的支持,因为下游商业重新分发者承担了向仍然需要这些版本的用户的提供支持的任务,而许多第三方库则维护与这些版本的兼容性,只要它们仍在广泛使用。
这意味着当前基于 setup.py install
的包安装模型对新打包标准的开发和采用提出了严重的困难,因为根据项目编写其 setup.py
文件的方式,安装命令(以及其他操作)最终可能会调用标准库的 distutils
包。
作为这可能如何导致更广泛的生态系统出现问题的指标,请考虑 Python 2.6 中 distutils
的功能集在 2008 年 6 月(发布 Python 2.6b1 时)被冻结,而 Python 2.7 中 distutils
的功能集在 2010 年 4 月(发布 Python 2.7b1 时)被冻结。
相比之下,使用像 pip
这样的单独安装程序应用程序(它确保即使是直接调用 distutils
的 setup.py
文件仍然支持新的打包标准)可以支持旧版 Python 中的新打包标准,只需升级 pip
(大约每 6 个月发布一次新功能)。通过使最终用户更容易安装和升级更新的构建系统(如 setuptools
)或改进的 PyPI 上传实用程序(如 twine
),旧版 Python 上的情况得到了进一步改善。
使用具有更多元数据和活动较少的分布格式的单独安装程序程序的这种建议模型与大多数操作系统(包括自引入安装程序服务和 MSI 文件格式以来的 Windows)以及许多其他特定于语言的安装程序使用的模型相匹配,这并非偶然。
对于 Python 2.6,此兼容性问题主要限于各种企业 Linux 发行版(及其下游派生版本)。这些发行版通常具有比 CPython 甚至更慢的更新周期,因此它们为被认为是“仅安全修复”版本的 Python 版本提供完全支持(有时甚至可能达到核心开发团队不再完全支持它们的程度——如果您确实需要,您仍然可以获得 Python 2.3 的商业支持!)。
实际上,由于像wget
和curl
这样的工具在Linux系统上很容易获得,大多数Linux上的Python用户已经熟悉命令行,并且大多数Linux发行版都带有默认配置,使得运行Python脚本变得很容易,这意味着现有的pip
任何*nix系统的引导指令已经非常简单明了。即使系统包管理器没有提供pip
,使用wget
或curl
从www.pip-installer.org检索引导脚本,然后运行它,只需要几个shell命令,可以根据需要轻松复制和粘贴。
因此,对于任何*nix系统上的任何版本的Python,在旧版本中引导pip
的需求不被认为是采用新打包标准的主要障碍,因为它只是这些长期稳定版本的用户遇到的一个小障碍。对于*nix系统,本PEP正式认可pip
作为首选的默认打包工具,这一点比使pip
默认可用所涉及的技术细节更为重要,因为它改变了pip
的开发人员与pip
和CPython的下游重新打包者之间的对话性质。
另一方面,对于Python 2.7,采用新元数据标准的兼容性问题更为普遍,因为它影响了Windows和Mac OS X的python.org二进制安装程序,甚至影响了发展相对较快的*nix平台。
首先,与Python 2.6不同,Python 2.7仍然是完全受支持的上游版本,并且将一直持续到Python 2.7.9发布(目前计划于2015年5月发布),届时预计将进入通常的“仅安全修复”模式。这意味着Python 2.7至少还有19个月的时间是Python应用程序的部署目标,并且享受完全的上游支持。即使核心开发团队在2015年将2.7切换到仅安全发布模式后,Python 2.7也可能在2020年以后仍然是商业支持的遗留目标。
虽然对于新的Python应用程序和部署,Python 3已经比Python 2提供了更具吸引力的替代方案,前提是它们没有对Python 2的现有投资,并且没有依赖于特定于Python 2的第三方模块(随着时间的推移,这套模块越来越小),但是要创建令人信服的业务案例来将现有的基于Python 2.7的基础设施更新到Python 3需要更长的时间,尤其是在自动化测试文化薄弱(或不存在)的情况下,这使得难以有效地使用可用的迁移工具。
虽然本PEP仅针对Python 2.7提出文档更改,但一旦pip
拥有Windows安装程序可用,将创建并提交一个单独的PEP,建议为未来的CPython 2.7维护版本创建和分发聚合安装程序,将CPython、pip
和Python启动器用于Windows的安装程序组合到一个下载中(单独的下载仍然可用——聚合安装程序将作为一种便利提供,并作为Windows系统中推荐的Python操作环境的明确指示)。
为什么选择 pip?
pip
已被选为首选的默认安装程序,因为它是一个已经很流行的工具,解决了其前身easy_install
的几个设计和用户体验问题(由于向后兼容性的考虑,这些问题不能轻易地在easy_install
本身中修复)。pip
也非常适合在单个Python运行时安装(包括关联的虚拟环境)的范围内工作,这对于与CPython捆绑在一起的工具来说是一个理想的功能。
其他工具,如zc.buildout
和conda
,在目标方面更有野心(因此在处理外部二进制依赖项方面比pip
好得多),因此,Python生态系统将它们更多地视为与之交互的平台包管理器,而不是作为默认的跨平台安装工具是有意义的。这种关系类似于pip
和平台包管理系统(如apt
和yum
)之间的关系(它们也设计用于处理任意二进制依赖项)。
提案概述
本PEP建议更新安装Python模块指南,以正式推荐使用pip
作为Python包的默认安装程序,而不是当前推荐直接调用setup.py install
命令的方法。
但是,为了避免推荐CPython未提供的工具,进一步建议在安装CPython 3.4或更高版本以及使用标准库的venv
模块通过pyvenv
命令行实用程序创建虚拟环境时,默认提供pip包管理器。
为了支持这一目标,本PEP建议在Python 3.4中包含一个ensurepip
引导模块,以及从pyvenv
自动调用该模块,以及对Windows上Python安装脚本处理方式的更改。使用引导模块而不是直接提供pip
有助于明确区分开发责任,并避免在更新CPython时意外降级pip
。
为了为可能没有从最新版本开始的新Python用户提供明确的指导,本PEP还建议更新Python 2.7和3.3中的“安装Python模块”指南,以推荐安装和使用pip
,而不是直接调用distutils
。它不建议移植为Python 3.4提出的任何代码更改。
最后,PEP还强烈建议CPython重新分发者和其他Python实现确保pip
默认可用,或者至少明确说明它未包含在内。
本PEP不建议将pip(或任何依赖项)直接作为标准库的一部分提供。相反,pip将作为与CPython一起提供的捆绑应用程序,为Python用户提供便利,但受其自身的开发生命周期约束,并且能够独立于核心解释器和标准库进行升级。
显式引导机制
一个名为ensurepip
的附加模块将被添加到标准库中,其目的是将pip及其任何依赖项安装到适当的位置(最常见的是site-packages)。它将公开一个名为bootstrap()
的可调用对象,并通过python -m ensurepip
提供直接执行。
引导程序不会联系PyPI,而是依赖于存储在标准库内的pip的私有副本。因此,仅支持与安装位置相关的选项(--user
,--root
等)。
鼓励用户使用最新版本的pip
被认为是可取的,以便利用持续改进基于PyPI的生态系统安全性的工作,以及利用改进该生态系统速度、可靠性和灵活性的工作。
为了满足默认提供最新版本pip
的目标,pip
的私有副本将在CPython维护版本中更新,这应该与用于新pip
版本的6个月周期保持一致。
安全注意事项
本PEP中的设计故意选择不更改CPython对于随后不运行pip install --upgrade pip
命令的最终用户的信任模型。
安装程序将包含功能齐全的Python版本的全部组件,包括pip
安装程序。安装过程不需要网络访问,并且不会依赖于信任pip
和Python包索引之间建立的网络连接的安全性。
只有选择使用pip
与PyPI通信的用户才需要关注随之而来的额外安全考虑因素。
但是,核心CPython团队仍将协助审查和解决至少目前影响requests
项目(以及pip
)的证书更新管理问题,并且也可能能够提供帮助解决其他已识别的安全问题[1]。
可靠性注意事项
通过将引导程序作为标准库的一部分(而不仅仅是二进制安装程序的功能),可以使用现有的CPython buildbot基础设施轻松测试引导程序命令的正确操作,而无需显著增加安装程序本身的测试负担。
实施策略
为了确保在安装Python或创建虚拟环境时不需要网络访问,ensurepip
模块将作为实现细节,包含pip及其依赖项的完整私有副本,这些副本将用于提取pip并将其安装到目标环境中。必须强调,pip的这个私有副本仅是实现细节,并且不应依赖或假设它存在于通过ensurepip
模块(以及间接地通过venv
)公开的公共功能之外。
目前还没有ensurepip
的参考实现。现有的get-pip.py
引导脚本演示了早期版本的通用概念,但标准库版本将利用CPython安装程序提供的改进的分布功能来包含pip
和setuptools
的私有副本作为wheel文件(而不是作为嵌入式base64编码数据),并且不会尝试联系PyPI(而是直接从私有wheel文件安装)。
与其包含单独的代码来处理引导过程,ensurepip
模块将以适当的方式操作 sys.path
,以允许使用 wheel 文件自行安装,安装到当前的 Python 安装中或虚拟环境中(由传递给引导命令的选项确定)。
建议分五个独立的步骤来实施(除前两个步骤外,所有步骤彼此独立,可以按任何顺序执行)。
- 第一步将更新“安装 Python 模块”文档,建议使用
pip
并参考pip
团队关于下载和安装它的说明。此更改将应用于 Python 2.7、3.3 和 3.4。 ensurepip
模块以及最新发布版本的 pip 和 setuptools 的私有副本将添加到 Python 3.4 中,并相应地更新 3.4 的“安装 Python 模块”文档。- CPython Windows 安装程序将更新为为 Python 3.4 提供新的
pip
安装选项。 - CPython Mac OS X 安装程序将更新为为 Python 3.4 提供新的
pip
安装选项。 venv
模块和pyvenv
命令将更新为在 Python 3.4 中使用ensurepip
。- Windows 上的 PATH 处理将更新为 Python 3.4+。
集成时间表
如果此 PEP 被接受,则建议在 CPython 版本中集成 pip
的时间范围如下。
- 在 3.4.0 alpha 4 发布后尽快。
- 文档更新并基于
pip
1.5 的预发布版本实现ensurepip
。 - Python 3.4 的所有其他提议的功能更改都已实施,包括安装程序更新以调用
ensurepip
。
- 文档更新并基于
- 到 11 月 20 日(3.4.0 beta 1 预计日期的前 3 天)。
ensurepip
更新为使用pip
1.5 发布候选版本。- PEP 101 更新为涵盖确保捆绑的
pip
版本是最新的。
- 到 11 月 24 日(3.4.0 beta 1 预计日期)。
- 与任何其他新功能一样,Python 3.4 的所有提议的功能更改都必须在 Beta 功能冻结之前实现。
- 到 12 月 29 日(3.4.0 beta 2 预计日期的前 1 周)。
requests
证书管理问题已解决。ensurepip
更新为pip
1.5 的最终版本或后续维护版本(包括适当更新的requests
供应商副本)。
(有关每个版本的当前官方计划日期,请参阅 PEP 429。以上列出的日期截至 2013 年 10 月 20 日准确)。
如果在 Python 3.4 beta 2 预计发布日期前一周,没有 pip
1.5 的最终版本或维护版本以及具有适当更新的 requests
版本可用,则此 PEP 的实施将推迟到 Python 3.5。请注意,这种情况被认为不太可能——pip
1.5 发布的暂定日期目前为 12 月 1 日。
在未来的 CPython 版本中,这种协调的计划不应该需要:CPython 发布管理器将能够更新到最新发布的 pip
版本。但是,在这种情况下,需要在 pip
中进行一些修复才能使捆绑正常工作,并且需要改进 requests
的证书更新机制,因此 pip
1.5 的发布周期需要与 CPython 3.4 Beta 版本正确对齐。
建议的 CLI
提议的 CLI 基于现有 pip install
选项的一个子集。
Usage:
python -m ensurepip [options]
General Options:
-h, --help Show help.
-v, --verbose Give more output. Option is additive, and can be used up to 3 times.
-V, --version Show the pip version that would be extracted and exit.
-q, --quiet Give less output.
Installation Options:
-U, --upgrade Upgrade pip and dependencies, even if already installed
--user Install using the user scheme.
--root <dir> Install everything relative to this alternate root directory.
在大多数情况下,最终用户不需要直接使用此 CLI,因为在安装 Python 或创建虚拟环境时,pip
应该已自动安装。但是,它正式记录为公共接口,以支持至少以下已知用例。
- 在安装过程中未选择“安装 pip”选项的 Windows 和 Mac OS X 安装。
- 用户之前运行过“pip uninstall pip”的任何安装。
想要从 PyPI 获取最新版本或需要更多灵活性的用户,然后可以适当地调用提取的 pip
。
建议的模块 API
提议的 ensurepip
模块 API 包含以下两个函数。
def version():
"""
Returns a string specifying the bundled version of pip.
"""
def bootstrap(root=None, upgrade=False, user=False, verbosity=0):
"""
Bootstrap pip into the current Python installation (or the given root
directory).
"""
从 CPython 安装程序调用
CPython Windows 和 Mac OS X 安装程序将分别获得一个新的选项。
- 安装 pip(默认的 Python 包管理实用程序)?
默认情况下会选中此选项。
如果选中此选项,则安装程序将使用刚刚安装的 Python 调用以下命令。
python -m ensurepip --upgrade
这确保了默认情况下,安装或更新 CPython 将确保安装的 pip 版本至少与该 CPython 版本附带的版本一样新。如果已安装了更新版本的 pip,则 python -m ensurepip --upgrade
将简单地返回而无需执行任何操作。
从源代码安装
就像预构建的二进制安装程序将更新为默认运行 python -m ensurepip
一样,源代码分发版的 make install
和 make altinstall
命令也将进行类似的更改。sysconfig
模块中的目录设置应确保 pip
组件自动安装到预期位置。
ensurepip
本身(包括 pip
的私有副本及其依赖项)将始终正常安装(因为它属于标准库的常规部分),但将提供一个选项来跳过 ensurepip
的调用。
这意味着即使从源代码安装也会默认提供 pip
,但重新分发者可以通过其他方式提供 pip
(或根本不提供)仍然可以选择不使用 ensurepip
安装它。
对虚拟环境的更改
Python 3.3 通过 venv
模块包含了一种标准库方法来创建虚拟 Python 环境。自发布以来,很明显很少有用户愿意直接使用此功能,部分原因是虚拟环境中默认没有安装程序。他们反而选择继续使用 virtualenv
包,该包确实包含默认安装的 pip。
为了使 venv
对用户更有用,它将被修改为在创建新环境时默认在环境内部发出 pip 引导。这将使人们在虚拟环境中获得与此 PEP 在虚拟环境外部提供的相同便利,并使 venv
模块更接近与外部 virtualenv
包的功能奇偶校验,使其成为更合适的替代方案。
为了处理用户不希望将 pip 引导到其虚拟环境中的情况,将添加 --without-pip
选项。
venv.EnvBuilder
和 venv.create
API 将更新为接受一个新参数:with_pip
(默认为 False
)。
模块 API 的新默认值是为了与当前行为保持向后兼容(因为假设大多数 venv
模块的调用都是通过第三方工具进行的,这些工具可能不希望安装 pip
,除非明确请求),而命令行界面的默认值是为了尝试确保在大多数虚拟环境中都有 pip
可用,而无需最终用户执行任何其他操作。
由于此更改仅对 Python 3.4 及更高版本有效,因此仍需要第三方 virtualenv
项目才能在 Python 3.3 和 2.7 中获得一致的跨版本体验。
文档
Python 2.7、3.3 和 3.4 中标准库文档的“安装 Python 模块”部分将更新为建议使用 pip
安装程序,该安装程序由 Python 3.4 中默认提供,或由 Python 2.7 或 3.3 中的用户检索和安装。它将简要描述最常见的命令和选项,但将完整的详细信息委托给外部维护的 pip
文档。
在 Python 3.4 中,pyvenv
和 venv
文档也将更新为引用修订后的模块安装指南。
模块安装指南的现有内容将在所有版本中保留,但将在新的“直接调用 distutils”小节下。
将 CA 证书与 CPython 捆绑在一起
ensurepip
实现将包含 pip
CA 捆绑包以及 pip
的其余部分。这意味着 CPython 有效地包含一个 CA 捆绑包,该捆绑包仅在提取后由 pip
使用。
这被认为优于仅依赖系统证书存储,因为它确保 pip
在所有受支持的 Python 版本中都具有相同的行为,即使是在 Windows 上无法访问系统证书存储的 Python 3.4 之前的版本也是如此。
自动安装 setuptools
pip
当前依赖于 setuptools
来处理构建过程中的元数据生成,以及其他一些功能。虽然正在努力减少或消除这种依赖关系,但目前尚不清楚这项工作是否能在 pip 1.5(Python 3.4.0 发布时可能使用的版本)发布之前完成。
本 PEP 建议,如果 pip 仍然需要 setuptools 作为依赖项,则 ensurepip
将包含一个 setuptools 的私有副本(除了 ensurepip
的私有副本)。python -m ensurepip
除了安装 pip
本身之外,还会安装这个私有副本。
但是,此行为在官方上被视为实现细节。其他明确需要 setuptools
的项目仍然必须提供相应的依赖项声明,而不是假设 setuptools
将始终与 pip
一起安装。
setuptools
的私有副本将在不再需要时从 ensurepip
中移除。这很可能是在 get-pip.py
停止默认安装 setuptools
的时候。只要需要 setuptools,它将是最新上游 setuptools 版本的完全未修改的副本,包括 easy_install
脚本(如果上游 setuptools 继续包含它)。与 pip
一起安装 easy_install
并不被认为是理想的,但安装一个损坏的 setuptools 会更糟糕。一旦 pip
开发人员成功地消除了他们对 setuptools
的依赖,并且 setuptools
的私有副本可以完全从 CPython 中移除,这个问题就会自然地解决。
更新 pip 的私有副本
为了跟上打包方面的演变,并为用户提供尽可能新的版本,ensurepip
模块将定期更新到所有它引导的组件的最新版本。
在每次新的 pip
版本发布后,以及在准备任何 Python 版本(包括功能版本)发布期间,将运行一个作为本 PEP 实现的一部分提供的脚本,以确保存储在 CPython 源代码库中的私有副本已更新到最新版本。
更新 ensurepip 模块 API 和 CLI
与 venv
和 pyvenv
一样,ensurepip
模块的 API 和 CLI 将受标准库的正常规则约束:维护版本不允许添加新功能。
但是,嵌入式组件可能会像上面提到的那样更新,因此提取的 pip
可能会在维护版本中提供额外的功能。
卸载
本 PEP 没有提出对 CPython 卸载过程进行任何更改。引导的 pip 将以与任何其他 pip 安装的包相同的方式安装,并以与 Python 环境中任何其他安装后添加项相同的方式处理。
至少在 Windows 上,这意味着引导文件在卸载后将保留下来,因为这些文件不会与 Python MSI 安装程序关联。
虽然可以为 CPython 安装程序自动清除这些目录辩护,但更改此行为被认为超出了本 PEP 的范围。
Windows 上的脚本执行
虽然 Python 3.3 中的 Windows 安装程序已更新为可以选择在 PATH 上提供 python
,但没有进行任何更改来包含 sysconfig.get_path("scripts")
返回的脚本安装目录。
因此,除了添加在安装期间提取和安装 pip
的选项外,本 PEP 还建议更新 Python 3.4 及更高版本中的 Windows 安装程序,以便在安装期间启用 PATH 修改选项时,也将 sysconfig.get_path("scripts")
返回的路径添加到 Windows PATH 中。
请注意,此更改仅在 Python 3.4 及更高版本中可用。
这意味着,对于 Python 3.3,在 Windows 上全局调用 pip 的最可靠方法(无需手动修改 PATH)仍然是 py -m pip
(或 py -3 -m pip
用于选择 Python 3 版本,如果同时安装了 Python 2 和 3)而不是简单地调用 pip
。这是因为 Python 3.3 默认提供 Windows 的 Python 启动器(以及相关的 py
命令)。
对于 Python 2.7 和 3.2,最可靠的机制是使用独立安装程序安装 Windows 的 Python 启动器,然后使用上面提到的 py -m pip
。
将脚本目录添加到系统 PATH 将意味着 pip
在“系统 PATH 上只有一个 Python 安装”的情况下可以可靠地工作,使用 py -m pip
、pipX
或 pipX.Y
仅在并行安装情况下(以及在虚拟环境之外)选择非默认版本。此更改还应该使 pyvenv
命令在 Windows 上更容易调用,以及 pip
、easy_install
和类似工具安装的所有脚本。
虽然在最新版本的 Python 上的脚本调用将通过 Windows 的 Python 启动器运行,但这不应该导致任何问题,只要 Scripts 目录中的 Python 文件在它们的 shebang 行中正确指定了 Python 版本或有一个相邻的 Windows 可执行文件(就像 easy_install
和 pip
一样)。
针对下游分发者的建议
Python 安装的常见来源是通过下游分发者,例如各种 Linux 发行版 [3] [4] [5],OSX 包管理器 [6] [7] [8],以及商业 Python 再分发者 [9] [10] [11]。为了为所有 Python 用户提供一致且用户友好的体验,无论他们如何获取 Python,本 PEP 建议并要求下游分发者
- 确保在安装 Python 时,
pip
要么被安装,要么以其他方式方便地提供给最终用户。- 对于使用二进制安装程序的再分发者,这可能采取在安装期间选择执行
ensurepip
引导程序的形式,类似于 CPython 安装程序。 - 对于使用包管理系统的再分发者,这可能采取单独的包相互依赖的形式,以便安装 Python 包会安装 pip 包,安装 pip 包会安装 Python 包。
- 另一种合理的实现方法是单独打包 pip,但确保存在某种全局挂钩,当用户在未安装 pip 的情况下执行
pip
时,会建议安装单独的 pip 包。选择此选项的系统应确保ensurepip
模块在虚拟环境内部调用时仍然直接安装 pip,但可以在系统 Python 安装中修改模块,以便在全局安装pip
时重定向到平台提供的机制。
- 对于使用二进制安装程序的再分发者,这可能采取在安装期间选择执行
- 即使 pip 通过其他方式全局可用,也不要从 Python 3.4 或更高版本中删除
ensurepip
模块。ensurepip
将需要用于venv
模块自动将 pip 安装到虚拟环境中。- 这类似于现有的
virtualenv
包,许多下游分发者已经对此做出了例外,违反了常见的“解绑”策略。 - 这确实意味着,如果由于安全问题需要更新
pip
,那么ensurepip
引导模块中的私有副本也需要更新。 - 但是,更改 pip 的私有副本以删除嵌入的 CA 证书捆绑包并改为依赖系统 CA 证书捆绑包是合理的更改。
- 确保本 PEP 的所有功能在对重新分发的 Python 版本进行任何修改后都能继续工作。
- 使用
python -m ensurepip --version
或ensurepip.version()
检查将要引导的 pip 的版本。 - 使用
python -m ensurepip
或ensurepip.bootstrap()
将 pip 安装到全局或虚拟 python 环境中。 - 在全局安装中使用
pip install --upgrade pip
不应影响任何已创建的虚拟环境(但允许影响未来的虚拟环境,即使在使用ensurepip
的标准实现时不会这样做)。 - 在虚拟环境中使用
pip install --upgrade pip
不应影响全局安装。
- 使用
- 将构建系统迁移到尽可能使用pip和Wheel,并避免直接调用
setup.py
。- 这将有助于确保在 Python 包生态系统不断发展时,能够更顺利、更及时地迁移到改进的元数据格式。
如果 Python 再分发者选择不遵循这些建议,我们请求他们明确记录此事实,并为其用户提供合适的指南,以便将上游基于pip
的安装说明转换为适合该平台的内容。
其他 Python 实现也鼓励在适用情况下遵循这些指南。
策略和治理
引导软件的维护人员和 CPython 核心团队将共同努力以满足双方的需求。引导软件仍将保持在 CPython 之外,并且本 PEP 不包括 CPython 吸收引导软件的开发责任或设计决策。本 PEP 的目标是减少希望使用第三方包的最终用户的负担,其中的决策是务实的决策,代表了 Python 社区已经对 Python 包管理机构(作为pip
、setuptools
、PyPI、virtualenv
和其他相关项目的作者和维护者)的信任。
向后兼容性
ensurepip
模块本身的公共 API 和 CLI 将遵循 Python 对其标准库的典型向后兼容性策略。本 PEP 捆绑的外部开发软件则不遵循。
最重要的是,这意味着 pip 的引导版本可能会在 CPython 维护版本中获得新功能,并且 pip 继续按照其自己的 6 个月发布周期运行,而不是 CPython 的 18-24 个月发布周期。
安全发布
任何影响ensurepip
模块的安全更新将在发布前与 Python 安全响应团队 (security@python.org) 共享。然后,PSRT 将决定报告的问题是否需要发布带有更新的pip
私有副本的 CPython 安全版本。
许可
pip
目前已获得 1 Clause BSD 许可,并且包含从其他项目中获取的代码。此外,本 PEP 将包含 setuptools,直到 pip 不再需要它为止。这些许可证在下面的表格中列出。
项目 | 许可证 |
---|---|
requests | Apache 2.0 |
six | 1 Clause BSD |
html5lib | 1 Clause BSD |
distlib | PSF |
colorama | 3 Clause BSD |
Mozilla CA Bundle | LGPL |
setuptools | PSF |
所有这些许可证都应与 PSF 许可证兼容。此外,尚不清楚 CA Bundle 是否为受版权保护的材料,以及它是否需要或可以获得许可。
附录:已拒绝的提案
更改 Windows 上的脚本目录名称
本 PEP 的早期版本建议将 Windows 上的脚本安装目录名称从“Scripts”更改为“bin”,以提高pyvenv
创建的虚拟环境的跨平台一致性。
但是,Paul Moore 确定此更改可能与使用早期版本的 Python 创建的跨版本 Windows 安装程序不兼容,因此此更改已从本 PEP 中删除 [2]。
在 Python 2.7 和 3.3 中包含 ensurepip
本 PEP 的早期版本认为,为新用户引导pip
所面临的挑战对 Python 的未来发展构成了足够大的障碍,因此证明将ensurepip
作为新功能添加到即将发布的 Python 2.7 和 3.3 维护版本中是合理的。
虽然为 Python 3.4 提供pip
的提议普遍受到欢迎,但该提议的这一部分存在很大争议,最终被 MvL 作为 BDFL-Delegate 拒绝。
因此,将ensurepip
向后移植到 Python 2.7 和 3.3 的提议已从本 PEP 中删除,转而为pip
创建一个 Windows 安装程序,以及未来可能发布的 PEP,建议创建一个用于 Python 2.7 的聚合安装程序,该安装程序结合了 CPython 2.7、pip
和 Windows 版 Python 启动器。
在引导 pip 时自动联系 PyPI
本 PEP 的早期版本将引导模块称为getpip
,并默认从 PyPI 下载和安装pip
,仅在作为后备选项或在明确请求时使用私有副本。
这导致了几个复杂的边缘情况,以及在为引导模块定义干净的 API 和 CLI 方面存在困难。它还显着改变了在 python.org 上发布的二进制安装程序的默认信任模型,因为最终用户需要明确选择退出信任 PyPI 生态系统的安全性(而不是通过在安装后明确调用pip
来选择加入)。
因此,PEP 简化为当前设计,其中引导始终使用pip
的私有副本。现在,联系 PyPI 始终是一个明确的单独步骤,可以直接访问完整的 pip 接口。
删除对 PyPI 的隐式访问尝试也使得在从自定义源构建安装时默认调用ensurepip
成为可能。
隐式引导
PEP 439,本 PEP 的前身,提出了自己的解决方案。其解决方案涉及运送一个假的pip
命令,该命令在执行时将隐式引导和安装 pip(如果它尚不存在)。这已被拒绝,因为它过于“魔幻”。它隐藏了最终用户何时以及是否安装了 pip 命令。它也没有针对希望通过其系统典型机制管理全局安装的 pip 的下游打包人员提供任何建议或注意事项。
如果用户无意中尝试在没有对相应安装目录的写入权限的情况下引导 pip,则隐式引导机制也会遇到可能的权限问题。
直接在标准库中包含 pip
与本 PEP 类似的是,仅将 pip 包含在标准库中的提议。这将确保 Python 始终包含 pip 并修复所有与默认情况下缺少 pip 相关的最终用户面临的问题。这已被拒绝,因为我们通过在标准库中包含和使用distutils
的历史了解到,失去独立更新打包工具的能力会导致工具处于持续的停滞状态。这使得它永远无法在真正影响用户的范围内合理地发展,因为任何新功能都不会在数年内提供给大众。
允许打包工具与 Python 发布和采用计划分开发展,可以使所有 Python 社区成员都能使用这些改进,而不仅仅是那些能够使用 Python 版本的最前沿功能的人。
过去,如果一个项目继续在外部维护,同时还在标准库中维护一个分支,也会出现“双重维护”问题。由于始终需要外部维护pip
来支持早期版本的 Python,因此提议的引导机制将成为 CPython 核心开发人员(在 pip 开发人员的协助下)的明确责任,而报告给 CPython 跟踪器的 pip 问题将迁移到 pip 问题跟踪器。毫无疑问,用户仍然会对使用哪个跟踪器感到困惑,但希望比历史上将第三方项目的完整公共副本包含在标准库中时看到的困惑要少。
本 PEP 中描述的方法还避免了一些与处理 CPython 维护更新相关的一些技术问题,当 pip 已独立更新到更新版本时。提议的基于 pip 的引导机制会自动处理这种情况,因为 pip 和系统安装程序永远不会就谁拥有 pip 安装发生冲突(它始终通过 pip 管理,无论是直接还是间接通过ensurepip
引导模块)。
最后,单独的引导步骤意味着如果最终用户希望这样做,也可以很容易地完全避免安装pip
。如果集成人员使用系统包来处理用多种语言编写的组件的安装(使用一组通用的工具),这种情况经常发生。
默认为 –user 安装
我们考虑过默认将 pip 引导到每个用户的 site-packages 目录中。但是,这种行为会让人感到意外(因为它与 pip 本身默认行为不同),并且目前也不被认为是可靠的(当 pip 安装到用户 site-packages 目录而不是系统 site-packages 目录时,有一些边缘情况处理不正确)。
参考文献
版权
本文档已置于公有领域。
来源:https://github.com/python/peps/blob/main/peps/pep-0453.rst
上次修改时间:2023-10-11 12:05:51 GMT