Python Pip 参考手册 - pip install 命令 ( 四 )

yufei       5 年, 9 月 前       3258

pip install 命令的知识点怎么会这么多啊,本来以为三个章节就差不多了,现在看来,再加上这第四个,说不定还讲不完

查找包

pip install 命令通过简单的 HTTP 接口在 PiPY 上查找包,相关的文档可以访问 这里这里

pip 提供了提供了许多包索引选项,用于定制包的查找方式

pip 可以从多处查找包,从 PyPI 上 ( 如果没有通过 --no-index 禁用 ) ,从本地文件系统中,以及通过--find-links--index 指定的任何其他存储库 URL

搜索的位置没有优先级,而是全部检查,然后选择 「 最佳 」 匹配要求 ( 有关版本号的知识,可以访问 PEP440 了解详细信息 )

关于查找包的范例,可以访问 Python Pip 参考手册 - pip install 命令 ( 一 )

SSL 证书验证

v1.3 开始,pip 通过 https 提供 SSL 证书验证,以防止针对 PyPI 下载的中间人攻击

缓存

v6.0 开始,pip 提供了一个功能类似于 Web 浏览器的默认启用 ( on-by-default ) 的缓存系统

虽默认情况下缓存处于启用状态,且默认情况下也会正确的运行,但我们可以使用 --no-cache-dir 选项禁用缓存并始终访问 PyPI

在进行任何实质性的 HTTP 请求前,pip 首先会检查本地缓存,以确定本地是否存在针对该请求的合适的本地响应,如果存在,则直接返回该响应,而不是从远程 PiPY 获取

如果本地缓冲中存在该请求的包,但包已经过时,那么它将会尝试发出条件请求以刷新本地缓存,该请求可能会收到一个空的响应,告诉 pip 应该使用缓存项 ( 并刷新过期时间 ),也可能收到一个全新的响应,而 pip 就可以把该响应保存到缓存中

将响应保存到缓存中时,pip 会首先使用 CacheControl 响应头,如果存在的话,否则使用 Expires 响应头,如果存在的话

这种缓存行为可以将 pip 作为浏览器来使用,允许 pip 与索引服务器进行通讯,以便确定特定项目的缓存时长

这种缓存系统非常强大,能够最小化网络活动,但它并不完全网络访问,如果你需要绕过访问 PyPI 而使用本地安装,请访问 本地软件包安装 以获得更多信息

缓存目录的默认位置取决于操作系统

  1. Unix 上,一般为 ~/.cache/pip,但也同时受 XDG_CACHE_HOME 环境变量影响

  2. macOS 上,为 ~/Library/Caches/pip

  3. Windows 上,为 <CSIDL_LOCAL_APPDATA>\pip\Cache

Wheel 缓存

Pip 会从 pip 缓存目录中的子目录 wheels 中查找并使用在那里找到的任何包,这也可以通过使用禁用 HTTP 缓存的 --no-cache-dir 选项来禁用

pip wheels 缓存的内部结构不是 pip API 的一部分,从 v7.0 版本开始,pip 为每个构建 wheel 的 sdist 创建一个子目录,并将结果 wheel 放在里面

Pip 会尝试从这些构建中选择最合适的 wheel,但其实更偏爱构建一个新的 wheel,这意味着当一个包包含了可选的 C 扩展并且构建带有 py 标记的 wheel 时,当无法构建 C 扩展时,只要任何通用的 wheel 已经构建,那么 pip 将不会尝试为支持它的 Pythons 构建更好的 wheel

为了纠正这个问题,可以使用 Python 特定标记来构建 wheel

当没有找到一个 sdist wheels 时,pip 将尝试自动构建一个 wheel 并将其插入 wheels 缓存中

哈希校验模式

v8.0 开始,pip 支持使用本地哈希值来检查检查下载的包归档,防止被远程篡改,如果要使用一个或多个哈希值来验证包,可以将这些哈希值添加到行的末尾,就像下面的代码一样

FooProject == 1.2 --hash=sha256:2cf24dba5fb0a30e26e83b2ac5b9e29e1b161e5c1fa7425e73043362938b9824 \
    --hash=sha256:486ea46224d1bb4fb680f34f7c9ad96a8f24ec88be73ea8e5a6c65260e9cb8a7

支持使用多个哈希是很重要的,因为包可能同时存在二进制和源代码分发,或者存在为各种平台提供二进制分发,这些分发的哈希值是不一样的,如果要跨平台构建,那么就要添加多个哈希值

目前推荐的哈希算法是 sha256,但 pip 支持 hashlib 模块中的所有哈希算法,但是,请不要使用比较弱的哈希算法,比如 md5sha1sha224 ,以免带来错误的安全感

