"pip download" 未下载所有依赖项

All dependencies are not downloaded with "pip download"

我正在尝试设置一个本地目录,其中包含可在没有 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

下载

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

不幸的是,setup_requires 中列出的软件包是由 setuptools 本身安装的,而不是通过 pip 安装的,因此 pip download 无法捕获这些要求。如果你坚持使用--no-binary :all:,那么唯一的解决办法就是手动编译一个pip install运行时丢失的包列表,下载它们,然后要么在依赖的包之前安装丢失的包他们或者 configure setuptools to look for the downloads in my_packages。幸运的是,该列表可能会很短(可能只有 pytest-runnersetuptools_scm)。

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

来自其 Github 页面:"pip2pi builds a PyPI-compatible package repository from pip requirements"

$ 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 命令从您自己的镜像安装。

使用 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 is a built-package format, and offers the advantage of not recompiling your software during every install.

因此,我推测 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