在我的CI我有一个 建立 步骤,使用 pip
并使用私有索引等正确设置
然后我有 测试 步骤,执行 python setup.py test
。
在这种特殊情况下 test
是别名 pytest
。
Setuptools和PIP以不同方式解决包依赖关系,这导致了 测试 尝试重新安装一些软件包。我想阻止这一点。有没有办法使用Setuptools配置(首选)或使用PyTest配置?
更新:
通过流行的需求回购来举例说明我所拥有的问题
https://github.com/vartec/example_repo_setuptools_issue
为什么不像这样覆盖测试命令:
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,
},
)
一个小小的修改 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 = []
所以,据我所知,问题是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本身将始终功能齐全,可导入且内省。
希望这是一个问题(如果我理解正确的话)。
你可以用 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