问题 防止setup.py test / pytest安装额外的依赖项


在我的CI我有一个 建立 步骤,使用 pip 并使用私有索引等正确设置

然后我有 测试 步骤,执行 python setup.py test。 在这种特殊情况下 test 是别名 pytest

Setuptools和PIP以不同方式解决包依赖关系,这导致了 测试 尝试重新安装一些软件包。我想阻止这一点。有没有办法使用Setuptools配置(首选)或使用PyTest配置?

更新:

通过流行的需求回购来举例说明我所拥有的问题 https://github.com/vartec/example_repo_setuptools_issue


11407
2017-10-17 17:38


起源

任何令人信服的理由不只是运行 pytest 命令目录而不是使用setup.py? - MrName
@MrName原因是这样的 python setup.py test  应该 无论哪个特定的测试运行器包使用,无论是vanilla unittest,pytest还是像nosetests一样过时的东西。 - vartec
如果已预安装pytest,setuptools会再次安装吗?我以为我遇到了这个问题,它通过将测试框架预先安装到virtualenv中来解决。 - Sergey Vasilyev
您能提供我们可以使用的最小可重复样本git repo吗? - Tarun Lalwani
@TarunLalwani完成了 - vartec


答案:


为什么不像这样覆盖测试命令:

from setuptools import setup
from setuptools.command.test import test


class CustomTest(test):
    def run(self):
        self.distribution.install_requires = []
        super().run()


setup(
    name = "test",
    version = "0.0.1",
    install_requires=['non-existing-package'],
    cmdclass={
        "test": CustomTest,
    },
)

5
2017-10-20 14:39



这是一个有趣的解决方法。我仍然希望减少黑客的解决方案,但如果没有其他方法可行,那可能会 - vartec
@vartec,不知道这是怎么比只做同样工作的两个班轮更好?我刚刚在我的回答中发布了编辑。如果你真的不在乎 install_requires 那么为什么要指定它们并自定义测试类然后忽略它们?当你在第一种情况下可以简单地忽略它们时 test 跑 - Tarun Lalwani


一个小小的修改 setup.py 特别适用于测试应该做的工作

import sys

import pkg_resources
from setuptools import setup, find_packages
from setuptools.dist import Distribution

install_requires = [
    'redis~=2.8.0',
    'example_submodule',
]

tests_require = [
    'pytest',
]

original_function = None

if sys.argv[1] == "test":
    working_set = pkg_resources.WorkingSet()
    new_reqs = set()
    for req in install_requires:
        try:
            sets = working_set.resolve(pkg_resources.parse_requirements(req))
        except Exception as ex:
            new_reqs.add(req)
    install_requires = new_reqs


setup(
    name='example_module',
    version='0.1.0',
    packages=find_packages(),
    install_requires=install_requires,
    tests_require=tests_require,
    setup_requires=['pytest-runner'],
    extras_require={
        'testing': tests_require,
    },
    dependency_links=[
        'git+ssh://git@github.com/vartec/example_repo_setuptools_issue_submodule.git#egg=example_submodule-0.1.0',
    ]
)

看看这确实是你想要的,如果没有,那么提供你的反馈。

编辑-1

如果你真的不在乎 install_requires 的情况下 test 那你就可以做到

if sys.argv[1] == "test":
   install_requires = []

5
2017-10-25 06:38





所以,据我所知,问题是setuptools将内部依赖项安装到本地文件夹中(.eggs 如果我没记错的话),而不是你使用的正常的virtualenv。

你不喜欢setuptools如何做到这一点。我也不是,特别是当我需要使用本地DevPI服务器时(setuptools忽略了这一点)。所以我这样做:

setup(
    ...
    install_requires=['monotonic'],  # just for example
    extras_require={
        'test': ['pytest', 'pytest-timeout'],
        'docs': ['sphinx', 'alabaster'],
    },
)

当您需要测试时,假设您以某种方式创建并安装virtualenv:

pip install -e .[test]

这里, . 是当前目录。 -e 意思是可编辑模式(但可以省略)。 [test] 是一个 setuptools“额外”。您可以声明多个“extras”,并将它们安装为 pip install mylib[ext1,ext2] 如果需要的话。

然后你可以运行测试:

pytest
python setup.py test

后者只有在 test 命令已配置为运行pytest(请参阅 pytest集成手册)。

诀窍是,如果 setuptools 可以在当前环境中找到测试依赖项(virtualenv,pyenv,system python,还有其他),它不会将它们安装为egg,而只会使用已安​​装的版本。

实际上,你甚至不需要申报 tests_require= 在这种情况下,假设库被安装到virtualenv中。如果不是,则测试命令将失败。

同样,你可以 pip install .[docs],并建立你的文档 sphinx-build ... 来自当前virtualenv的命令。

请注意 install_requires 总是安装,无论你添加额外的东西。所以app / lib本身将始终功能齐全,可导入且内省。

希望这是一个问题(如果我理解正确的话)。


3
2017-10-20 18:35





你可以用 requirements.txt 文件指定的依赖项不在PyPI而不是 dependency_links 的参数 setup 方法 setup.py

requirements.txt:

-e git+ssh://git@github.com/gentcys/example_repo_setuptools_issue_submodule.git#egg=example_submodule-0.1.0

-e .[testing]

setup.py:

from setuptools import setup, find_packages

install_requires = [
    'redis~=2.10.0',
    'example_submodule',
]

tests_require = [
    'pytest',
]


setup(
    name='example_module',
    version='0.1.0',
    packages=find_packages(),
    install_requires=install_requires,
    tests_require=tests_require,
    setup_requires=['pytest-runner'],
    extras_require={
        'testing': tests_require,
    },
)

我分叉你的示例回购并做了一些改变 https://github.com/gentcys/example_repo_setuptools_issue.git
我创建了一个子模块repo https://github.com/gentcys/example_repo_setuptools_issue_submodule.git


2
2017-10-23 10:01