【问题标题】:All dependencies are not downloaded with "pip download"所有依赖项都不是用“pip download”下载的
【发布时间】:2019-01-15 19:11:44
【问题描述】:

我正在尝试设置一个本地目录,其中包含可重复用于在没有 Internet 连接的机器上安装的包,但我遇到了一些包的问题。

我先用

下载包
pip download -r requirements.txt -d my_packages --no-binary :all:

然后我尝试安装它们

pip install -r requirements.txt --no-index -f my_packages

我在安装时遇到问题的软件包之一是elasticsearch-dsl==6.1.0

pip install -r requirements --no-index -f my_packages
Looking in links: my_packages
Collecting elasticsearch-dsl==6.1.0
Collecting six (from elasticsearch-dsl==6.1.0)
Collecting python-dateutil (from elasticsearch-dsl==6.1.0)
  Installing build dependencies ... error
  Complete output from command /Users/Oskar/.pyenv/versions/2.7.15/envs/no_internet/bin/python2.7 -m pip install --ignore-installed --no-user --prefix /private/var/folders/36/t0_t6_td2f560t2j0149vjmw0000gn/T/pip-build-env-moib0N --no-warn-script-location --no-binary :none: --only-binary :none: --no-index --find-links my_packages -- setuptools wheel:
  Looking in links: my_packages
  Collecting setuptools
    Could not find a version that satisfies the requirement setuptools (from versions: )
  No matching distribution found for setuptools

当然,setuptools 我可以手动安装,但包的数量比所有其他包所需的要多。 django-guardian==1.4.9 是另一个需要pytest-runner 的示例,由于某种原因没有使用pip download 下载

【问题讨论】:

    标签: python pip packages


    【解决方案1】:

    使用pip wheel,而不是pip download,预下载并编译您的依赖项。

    $ pip install wheel
    $ pip wheel -w my_wheels python-dateutil --no-binary :all:
    $ pip install -f my_wheels --no-index python-dateutil    # works
    $ pip install -f my_packages --no-index python-dateutil  # breaks
    

    pip wheel 构建了python-dateutil 包,因此您以后在pip install 期间不需要setuptools_scm

    根据文档,

    Wheel 是一种内置封装格式,具有以下优点: 在每次安装期间重新编译您的软件。

    因此,我推测pip wheel 将使用构建时依赖项,例如setuptools_scm,但pip install 不会,因为.whl 已构建。

    --no-binary :all: 选项仍然做正确的事:下载.tar.gz 中的源代码,而不是任何二进制分发版。

    (jwodder 精明地指出了运行时依赖关系install_requires和构建时依赖关系setup_requires之间的区别。)

    我在本地环境下测试过这个,没有setuptools_scm也没有pytest-runner,没问题。

    (py3) j@computer:~/so-examples|⇒ pip freeze
    django-guardian==1.4.9
    python-dateutil==2.7.3
    six==1.11.0
    

    【讨论】:

    • 在您想要跨平台的东西之前效果很好:)
    【解决方案2】:

    因为你指定了--no-binary :all:,pip 只下载包的 sdists,不下载任何轮子。但是,在安装时,pip 仍然需要轮子形式的每个包,因此pip install 尝试从 sdist 为每个包构建一个轮子,这一步需要setuptoolswheel 以及中列出的任何内容包裹的setup_requires。我不知道为什么你的环境没有setuptools,但是任何健康的Python环境都应该在创建环境时同时安装它和wheel

    不幸的是,setup_requires 中列出的软件包是由setuptools 本身而不是由 pip 安装的,因此pip download 无法捕获这些要求。如果您坚持使用--no-binary :all:,那么唯一的解决方案是手动编译pip install 运行时缺少的软件包列表,下载它们,然后在依赖它们的软件包之前安装缺少的软件包,否则@ 987654321@。幸运的是,该列表可能会很短(可能只有pytest-runnersetuptools_scm)。

    【讨论】:

    • 但是,pip 在安装时仍然需要轮子形式的每个包,因此 pip install 尝试为来自 sdist 的每个包构建一个轮子 - 这不是真的。 pip install pkgname --no-binary=pkgname 将跳过 bdist_wheel 并调用 setup.py install
    • 除此之外,我同意这是最合理的方法。要收集所有构建依赖项,需要一个复杂的解决方案,包括解压缩源 dists、在每个解压缩的目录中运行 setup.py egg_info 以及从 .eggs 目录中收集构建 deps 列表。很可能这也应该为每个构建依赖项递归地重复,因为鸡蛋也是二进制分布;一次性任务过多不必要的开销,也可以/应该用收集轮代替。
    【解决方案3】:

    您可以使用pip2pi 来避免重新发明轮子,这是一个非常方便的工具,可用于创建您自己的 pip 存储库。我为我的团队维护了一个部分 pypi 镜像,并且在这个项目中取得了最好的结果。

    来自其 Github 页面:“pip2pi 根据 pip 要求构建一个与 PyPI 兼容的包存储库”

    $ pip install pip2pi
    $ mkdir packages
    $ pip2tgz packages/ -r requirements.txt
    $ dir2pi -n packages/ # <--- this builds/updates the index, i.e. the "simple/" directory
    

    现在只需通过 http 提供 packages/simple/ 文件夹并将其用作您的索引。

    $ pip install -i http://myserver.net/simple/ -r requirements.txt
    

    为了避免 pip 安全检查的麻烦,您可以像这样调整您的 pip.conf:

    [global]
    format=columns
    disable_pip_version_check = 1
    index-url=file:http://myserver.net/simple/
    

    现在您可以使用常规的pip install 命令从自己的镜像安装。

    【讨论】:

      猜你喜欢
      • 2016-11-08
      • 2016-06-26
      • 2011-05-23
      • 1970-01-01
      • 1970-01-01
      • 2021-07-06
      • 2018-08-29
      • 1970-01-01
      • 2020-10-06
      相关资源
      最近更新 更多