Add tox configuration

Tox manages test environments for all supported Python versions, as
well as linting and formatting tools. On GitHub, the test and lint
steps are kept as close as possible to the Makefile equivalents.
This commit is contained in:
Martijn Pieters
2023-05-15 15:20:53 +01:00
parent 2eabc49d24
commit 0e9a8baeb2
5 changed files with 195 additions and 25 deletions

View File

@@ -32,11 +32,7 @@ jobs:
- name: Install linting requirements
run: poetry install --no-root --with=linting --all-extras
- name: Execute linters
run: |
poetry run black --check --diff .
poetry run flake8
poetry run mypy
poetry run pyright
run: make lint
test:
needs:
@@ -59,11 +55,10 @@ jobs:
cache: poetry
- name: Install testing requirements
run: |
poetry install --no-root --with=dev --all-extras
poetry install --no-root --all-extras
poetry run pip install tox-gh-actions
- name: Execute tests
env:
PYTHONDEVMODE: '1'
run: poetry run pytest
run: poetry run tox
test-summary:
name: Test matrix status

View File

@@ -1,27 +1,27 @@
checkfiles = fastapi_cache/ examples/ tests/
py_warn = PYTHONDEVMODE=1
up:
@poetry update
deps:
@poetry install --no-root --with=linting -E all
@poetry install --no-root --with=linting --all-extras
style: deps
@isort -src $(checkfiles)
@black $(checkfiles)
format: deps
@poetry run tox run -e format
check: deps
@black $(checkfiles) || (echo "Please run 'make style' to auto-fix style issues" && false)
@flake8 $(checkfiles)
@mypy ${checkfiles}
@pyright ${checkfiles}
lint: deps
@poetry run tox run -e lint
test: deps
$(py_warn) pytest
@poetry run tox
test-parallel: deps
@poetry run tox run-parallel
build: clean deps
@poetry build
clean:
@rm -rf ./dist
# aliases
check: lint
style: format

129
poetry.lock generated
View File

