当所请求的要求之一不存在时,如何使 pip 尽早失败?

Tob*_*ann 6 python pip

最小的例子:

\n
pip install tensorflow==2.9.1 non-existing==1.2.3\n
Run Code Online (Sandbox Code Playgroud)\n
Defaulting to user installation because normal site-packages is not writeable\nLooking in indexes: https://pypi.org/simple, https://pypi.ngc.nvidia.com\nCollecting tensorflow==2.9.1\n  Downloading tensorflow-2.9.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (511.7 MB)\n     \xe2\x94\x81\xe2\x94\x81\xe2\x94\x81\xe2\x94\x81\xe2\x94\x81\xe2\x94\x81\xe2\x94\x81\xe2\x94\x81\xe2\x94\x81\xe2\x94\x81\xe2\x94\x81\xe2\x94\x81\xe2\x94\x81\xe2\x94\x81\xe2\x94\x81\xe2\x94\x81\xe2\x94\x81\xe2\x94\x81\xe2\x94\x81\xe2\x94\x81\xe2\x94\x81\xe2\x94\x81\xe2\x94\x81\xe2\x94\x81\xe2\x94\x81\xe2\x94\x81\xe2\x94\x81\xe2\x94\x81\xe2\x94\x81\xe2\x94\x81\xe2\x94\x81\xe2\x94\x81\xe2\x94\x81\xe2\x94\x81\xe2\x94\x81\xe2\x94\x81\xe2\x94\x81\xe2\x94\x81\xe2\x94\x81\xe2\x94\x81 511.7/511.7 MB 7.6 MB/s eta 0:00:00\nERROR: Could not find a version that satisfies the requirement non-existing==1.2.3 (from versions: none)\nERROR: No matching distribution found for non-existing==1.2.3\n\n
Run Code Online (Sandbox Code Playgroud)\n

所以pip先下载(相当大的)TensorFlow,然后才告诉non-existing不存在。

\n

有没有办法让它更早失败,即打印错误并在之前退出打印错误并退出?

\n

fun*_*man 3

恐怕没有直接的方法来处理它。我最终编写了一个简单的 bash 脚本,在其中使用 pip 的索引命令检查包的可用性:

check_packages_availability () {
  while IFS= read -r line || [ -n "$line" ]; do
      package_name="${line%%=*}"
      package_version="${line#*==}"

      if ! pip index versions $package_name | grep "$package_version"; then
        echo "package $line not found"
        exit -1
      fi
  done < requirements.txt
}

if ! check_packages_availability; then
  pip install -r requirements.txt
fi
Run Code Online (Sandbox Code Playgroud)

这是一个 hacky 解决方案,但可能有效。对于此脚本中的每个包,requirements.txt尝试检索有关它的信息并匹配指定的版本。如果一切正常,它将开始安装它们。


或者您可以使用poetry,它会为您处理解决依赖关系,例如:

pyproject.toml

[tool.poetry]
name = "test_missing_packages"
version = "0.1.0"
description = ""
authors = ["funnydman"]

[tool.poetry.dependencies]
python = "^3.10"
tensorflow = "2.9.1"
non-existing = "1.2.3"

[build-system]
requires = ["poetry-core>=1.0.0"]
build-backend = "poetry.core.masonry.api"
Run Code Online (Sandbox Code Playgroud)

在解析阶段,它会抛出异常而不安装/下载软件包:

Updating dependencies
Resolving dependencies... (0.2s)

SolverProblemError
    
Because test-missing-packages depends on non-existing (1.2.3) which doesn't match any versions, version solving failed.
Run Code Online (Sandbox Code Playgroud)