【问题标题】:Install-time dependencies in requirements.txtrequirements.txt 中的安装时依赖项
【发布时间】:2016-04-12 13:14:59
【问题描述】:

我正在使用 tox 准备 venv 并运行单元测试,而我的应用程序需要 openopt 库,该库又在 setup.py 中导入 numpy.distutils.core

无论我如何在我的 requirements.txt 中订购 numpy 和 openopt,我都无法确保在执行 openopt 中的 setup.py 之前安装了 numpy,并以 ImportError: No module named numpy.distutils.core 退出

我该如何解决这个问题?对于开发,我可以将 numpy 添加到 requirements.txt,运行 tox,添加 openopt 并再次运行 tox,但这不是生产就绪设置。

【问题讨论】:

标签: python numpy pip tox


【解决方案1】:

更新 tox 项目中存在一个问题,该问题可能会被实施,它会添加功能以更“官方”的方式处理这些类型的问题。讨论在这里:Add an option to run commands after virtualenv creation but before other steps

更新(更多背景知识): 主要问题是假设已经在setup.py 中安装了一些其他软件包是一个 BadThing(TM)。这些类型的问题属于bootstrapping 的范围,它们可能很难正确处理,但通常需要一些额外的努力才能做到这一点。如果您真的在设置时需要不同的包,您可以查看setup_requires 和一些额外的魔法(例如查看setuptools_scm 以获得灵感)。在最坏的情况下,如果软件包不是很复杂,您可以将其作为软件包的一部分(不过这也有其自身的问题,例如保持最新状态和可能的许可冲突)。

原答案

如果你已经使用requirements.txt,一个简单(但不可否认)的解决方案是:

  1. 创建两个(或更多)需求文件(例如 requirements-0.txtrequirements-1.txt(希望有更好的名称))。
  2. 将包按依赖项排序到这些文件中
  3. 使用commands 而不是deps 以正确的顺序安装它们

.例如

[testenv]
deps = 
    pytest
    # whatever else where order does not matter

commands =
    pip install -r {toxinidir}/requirements-0.txt
    pip install -r {toxinidir}/requirements-1.txt
    # ... and more if needed

    # now do your actual testing ...
    pytest tests/unit

...或者,如果您想让它更简单,只需将要导入的包粘贴在另一个包的setup.py 中,就在您的单个 requirements.txt 前面

[...]
commands =
    pip install <package that needs to be installed first (e.g. numpy)>
    pip install -r {toxinidir}/requirements.txt        
    pytest tests/unit

【讨论】:

  • 这不起作用,因为 tox 在执行 commands 部分之前安装了包。如果在 setup.py 中提到/需要依赖项,则该软件包根本不会安装在 tox 环境中。
  • 您说的场景是正确的(在 setup.py 中有冲突的依赖项),但这不是问题所在。
  • 所以为了清楚起见,这需要 OP 从他的包的 setup.py 中删除 openopt。而是应该显式安装。
  • @jadelord - OP 在 setup.py 中没有 openopt。 openopt 在其 setup.py 中导入了 numpy。 OP 有一个包含 numpy 和 openopt 的 requirements.txt,并且始终首先安装 openopt。这是问题的原因,您只能通过确保在安装 openopt 之前安装 numpy 来完成这项工作。我意识到虽然使用 令人困惑,因为在这种情况下,讨厌的包是 openopt 。我会用具体的包来澄清我的答案。
【解决方案2】:

记录在https://testrun.org/tox/latest/example/basic.html#depending-on-requirements-txt

deps = -rrequirements.txt

根据github上的常用做法,常用trick是:

deps =
    setuptools
    -r{toxinidir}/requirements.txt

【讨论】:

【解决方案3】:

我有一个通用的方法来引导setup.py 中的构建时依赖项。即使您不使用tox,也可以使用它。对于这种情况,请将以下 sn -p 添加到 setup.py 脚本的顶部。

from setuptools.dist import Distribution

# Bootstrapping dependencies required for the setup
Distribution(dict(setup_requires=['numpy']))

警告:这将使用easy_install 安装numpy。用这种方法安装numpy有点棘手。

【讨论】:

  • 注意:此方法仅适用于 setuptools PEP 518 使用 pip 10.0.0 实现,我们可以有一个更清洁的解决方案。
猜你喜欢
  • 2018-10-27
  • 2021-08-05
  • 2021-04-04
  • 2019-01-10
  • 2021-04-11
  • 2016-10-20
  • 2017-05-18
  • 2016-08-21
  • 1970-01-01
相关资源
最近更新 更多