@@ -315,6 +315,18 @@ files = [
[package.dependencies]
types-awscrt = "*"
[[package]]
name = "cachetools"
version = "5.3.0"
description = "Extensible memoizing collections and decorators"
category = "dev"
optional = false
python-versions = "~=3.7"
files = [
{file = "cachetools-5.3.0-py3-none-any.whl", hash = "sha256:429e1a1e845c008ea6c85aa35d4b98b65d6a9763eeef3e37e92728a12d1de9d4"},
{file = "cachetools-5.3.0.tar.gz", hash = "sha256:13dfddc7b8df938c21a940dfa6557ce6e94a2f1cdfa58eb90c805721d58f2c14"},
]
[[package]]
name = "certifi"
version = "2023.5.7"
@@ -404,6 +416,18 @@ files = [
[package.dependencies]
pycparser = "*"
[[package]]
name = "chardet"
version = "5.1.0"
description = "Universal encoding detector for Python 3"
category = "dev"
optional = false
python-versions = ">=3.7"
files = [
{file = "chardet-5.1.0-py3-none-any.whl", hash = "sha256:362777fb014af596ad31334fde1e8c327dfdb076e1960d1694662d46a6917ab9"},
{file = "chardet-5.1.0.tar.gz", hash = "sha256:0d62712b956bc154f85fb0a266e2a3c5913c2967e00348701b32411d6def31e5"},
]
[[package]]
name = "charset-normalizer"
version = "3.1.0"
@@ -622,6 +646,18 @@ test = ["iso8601", "pretend", "pytest (>=6.2.0)", "pytest-benchmark", "pytest-co
test-randomorder = ["pytest-randomly"]
tox = ["tox"]
[[package]]
name = "distlib"
version = "0.3.6"
description = "Distribution utilities"
category = "dev"
optional = false
python-versions = "*"
files = [
{file = "distlib-0.3.6-py2.py3-none-any.whl", hash = "sha256:f35c4b692542ca110de7ef0bea44d73981caeb34ca0b9b6b2e6d7790dda8f80e"},
{file = "distlib-0.3.6.tar.gz", hash = "sha256:14bad2d9b04d3a36127ac97f30b12a19268f211063d8f8ee4f47108896e11b46"},
]
[[package]]
name = "exceptiongroup"
version = "1.1.1"
@@ -659,6 +695,22 @@ dev = ["pre-commit (>=2.17.0,<3.0.0)", "ruff (==0.0.138)", "uvicorn[standard] (>
doc = ["mdx-include (>=1.4.1,<2.0.0)", "mkdocs (>=1.1.2,<2.0.0)", "mkdocs-markdownextradata-plugin (>=0.1.7,<0.3.0)", "mkdocs-material (>=8.1.4,<9.0.0)", "pyyaml (>=5.3.1,<7.0.0)", "typer-cli (>=0.0.13,<0.0.14)", "typer[all] (>=0.6.1,<0.8.0)"]
test = ["anyio[trio] (>=3.2.1,<4.0.0)", "black (==23.1.0)", "coverage[toml] (>=6.5.0,<8.0)", "databases[sqlite] (>=0.3.2,<0.7.0)", "email-validator (>=1.1.1,<2.0.0)", "flask (>=1.1.2,<3.0.0)", "httpx (>=0.23.0,<0.24.0)", "isort (>=5.0.6,<6.0.0)", "mypy (==0.982)", "orjson (>=3.2.1,<4.0.0)", "passlib[bcrypt] (>=1.7.2,<2.0.0)", "peewee (>=3.13.3,<4.0.0)", "pytest (>=7.1.3,<8.0.0)", "python-jose[cryptography] (>=3.3.0,<4.0.0)", "python-multipart (>=0.0.5,<0.0.7)", "pyyaml (>=5.3.1,<7.0.0)", "ruff (==0.0.138)", "sqlalchemy (>=1.3.18,<1.4.43)", "types-orjson (==3.6.2)", "types-ujson (==5.7.0.1)", "ujson (>=4.0.1,!=4.0.2,!=4.1.0,!=4.2.0,!=4.3.0,!=5.0.0,!=5.1.0,<6.0.0)"]
[[package]]
name = "filelock"
version = "3.12.0"
description = "A platform independent file lock."
category = "dev"
optional = false
python-versions = ">=3.7"
files = [
{file = "filelock-3.12.0-py3-none-any.whl", hash = "sha256:ad98852315c2ab702aeb628412cbf7e95b7ce8c3bf9565670b4eaecf1db370a9"},
{file = "filelock-3.12.0.tar.gz", hash = "sha256:fc03ae43288c013d2ea83c8597001b1129db351aad9c57fe2409327916b8e718"},
]
[package.extras]
docs = ["furo (>=2023.3.27)", "sphinx (>=6.1.3)", "sphinx-autodoc-typehints (>=1.23,!=1.23.4)"]
testing = ["covdefaults (>=2.3)", "coverage (>=7.2.3)", "diff-cover (>=7.5)", "pytest (>=7.3.1)", "pytest-cov (>=4)", "pytest-mock (>=3.10)", "pytest-timeout (>=2.1)"]
[[package]]
name = "flake8"
version = "6.0.0"
@@ -1137,6 +1189,9 @@ files = [
{file = "platformdirs-3.5.1.tar.gz", hash = "sha256:412dae91f52a6f84830f39a8078cecd0e866cb72294a5c66808e74d5e88d251f"},
]
[package.dependencies]
typing-extensions = {version = ">=4.5", markers = "python_version < \"3.8\""}
[package.extras]
docs = ["furo (>=2023.3.27)", "proselint (>=0.13)", "sphinx (>=6.2.1)", "sphinx-autodoc-typehints (>=1.23,!=1.23.4)"]
test = ["appdirs (==1.4.4)", "covdefaults (>=2.3)", "pytest (>=7.3.1)", "pytest-cov (>=4)", "pytest-mock (>=3.10)"]
@@ -1249,6 +1304,26 @@ files = [
{file = "pyflakes-3.0.1.tar.gz", hash = "sha256:ec8b276a6b60bd80defed25add7e439881c19e64850afd9b346283d4165fd0fd"},
]
[[package]]
name = "pyproject-api"
version = "1.5.1"
description = "API to interact with the python pyproject.toml based projects"
category = "dev"
optional = false
python-versions = ">=3.7"
files = [
{file = "pyproject_api-1.5.1-py3-none-any.whl", hash = "sha256:4698a3777c2e0f6b624f8a4599131e2a25376d90fe8d146d7ac74c67c6f97c43"},
{file = "pyproject_api-1.5.1.tar.gz", hash = "sha256:435f46547a9ff22cf4208ee274fca3e2869aeb062a4834adfc99a4dd64af3cf9"},
]
[package.dependencies]
packaging = ">=23"
tomli = {version = ">=2.0.1", markers = "python_version < \"3.11\""}
[package.extras]
docs = ["furo (>=2022.12.7)", "sphinx (>=6.1.3)", "sphinx-autodoc-typehints (>=1.22,!=1.23.4)"]
testing = ["covdefaults (>=2.2.2)", "importlib-metadata (>=6)", "pytest (>=7.2.1)", "pytest-cov (>=4)", "pytest-mock (>=3.10)", "virtualenv (>=20.17.1)", "wheel (>=0.38.4)"]
[[package]]
name = "pyright"
version = "1.1.308"
@@ -1434,6 +1509,36 @@ files = [
{file = "tomli-2.0.1.tar.gz", hash = "sha256:de526c12914f0c550d15924c62d72abc48d6fe7364aa87328337a31007fe8a4f"},
]
[[package]]
name = "tox"
version = "4.5.1"
description = "tox is a generic virtualenv management and test command line tool"
category = "dev"
optional = false
python-versions = ">=3.7"
files = [
{file = "tox-4.5.1-py3-none-any.whl", hash = "sha256:d25a2e6cb261adc489604fafd76cd689efeadfa79709965e965668d6d3f63046"},
{file = "tox-4.5.1.tar.gz", hash = "sha256:5a2eac5fb816779dfdf5cb00fecbc27eb0524e4626626bb1de84747b24cacc56"},
]
[package.dependencies]
cachetools = ">=5.3"
chardet = ">=5.1"
colorama = ">=0.4.6"
filelock = ">=3.11"
importlib-metadata = {version = ">=6.4.1", markers = "python_version < \"3.8\""}
packaging = ">=23.1"
platformdirs = ">=3.2"
pluggy = ">=1"
pyproject-api = ">=1.5.1"
tomli = {version = ">=2.0.1", markers = "python_version < \"3.11\""}
typing-extensions = {version = ">=4.5", markers = "python_version < \"3.8\""}
virtualenv = ">=20.21"
[package.extras]
docs = ["furo (>=2023.3.27)", "sphinx (>=6.1.3)", "sphinx-argparse-cli (>=1.11)", "sphinx-autodoc-typehints (>=1.23,!=1.23.4)", "sphinx-copybutton (>=0.5.2)", "sphinx-inline-tabs (>=2022.1.2b11)", "sphinxcontrib-towncrier (>=0.2.1a0)", "towncrier (>=22.12)"]
testing = ["build[virtualenv] (>=0.10)", "covdefaults (>=2.3)", "devpi-process (>=0.3)", "diff-cover (>=7.5)", "distlib (>=0.3.6)", "flaky (>=3.7)", "hatch-vcs (>=0.3)", "hatchling (>=1.14)", "psutil (>=5.9.4)", "pytest (>=7.3.1)", "pytest-cov (>=4)", "pytest-mock (>=3.10)", "pytest-xdist (>=3.2.1)", "re-assert (>=1.1)", "time-machine (>=2.9)", "wheel (>=0.40)"]
[[package]]
name = "types-aiobotocore"
version = "2.5.0.post2"
@@ -1902,6 +2007,28 @@ typing-extensions = {version = "*", markers = "python_version < \"3.8\""}
[package.extras]
standard = ["colorama (>=0.4)", "httptools (>=0.5.0)", "python-dotenv (>=0.13)", "pyyaml (>=5.1)", "uvloop (>=0.14.0,!=0.15.0,!=0.15.1)", "watchfiles (>=0.13)", "websockets (>=10.4)"]
[[package]]
name = "virtualenv"
version = "20.23.0"
description = "Virtual Python Environment builder"
category = "dev"
optional = false
python-versions = ">=3.7"
files = [
{file = "virtualenv-20.23.0-py3-none-any.whl", hash = "sha256:6abec7670e5802a528357fdc75b26b9f57d5d92f29c5462ba0fbe45feacc685e"},
{file = "virtualenv-20.23.0.tar.gz", hash = "sha256:a85caa554ced0c0afbd0d638e7e2d7b5f92d23478d05d17a76daeac8f279f924"},
]
[package.dependencies]
distlib = ">=0.3.6,<1"
filelock = ">=3.11,<4"
importlib-metadata = {version = ">=6.4.1", markers = "python_version < \"3.8\""}
platformdirs = ">=3.2,<4"
[package.extras]
docs = ["furo (>=2023.3.27)", "proselint (>=0.13)", "sphinx (>=6.1.3)", "sphinx-argparse (>=0.4)", "sphinxcontrib-towncrier (>=0.2.1a0)", "towncrier (>=22.12)"]
test = ["covdefaults (>=2.3)", "coverage (>=7.2.3)", "coverage-enable-subprocess (>=1)", "flaky (>=3.7)", "packaging (>=23.1)", "pytest (>=7.3.1)", "pytest-env (>=0.8.1)", "pytest-freezegun (>=0.4.2)", "pytest-mock (>=3.10)", "pytest-randomly (>=3.12)", "pytest-timeout (>=2.1)", "setuptools (>=67.7.1)", "time-machine (>=2.9)"]
[[package]]
name = "wrapt"
version = "1.15.0"
@@ -2100,4 +2227,4 @@ redis = ["redis"]
[metadata]
lock-version = "2.0"
python-versions = "^3.7"
content-hash = "f09d0644dfef38d2912bdd3a0e95a375a039ff312be97f21250509783b14412e"
content-hash = "edb317193b26f7b00f1a4998cb61a56b2f3fd542c15218f0c3858d8e60a33bf0"

View File

@@ -42,10 +42,11 @@ pytest = "*"
requests = "*"
coverage = "^6.5.0"
httpx = "*"
tox = "^4.5.1"
[build-system]
requires = ["poetry>=0.12"]
build-backend = "poetry.masonry.api"
requires = ["poetry-core"]
build-backend = "poetry.core.masonry.api"
[tool.poetry.extras]
redis = ["redis"]

47
tox.ini Normal file
View File

@@ -0,0 +1,47 @@
[tox]
env_list =
py37,py38,py39,py310,py311
minversion = 4.5.1
[gh-actions]
# Map Github Actions Python version to environment factors
# Requires tox-gh-actions 3.x is installed in the GitHub action
python =
3.7: py37
3.8: py38
3.9: py39
3.10: py310
3.11: py311
[testenv]
description = Run the tests with pytest
package = wheel
extras = all
set_env =
# trick poetry into adopting the tox virtualenv
POETRY_VIRTUALENVS_PATH = {[tox]work_dir}
allowlist_externals = poetry
commands_pre =
poetry install --no-root --sync --all-extras
commands =
python -X dev -m pytest {tty:--color=yes} {posargs}
[testenv:lint]
description = Run the linters
skip_install = true
commands_pre =
poetry install --no-root --with=linting --sync --all-extras
commands =
black --check --diff .
flake8
mypy
pyright
[testenv:format]
description = Format the code
skip_install = true
commands_pre =
poetry install --no-root --sync --with=linting
commands =
black .
isort .