需要注意的是,哈希校验的选择只能是全有或全无,出于任何要求而使用 --hash 选项不仅会检查该哈希值,还会激活全局哈希检查模式,这会强加其它几个安全限制

  1. 所有的需求 ( requirements ) 都需要哈希值,很少使用部分散列的需求文件,因为它可能带来一个安全隐患:恶意代理可能会通过其中一个未处理的需求将错误的代码放入安装的包中

    请注意,在 URL 中使用 #md5 = ... 添加的哈希值同样也会带来安全隐患,因为 md5 是可碰撞的,无论强度如何,因此我们需要使用使用更强大的哈希值,例如 sha256

  2. 所有依赖项都需要哈希值,如果需求文件中存在某个未添加哈希值的依赖项,同样会导致错误

    记住上面说的全有或全无,要么所有的需求都添加哈希值,要么都不添加

  3. 如果使用了哈希校验,项目名称 ( 而不是 URL 或本地文件系统路径) 形式的需求必须使用 == 符号固定到特定版本,防止使用了与需求说明符匹配的新版本时出现哈希不匹配的情况

  4. 如果使用了哈希校验,则不允许再使用 --egg ,因为它会将依赖项的安装委托给 setuptools,这使得 pip 无法执行上述任何一项安全检查

可以使用 --require-hashes 命令行选项强制使用哈希检查模式

$ pip install --require-hashes -r requirements.txt
    ...
    Hashes are required in --require-hashes mode (implicitly on when a hash is
    specified for any package). These requirements were missing hashes,
    leaving them open to tampering. These are the hashes the downloaded
    archives actually had. You can add lines like these to your requirements
    files to prevent tampering.
        pyelasticsearch==1.0 --hash=sha256:44ddfb1225054d7d6b1d02e9338e7d4809be94edbe9929a2ec0807d38df993fa
        more-itertools==2.2 --hash=sha256:93e62e05c7ad3da1a233def6731e8285156701e3419a5fe279017c429ec67ce0

这种强制模式在部署脚本中很有用,可以确保需求文件的作者提供哈希值,这也是一种获取哈希值列表的便捷方式,因为它会显示所获取的包的哈希值

但这个选项仅为每个包提取首选归档,因此我们可能需要使用 pip hash 命令给备用归档添加哈希,例如,同时存在二进制和源分发的时候

哈希检查模式下会禁用 wheel 缓存

哈希检查模式下会禁用 wheels 缓存,以防止出现虚假哈希不匹配的错误,这种错误一般出现在安装已经自动构建到缓存 wheels 中的 sdists 时,因为这些 wheels 将被选中进行安装,但它们的哈希值与需求文件中的 sdist哈希值不匹配。

更复杂的是,本地构建的 wheels 是不确定的,因为会把修改时间加入归档中,使得哈希在机器和缓存刷新之间变得不可预测

C 代码的编译进一步增加了非确定性,因为许多编译器在其输出中包含随机种子值

当然了,也不要太悲观,至少,从索引服务器获取的 wheels 每次都是相同的,它们会保存在本地的 HTTP 缓存中,而不是 wheels 缓存中,因此,在哈希检查模式下也是可用的

因此,禁用 wheels 缓存的唯一缺点是为 sdists 提供额外的构建时间,这可以使用索引服务器提供预构建的 wheels 来解决

哈希检查模式也适用于 pip download 命令和 pip wheel 命令,同时我们也在用户指南章节中详细阐述了 散列检查模式与其他可重复性策略的比较

警告:请注意 setup.py 中的 setup_requires 变量,会 (比较罕见) 导致软件包的依赖项直接由 setuptools 下载,跳过 pip 的哈希检查,如果你需要使用这样的包,可以访问 控制 setup_requires

警告:通过直接使用 setuptools 安装实际项目时,请注意不要使所有安全工作无效,例如,通过调用 python setup.py installpython setup.py developeasy_installsetuptools 会下载,不检查需求文件中缺失的任何内容,随着项目的发展,很容易错过任何内容。安全起见,你应该使用 pip install --no-deps 安装项目

可以使用下面的命令代替 python setup.py develop

pip install --no-deps -e .

可以使用下面的命令代替 python setup.py install

pip install --no-deps .

从 PiPY 返回的哈希摘要

每个包的下载网址的哈希部分,PiPY 都添加了该包的 MD5 哈希摘要值,如 #md5=123... ,用于 pip 检查下载的包是否遭到损坏

除了 md5 外,此处还可以使用其它的 hashlib 模块支持的哈希算法:sha1sha224sha384sha256sha512

由于这个哈希是远程生成的,因此并不能够有效的防止篡改,也就不满足 --require-hashes 选项要求的每个包都有一个本地哈希

「 可编辑 」 安装

「 可编辑 」 安装基本上就是 setuptools 开发模式 安装

我们可以在 「 可编辑 」 模式下安装本地项目或 VCS 项目

$ pip install -e path/to/SomeProject
$ pip install -e git+http://repo/my_project.git#egg=SomeProject

有关 VCS 相关语法 的详细信息,可以阅读前面章节中的 VCS 支持部分

对于本地项目,SomeProject.egg-info 是相对于项目路径创建的,这比仅使用 setup.py develop 更有优势,因为它直接相对于当前工作目录创建 egg-info

目前尚无回复
简单教程 = 简单教程,简单编程
简单教程 是一个关于技术和学习的地方
现在注册
已注册用户请 登入
关于   |   FAQ   |   我们的愿景   |   广告投放   |  博客

  简单教程,简单编程 - IT 入门首选站

Copyright © 2013-2022 简单教程 twle.cn All Rights Reserved.