简体   繁体   English

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

[英]Prevent setup.py test / pytest from installing extra dependencies

In my CI I have a build step, which uses pip and is correctly set up using private indexes etc. 在我的CI中,我有一个构建步骤,它使用pip并使用私有索引等正确设置。

Then I have test step, which executes python setup.py test . 然后我有测试步骤,执行python setup.py test In this particular case test is an alias to pytest . 在这个特殊情况下, testpytest的别名。

Setuptools and PIP resolve package dependencies differently, which leads to test step attempting to re-install some of the packages. Setuptools和PIP以不同方式解析包依赖关系,这导致尝试重新安装某些包的测试步骤。 I would like to prevent that. 我想阻止这一点。 Is there a way to do that either with Setuptools configuration (preferable) or with PyTest configuration? 有没有办法使用Setuptools配置(首选)或使用PyTest配置?

Update: 更新:

By popular demand repos to exemplify the issue I'm having https://github.com/vartec/example_repo_setuptools_issue 通过流行的需求回购来举例说明我遇到的问题https://github.com/vartec/example_repo_setuptools_issue

Why not override test command like this: 为什么不像这样覆盖测试命令:

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,
    },
)

A small modification in setup.py specifically applicable for test should do the job 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',
    ]
)

See if this is indeed what you were looking for, if not then provide your feedback. 看看这确实是你想要的,如果没有,那么提供你的反馈。

Edit-1 编辑-1

If you really don't care about the install_requires in case of test then you can just do 如果您在test情况下真的不关心install_requires ,那么您可以这样做

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

So, as I understand, the problem is that setuptools installs the internal dependencies into the local folder ( .eggs if I remember correctly), not into the normal virtualenv that you use. 所以,据我所知,问题是setuptools将内部依赖项安装到本地文件夹(如果我没记错的话, .eggs ),而不是你使用的普通virtualenv。

And you do not like how setuptools does that. 你不喜欢setuptools如何做到这一点。 Neither do I, especially when I need a local DevPI server to be used (setuptools ignores that). 我也不是,特别是当我需要使用本地DevPI服务器时(setuptools忽略了这一点)。 So I do this way: 所以我这样做:

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

When you need to test, assuming that you create and install virtualenv somehow: 当你需要测试时,假设你以某种方式创建和安装virtualenv:

pip install -e .[test]

Here, . 在这里, . is the current directory. 是当前目录。 -e mean editable mode (but can be omitted). -e表示可编辑模式(但可以省略)。 [test] is a setuptools "extra" . [test]是一个“额外”setuptools You can declare multiple "extras", and instal them as pip install mylib[ext1,ext2] if needed. 您可以声明多个“extras”,并根据需要pip install mylib[ext1,ext2]它们安装为pip install mylib[ext1,ext2]

Then you can run the tests either way: 然后你可以运行测试:

pytest
python setup.py test

The latter one is only if the test command is already configured to run pytest (see pytest integration manual ). 后者仅在test命令已配置为运行pytest时才能运行(参见pytest集成手册 )。

The trick is that if setuptools can find the test-dependencies in the current environment (virtualenv, pyenv, system python, whatever else), it will not install them as the eggs, and will just use the installed versions. 诀窍是如果setuptools可以在当前环境中找到测试依赖项(virtualenv,pyenv,system python,还有其他),它将不会将它们安装为egg,并且只使用已安装的版本。

Actually, you do not even need to declare tests_require= in that case, as the libraries are assumed to be installed into the virtualenv. 实际上,在这种情况下你甚至不需要声明tests_require= ,因为假定库被安装到virtualenv中。 If they were not, the test command will just fail. 如果不是,则测试命令将失败。

Similarly, you can pip install .[docs] , and build your docs with sphinx-build ... command from the current virtualenv. 同样,您可以使用现有的virtualenv pip install .[docs] ,并使用sphinx-build ...命令构建您的文档。

Note that the install_requires are installed always, no matter with extras you add. 请注意,无论您添加了多少额外内容,都会始终安装install_requires So the app/lib itself will be always fully functional, importable and introspectable. 所以app / lib本身将始终功能齐全,可导入且内省。

Hopefully, this was the question (if I understood it correctly). 希望这是一个问题(如果我理解正确的话)。

You may use requirements.txt file specified dependencies are not in PyPI instead of the dependency_links parameter of setup method in setup.py . 您可以使用requirements.txt文件指定的依赖项不在PyPI中,而不是setup.pysetup方法的dependency_links参数。

requirements.txt: 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: 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,
    },
)

I forked your example repo and made some changes https://github.com/gentcys/example_repo_setuptools_issue.git 我将您的示例repo分叉并进行了一些更改https://github.com/gentcys/example_repo_setuptools_issue.git
And i create a submodule repo https://github.com/gentcys/example_repo_setuptools_issue_submodule.git 我创建了一个子模块repo https://github.com/gentcys/example_repo_setuptools_issue_submodule.git

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM