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

View File

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

129
poetry.lock generated
View File

@@ -315,6 +315,18 @@ files = [
[package.dependencies] [package.dependencies]
types-awscrt = "*" 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]] [[package]]
name = "certifi" name = "certifi"
version = "2023.5.7" version = "2023.5.7"
@@ -404,6 +416,18 @@ files = [
[package.dependencies] [package.dependencies]
pycparser = "*" 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]] [[package]]
name = "charset-normalizer" name = "charset-normalizer"
version = "3.1.0" version = "3.1.0"
@@ -622,6 +646,18 @@ test = ["iso8601", "pretend", "pytest (>=6.2.0)", "pytest-benchmark", "pytest-co
test-randomorder = ["pytest-randomly"] test-randomorder = ["pytest-randomly"]
tox = ["tox"] 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]] [[package]]
name = "exceptiongroup" name = "exceptiongroup"
version = "1.1.1" 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)"] 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)"] 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]] [[package]]
name = "flake8" name = "flake8"
version = "6.0.0" version = "6.0.0"
@@ -1137,6 +1189,9 @@ files = [
{file = "platformdirs-3.5.1.tar.gz", hash = "sha256:412dae91f52a6f84830f39a8078cecd0e866cb72294a5c66808e74d5e88d251f"}, {file = "platformdirs-3.5.1.tar.gz", hash = "sha256:412dae91f52a6f84830f39a8078cecd0e866cb72294a5c66808e74d5e88d251f"},
] ]
[package.dependencies]
typing-extensions = {version = ">=4.5", markers = "python_version < \"3.8\""}
[package.extras] [package.extras]
docs = ["furo (>=2023.3.27)", "proselint (>=0.13)", "sphinx (>=6.2.1)", "sphinx-autodoc-typehints (>=1.23,!=1.23.4)"] 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)"] 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"}, {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]] [[package]]
name = "pyright" name = "pyright"
version = "1.1.308" version = "1.1.308"
@@ -1434,6 +1509,36 @@ files = [
{file = "tomli-2.0.1.tar.gz", hash = "sha256:de526c12914f0c550d15924c62d72abc48d6fe7364aa87328337a31007fe8a4f"}, {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]] [[package]]
name = "types-aiobotocore" name = "types-aiobotocore"
version = "2.5.0.post2" version = "2.5.0.post2"
@@ -1902,6 +2007,28 @@ typing-extensions = {version = "*", markers = "python_version < \"3.8\""}
[package.extras] [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)"] 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]] [[package]]
name = "wrapt" name = "wrapt"
version = "1.15.0" version = "1.15.0"
@@ -2100,4 +2227,4 @@ redis = ["redis"]
[metadata] [metadata]
lock-version = "2.0" lock-version = "2.0"
python-versions = "^3.7" python-versions = "^3.7"
content-hash = "f09d0644dfef38d2912bdd3a0e95a375a039ff312be97f21250509783b14412e" content-hash = "edb317193b26f7b00f1a4998cb61a56b2f3fd542c15218f0c3858d8e60a33bf0"

View File

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