Pip 是 Python 下的包管理工具,是一个命令行程序,可以用来管理和安装 Python 第三方包或模块
Pip 通过调用构建系统来构建包,目前,唯一支持的构建系统是 setuptools
,但是在未来,pip 将支持 PEP517,它允许项目在 apyproject.toml
文件中指定一个备用构建系统
除了构建包之外,构建系统还可以从源代码直接安装这个包,通过调用构建系统来构建一个 wheel
,然后从该 wheel
安装。pip 会在本地缓存已经构建好的 wheel
,避免重复相同的构建
构建系统的当前接口是使用 setup.py
命令行脚本,所有构建操作都由 setup.py
文件中指定的用于调用所需的操作的命令行定义
setuptools 注入
如上所述,pip
当前支持的构建系统是 setuptools
,但是,并非所有软件包都使用 setuptools
来创建自己的构建系统脚本,为了支持 「 纯粹使用 distutils
」 的项目,pip
会在调用 setup.py
之前将setuptools
注入 sys.modules
变量中
该注入对于基于 distutils
的项目是透明的,在构建包时,第三方构建工具仍然需要提供一个 setup.py
文件,并添加用于模拟 pip
所需要的命令
构建系统输出
pip 会收集构建系统生成的任何输出,并在需要的情况下,显示给用户
为了正确的读取构建系统生成的输出,pip 要求输出使用明确定义的编码编写,特别是用户为文本输出配置的编码 ( 可以在 Python 代码中使用 locale.getpreferredencoding
获取 ),如果配置的编码是 ASCII
,则 pip 假定为 UTF-8
( 参考 某些Unix 系统的行为 )
构建系统应该确保它们调用的任何工具 ( 编译等 ) 都使用正确的编码生成输出。具体的实践中,特别是在 Windows 上,工具使用 「 OEM 」 和 「 ANSI」 代码页时的结果是不一致,这可能并不总是可行的
如果构建工具使用了错误的编码生成输出,Pip 会尝试将不支持的字节序列转换为 Python 格式的十六进制转义序列 ( \x80\xff
等 ),当然。输出的结果仍然是使用不正确的编码 ( mojibake )
PEP 518 支持
Pip 支持使用了 PEP518 所定义的格式的 pyproject.toml
文件来声明安装时所需的依赖
在构建这种项目时,pip 将在本地安装所需的依赖项,并使它们可用于构建过程
如 PEP 所述,pip 能够构建一个项目的最低要求是
[build-system] # Minimum requirements for the build system to execute. requires = ["setuptools", "wheel"]
setuptools
和 wheel
必须包含在项目提供的任何 pyproject.toml
文件中,pip 会将这些视为默认值,而且不会将它们添加到项目的 pyproject.toml
文件中的显式提供列表中,一旦 PEP517 支持添加完成后,将取消此限制,并允许使用其他构建工具
pip 会在隔离环境中创建构建依赖性,也就是说,pip 不会将这些依赖安装到用户的 site-packages
中,而是将它们安装在一个临时目录中,该目录在构建期间会添加到用户的 sys.path
中,这可以确保构建的依赖项独立于用户的运行时环境
也就是说,用户已经在 site-packages
安装了旧版本的情况下,即使某个构建的项目需要安装最新版本的 setuptools
,也无需安装新的版本来代替旧的版本
某些情况下,项目或再分发者可能已经存在了用于管理构建环境的明确的工作流程,对于这些工作流程,构建隔离可能会产生一些问题,针对这种情况,pip 提供了 --no-build-isolationflag
来禁用构建隔离,但一旦提供了此选项参数,则使用者就需要自己来确保正确管理构建环境
pip 中的 PEP518
的当前实现要求 pyproject.toml
中指定的任何依赖项都可以作为 wheels
来使用,这是实现的技术限制,仅作为源可用的依赖项需要它们自己的构建步骤,这将递归地调用 PEP518 依赖项安装过程,而涉及的潜在无限递归是不可接受的,因此从源安装构建依赖关系已被禁用,直到找到安全解决此问题为止
此外,它也不支持使用环境标记和附加功能,只考虑版本说明符,对于环境标记和附加功能,可能会在未来的版本中实现,也说不定
未来发展
PEP426 创建的愿景是在元数据规范 2.1版中为项目元数据添加钩子,以明确定义如何从源代码构建项目
一旦 PEP426
元数据规范最终定稿,pip
将迁移到使用该接口,那个时候,此处记录的 setup.py
接口将仅用于遗留目的,直到项目已迁移为止
也就是说,应用程序不应依赖 setup.py
接口提供的任何形式的向后兼容性保证
构建选项
pip install
和 pip wheel
命令中的 --global-option
和 --build-option
选项会可以将额外的参数注入 setup.py
命令 ( --build-option
仅在 pip wheel
命令中可用 )
这两个参数的语法如下
python setup.py <global_options> BUILD COMMAND <build_options>
pip
不会修改任何参数,而是原样传递,而且目前还支持对 distutils
命令行的直接访问
使用 --global-option
和 --build-option
依赖于所使用的构建系统,对于 pip
添加的备用的构建系统,当前的格式可能不被支持