requirements.txt 中的安装时依赖项

Install-time dependencies in requirements.txt

我正在使用 tox 准备 venv 和 运行 单元测试,我的应用程序需要 openopt 库,该库又在其 setup.py.

中导入 numpy.distutils.core

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

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

UPDATE tox 项目中存在一个问题,可能会实施该问题,该问题将添加功能以更 "official" 的方式处理此类问题。讨论在这里:Add an option to run commands after virtualenv creation but before other steps

更新(更多背景知识): 主要问题是假设已经在 setup.py 中安装了一些其他软件包是 BadThing(TM) .这些类型的问题属于 bootstrapping and they can be hellish to handle properly, but usually this is possible with some extra effort. If you really need a different package at setup time, you can look into setup_requires and some additional magic (have a look e.g. at setuptools_scm 领域的灵感)。在最坏的情况下,如果软件包不太复杂,您可以将其作为软件包的一部分(尽管它有自己的问题,比如保持最新和可能的许可冲突)。

原回答:

如果您已经在使用 requirements.txt,一个简单(但公认的丑陋)的解决方案是:

  1. 创建两个(或更多)需求文件(例如 requirements-0.txtrequirements-1.txt(希望有更好的名称))。
  2. 按相关性将包排序到这些文件中
  3. 使用 commands instead of 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[=21= 前面]

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

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

deps = -rrequirements.txt

根据github上的惯例,常用的技巧是:

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

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

from setuptools.dist import Distribution

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

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