18

我正在切换一个当前用作测试的项目,以查看差异是什么pipenvpoetry该项目是一个简单的、可再分发的 Django 应用程序。它支持 Python 3.6-8,以及 Django 2.2 和 3.0。我有一个tox.ini文件涵盖了 Python 和 Django 的所有组合,因此:

[tox]
envlist = py{36,37,38}-django{22,30}

[testenv]
whitelist_externals = poetry
skip_install = true

deps =
    django22: Django==2.2
    django30: Django==3.0

commands =
    poetry install -vvv
    poetry run pytest --cov=my_app tests/
    poetry run coverage report -m

我遇到的问题(pipenv世界上不存在)是该poetry install语句将始终用文件中的任何内容覆盖该deps部分中的任何内容poetry.lock(如果不存在则将自动生成)。这意味着测试矩阵永远不会针对 Django 2.2 进行测试——因为每个 tox virtualenv 都会默认安装 Django 3.0。

我不明白这应该如何工作 - 安装依赖项是否应该poetry尊重它正在安装的现有环境?

所以 - 我的问题是 - 我如何设置一个多版本的 tox(或 travis)测试矩阵,以诗歌作为依赖管理器?

pyproject.toml将 Python / Django 版本定义为:

[tool.poetry.dependencies]
python = "^3.6"
django = "^2.2 || ^3.0"

生成的poetry.lock文件(未提交)具有以下 Django 版本信息:

[[package]]
category = "main"
description = "A high-level Python Web framework that encourages rapid development and clean, pragmatic design."
name = "django"
optional = false
python-versions = ">=3.6"
version = "3.0"

更新:包括干净的毒物输出

这是我删除锁定文件并重新创建 tox 环境时的结果。如您所见,toxDjango==2.2作为依赖项安装在 virtualenv 中,但poetry随后将其更新到3.0安装时。

我需要一个运行诗歌安装的解决方案,尊重现有的包安装。即如果pyproject.tomlstatesDjango = "^2.2 || ^3.0"和 2.2 已经安装,则固定到该版本 - 不要尝试升级。

my-app$ tox -r -e py36-django22
py36-django22 recreate: .tox/py36-django22
py36-django22 installdeps: Django==2.2
py36-django22 installed: Django==2.2,my-app==0.1.0,pytz==2019.3,sqlparse==0.3.0
py36-django22 run-test: commands[0] | poetry install -vvv
Using virtualenv: .tox/py36-django22
Updating dependencies
Resolving dependencies...
   1: derived: django (^2.2 || ^3.0)
   ...
PyPI: 10 packages found for django >=2.2,<4.0
   ...
   1: Version solving took 3.330 seconds.
   1: Tried 1 solutions.

Writing lock file

Package operations: 52 installs, 1 update, 0 removals, 3 skipped

  - ...
  - Updating django (2.2 -> 3.0)
  - ...

更新 2

按照下面 sinoroc 的说明 - 我已更新 tox 文件以删除skip_dist和包含isolated_build. 这行得通,有点。tox 构建包并安装它 - 但只有非开发版本,不包括pytestcoverage以及我想在以后包含的大量 linting 工具。即我想通过 tox 运行的工具在诗歌中被指定为开发依赖项。这里有一个解决方案,将所有这些都包含在 tox 文件中 - 但这似乎弄巧成拙 - 因为那时我有诗歌和 tox 都声明依赖关系。

[tool.poetry.dependencies]
python = "^3.6"
django = "^2.2 || ^3.0"

[tool.poetry.dev-dependencies]
pytest = "^3.0"
pytest-cov = "^2.8"
pytest-django = "^3.7"
coverage = "^4.5"
pylint = "^2.4"
pylint-django = "^2.0"
flake8 = "^3.7"
flake8-bandit = "^2.1"
flake8-docstrings = "^1.5"
isort = "^4.3"
mypy = "^0.750.0"
pre-commit = "^1.20"
black = "=19.3b0"

更新3:解决方案

[tox]
isolated_build = True
envlist = lint, mypy, py{36,37,38}-django{22,30}

[travis]
python =
    3.6: lint, mypy, py36
    3.7: lint, mypy, py37
    3.8: lint, mypy, py38

[testenv]
deps =
    pytest
    pytest-cov
    pytest-django
    coverage
    django22: Django==2.2
    django30: Django==3.0

commands =
    django-admin --version
    pytest --cov=my_app tests/

[testenv:lint]
deps =
    pylint
    pylint-django
    flake8
    flake8-bandit
    flake8-docstrings
    isort
    black

commands =
    isort --recursive my_app
    black my_app
    pylint my_app
    flake8 my_app

[testenv:mypy]
deps =
    mypy

commands =
    mypy my_app
4

1 回答 1

14

尚未对其进行彻底测试,但我相信这样的事情应该可以工作:

[tox]
envlist = py{36,37,38}-django{22,30}
isolated_build = True

[testenv]
deps =
    django22: Django==2.2
    django30: Django==3.0
    # plus the dev dependencies
    pytest
    coverage

commands =
    pytest --cov=my_app tests/
    coverage report -m

请参阅tox文档的“包装”一章中的诗歌”部分。


为了避免开发依赖的重复,可以尝试基于extras功能的以下变体:

tox.ini

[tox]
# ...

[testenv]
# ...
deps =
    django22: Django==2.2
    django30: Django==3.0
extras =
    test

pyproject.toml

[tool.poetry]
# ...

[tool.poetry.dependencies]
python = "^3.6"
django = "^2.2 || ^3.0"
#
pytest = { version = "^5.2", optional = true }

[tool.poetry.extras]
test = ["pytest"]

[build-system]
# ...

现在有一些tox插件试图更好地与基于诗歌的项目集成:

于 2019-12-29T19:25:35.400 回答