web-dev-qa-db-fra.com

Comment puis-je faire en sorte que tox et poésie travaillent ensemble pour prendre en charge le test de plusieurs versions d'une dépendance Python?

Je passe un projet qui utilise actuellement pipenv à poetry comme test pour voir quelles sont les différences. Le projet est un simple, redistribuable, Django app. Il prend en charge Python 3.6-8, et Django 2.2 et 3.0 . J'ai un fichier tox.ini Qui couvre toutes les combinaisons de Python et Django donc:

[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

Le problème que j'ai (qui n'existe pas dans le monde pipenv) est que l'instruction poetry install Écrasera toujours tout ce qui se trouve dans la section deps avec tout ce qui se trouve dans le poetry.lock Fichier (qui sera généré automatiquement s'il n'existe pas). Cela signifie que la matrice de test ne testera jamais contre Django 2.2 - car chaque tox virtualenv obtient Django 3.0 installé par défaut.

Je ne comprends pas comment cela est censé fonctionner - l'installation de dépendances à l'aide de poetry doit-elle respecter l'environnement existant dans lequel elle est installée ou non?

Alors - ma question est - comment mettre en place une matrice de test multi-version tox (ou travis), avec la poésie comme gestionnaire de dépendances?

Mon pyproject.toml Définit Python/Django versions comme:

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

Le fichier poetry.lock Généré (non validé) a cette Django informations de version:

[[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"

MISE À JOUR: inclure une sortie toxique propre

C'est le résultat lorsque je supprime le fichier de verrouillage et que je recrée l'environnement tox. Comme vous pouvez le voir, tox installe Django==2.2 En tant que dépendance dans virtualenv, mais poetry le met alors à jour en 3.0 Lors de l'installation.

J'ai besoin d'une solution qui exécute l'installation de poésie, en respectant les installations de package existantes. c'est-à-dire que si pyproject.toml indique Django = "^2.2 || ^3.0", et que 2.2 est déjà installé, alors épinglez à cette version - n'essayez pas de mettre à jour.

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)
  - ...

MISE À JOUR 2

En suivant les instructions de sinoroc ci-dessous - J'ai mis à jour le fichier tox pour supprimer skip_dist Et inclure isolated_build. Cela fonctionne, en quelque sorte. tox construit le paquet et l'installe - mais seulement la version non-dev, qui n'inclut pas pytest, coverage et un hôte d'outils de peluchage que j'aimerais inclure plus tard point. c'est-à-dire que les outils que je veux utiliser dans tox sont spécifiés comme dépendances de développement dans la poésie. Il y a une solution ici, pour inclure tout cela dans le fichier tox - mais cela semble autodestructeur - car alors j'ai la poésie et le tox tous deux déclarant des dépendances.

[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"

MISE À JOUR 3: solution

[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
9
Hugo Rodger-Brown

Je ne l'ai pas complètement testé, mais je pense que quelque chose comme ça devrait fonctionner:

[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

Voir la section " poésie " dans le chapitre "emballage" du tox documentation .


Afin d'éviter la répétition des dépendances dev , on pourrait essayer la variation suivante basée sur fonctions supplémentaires :

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]
# ...
8
sinoroc