From 0ac30b0e9b056c4c21e78edd3c50cd5a3b19e8a3 Mon Sep 17 00:00:00 2001 From: Guy Bolton King Date: Wed, 20 Apr 2022 12:25:11 +0100 Subject: [PATCH 1/6] Use poetryw and toxw wrappers and update docs --- CONTRIBUTING.md | 16 ++--- ci-tools/bootstrap-user-python-support | 50 ---------------- ci-tools/python-versions.sh | 11 ---- ci-tools/tox-bootstrap | 28 --------- ci-tools/wrappers.sh | 65 ++++++++++++++++++++ poetry.lock | 82 ++++++++++++++++++++++++-- poetryw | 9 +++ pyproject.toml | 1 + toxw | 15 +++++ 9 files changed, 175 insertions(+), 102 deletions(-) delete mode 100755 ci-tools/bootstrap-user-python-support delete mode 100644 ci-tools/python-versions.sh delete mode 100755 ci-tools/tox-bootstrap create mode 100644 ci-tools/wrappers.sh create mode 100755 poetryw create mode 100755 toxw diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index ed326799..fb6653a7 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -1,19 +1,19 @@ # Setting up for development -* [Install poetry](https://python-poetry.org/docs/#installation) +* Ensure that `python3` points to a version of python >= 3.8 (`python3 --version` will tell you). If it does not, use [pyenv](https://github.com/pyenv/pyenv) to install a recent python version. -* If you want to maintain your own virtualenv, install pyenv and use pyenv virtualenv to create and manage one. Poetry will automatically find any active virtualenv and use that. +* There are two wrappers (`poetryw` and `toxw`) that install and run the correct versions of [poetry](https://python-poetry.org) and [tox](https://tox.wiki) for you; respectively. * Run poetry to install dependencies: ``` -poetry install +./poetryw install ``` * Run the development version of hunter using poetry: ``` -poetry run hunter ... +./poetryw run hunter ... ``` See the [poetry docs](https://python-poetry.org/docs) for more. @@ -21,13 +21,13 @@ See the [poetry docs](https://python-poetry.org/docs) for more. # Running tests ``` -poetry run pytest tests +./poetryw run pytest tests ``` ...or using [tox](https://tox.readthedocs.io/): ``` -ci-tools/tox-bootstrap +./toxw ``` # Linting and formatting @@ -35,12 +35,12 @@ ci-tools/tox-bootstrap Code-style is enforced using [black](https://black.readthedocs.io/). Linting is automatically applied when tox runs tests; if linting fails, you can fix it with: ``` -ci-tools/tox-bootstrap -e format +./toxw -e format ``` # Build a docker image ``` -ci-tools/tox-bootstrap -e docker-build +./toxw -e docker-build ``` diff --git a/ci-tools/bootstrap-user-python-support b/ci-tools/bootstrap-user-python-support deleted file mode 100755 index 4a27cdfe..00000000 --- a/ci-tools/bootstrap-user-python-support +++ /dev/null @@ -1,50 +0,0 @@ -#!/bin/bash -ex - -# Bootstrap pipx and then use it to install poetry, avoiding the use of -# `curl`ed scripts, and using specific versions (for both security and -# stability). - -function pip() -{ - command pip3 "$@" -} - -function installed() -{ - which "$1" >/dev/null 2>&1 -} - -thisdir="$(cd "$(dirname "$0")"; pwd)" -source "$thisdir/python-versions.sh" - -export PIPX_DEFAULT_PYTHON="$PYTHON" - -# Ensure ~/.local/bin is in the path; some OS's don't do this -PATH="$HOME/.local/bin:$PATH" - -# Because both pip install --user and pipx create a -# symlink at ~/.local/bin/pipx, we need to install -# pipx twice to make sure the symlink is correct -if ! installed pipx; then - # Install pipx in the user's global environment to ~/.local/bin/pipx - pip install --user pipx=="$PIPX_VERSION" - - # Use the pipx installed above to install pipx in a venv specific to - # pipx as ~/.local/bin/pipx - pipx install pipx - - # Uninstall pipx from the user's global environment; this deletes - # ~/.local/bin/pipx, so we have to restore it by... - pip uninstall --yes pipx - - # ...reinstalling pipx using pipx. - "$HOME/.local/pipx/venvs/pipx/bin/pipx" install --force pipx - - # Tell the shell to recalculate its command lookup hash table - hash -r -fi - -# Install poetry without `curl`ing -if ! installed poetry; then - pipx install poetry=="$POETRY_VERSION" -fi diff --git a/ci-tools/python-versions.sh b/ci-tools/python-versions.sh deleted file mode 100644 index fcb63796..00000000 --- a/ci-tools/python-versions.sh +++ /dev/null @@ -1,11 +0,0 @@ -# This file contains the versions of the tools used to bootstrap the python -# environment in CI. Python package dependencies should all live in -# pyproject.toml - -# shellcheck disable=SC2034 - -PYTHON="python3.8" - -PIPX_VERSION="0.16.1.0" -POETRY_VERSION="1.1.5" -TOX_VERSION="3.23.0" diff --git a/ci-tools/tox-bootstrap b/ci-tools/tox-bootstrap deleted file mode 100755 index 0e2d4139..00000000 --- a/ci-tools/tox-bootstrap +++ /dev/null @@ -1,28 +0,0 @@ -#!/bin/bash -e - -thisdir="$(cd "$(dirname "$0")"; pwd)" -source "$thisdir/python-versions.sh" - -pip_options="" - -if [[ -n "$TOX_BOOTSTRAP_QUIET" ]]; then - pip_options="--quiet" - function run() - { - "$@" - } -else - function run() - { - echo "$@" - "$@" - } -fi - - -run mkdir -p .tox -run "$PYTHON" -m venv .tox/bootstrap -run source .tox/bootstrap/bin/activate -run pip $pip_options install $pip_options --upgrade pip -run pip $pip_options install $pip_options "tox~=$TOX_VERSION" -run exec tox "$@" diff --git a/ci-tools/wrappers.sh b/ci-tools/wrappers.sh new file mode 100644 index 00000000..a84ccf2a --- /dev/null +++ b/ci-tools/wrappers.sh @@ -0,0 +1,65 @@ +# Support functions for bootstrapping python tools + +python=${PYTHON:-python3} + +# set -x would generate a lot of noise when we activate the venv, so +# we use this hand-crafted equivalent here: +run() +{ + echo "$@" 1>&2 + "$@" +} + +build_dir="$thisdir/build" +venvs_dir="$build_dir/venvs" +bin_dir="$build_dir/wrappers/bin" + +install_tool() +{ + tool="$1" + shift + + pip_spec="$1" + shift + + test -f "$bin_dir/$tool" && return + + run mkdir -p "$venvs_dir" "$bin_dir" + + venv="$venvs_dir/$tool" + + run "$python" -m venv "$venv" + + # Run in a subshell to prevent the activate/deactivate steps + # interfering with pyenv + ( + run source "$venv/bin/activate" + run "$python" -m pip install -qqq --upgrade pip + run "$python" -m pip install -qqq $pip_spec + run ln -fs "../../venvs/$tool/bin/$tool" "$bin_dir/$tool" + run deactivate + ) +} + +run_tool() +{ + tool="$1" + shift + + # Ensure that the tool has access to all the bootstrapped tools + PATH="$bin_dir:$PATH" + + exec "$bin_dir/$tool" "$@" +} + +install_and_run_tool() +{ + tool="$1" + shift + + pip_spec="$1" + shift + + install_tool "$tool" "$pip_spec" + run_tool "$tool" "$@" +} diff --git a/poetry.lock b/poetry.lock index 58326467..7afd71de 100644 --- a/poetry.lock +++ b/poetry.lock @@ -118,6 +118,14 @@ category = "main" optional = false python-versions = ">=3.5" +[[package]] +name = "distlib" +version = "0.3.4" +description = "Distribution utilities" +category = "dev" +optional = false +python-versions = "*" + [[package]] name = "expandvars" version = "0.6.5" @@ -126,6 +134,18 @@ category = "main" optional = false python-versions = "*" +[[package]] +name = "filelock" +version = "3.6.0" +description = "A platform independent file lock." +category = "dev" +optional = false +python-versions = ">=3.7" + +[package.extras] +docs = ["furo (>=2021.8.17b43)", "sphinx (>=4.1)", "sphinx-autodoc-typehints (>=1.12)"] +testing = ["covdefaults (>=1.2.0)", "coverage (>=4)", "pytest (>=4)", "pytest-cov", "pytest-timeout (>=1.4.2)"] + [[package]] name = "idna" version = "3.3" @@ -431,6 +451,28 @@ category = "main" optional = false python-versions = ">=3.7" +[[package]] +name = "tox" +version = "3.25.0" +description = "tox is a generic virtualenv management and test command line tool" +category = "dev" +optional = false +python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*,>=2.7" + +[package.dependencies] +colorama = {version = ">=0.4.1", markers = "platform_system == \"Windows\""} +filelock = ">=3.0.0" +packaging = ">=14" +pluggy = ">=0.12.0" +py = ">=1.4.17" +six = ">=1.14.0" +toml = ">=0.9.4" +virtualenv = ">=16.0.0,<20.0.0 || >20.0.0,<20.0.1 || >20.0.1,<20.0.2 || >20.0.2,<20.0.3 || >20.0.3,<20.0.4 || >20.0.4,<20.0.5 || >20.0.5,<20.0.6 || >20.0.6,<20.0.7 || >20.0.7" + +[package.extras] +docs = ["pygments-github-lexers (>=0.0.5)", "sphinx (>=2.0.0)", "sphinxcontrib-autoprogram (>=0.1.5)", "towncrier (>=18.5.0)"] +testing = ["flaky (>=3.4.0)", "freezegun (>=0.3.11)", "pytest (>=4.0.0)", "pytest-cov (>=2.5.1)", "pytest-mock (>=1.10.0)", "pytest-randomly (>=1.0.0)", "psutil (>=5.6.1)", "pathlib2 (>=2.3.3)"] + [[package]] name = "typing-extensions" version = "3.10.0.2" @@ -492,10 +534,28 @@ six = ">=1.4.0" [package.extras] test = ["pytest (>=2.2.3)", "flake8 (>=2.4.0)", "isort (>=4.2.2)"] +[[package]] +name = "virtualenv" +version = "20.14.1" +description = "Virtual Python Environment builder" +category = "dev" +optional = false +python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*,>=2.7" + +[package.dependencies] +distlib = ">=0.3.1,<1" +filelock = ">=3.2,<4" +platformdirs = ">=2,<3" +six = ">=1.9.0,<2" + +[package.extras] +docs = ["proselint (>=0.10.2)", "sphinx (>=3)", "sphinx-argparse (>=0.2.5)", "sphinx-rtd-theme (>=0.4.3)", "towncrier (>=21.3)"] +testing = ["coverage (>=4)", "coverage-enable-subprocess (>=1)", "flaky (>=3)", "pytest (>=4)", "pytest-env (>=0.6.2)", "pytest-freezegun (>=0.4.1)", "pytest-mock (>=2)", "pytest-randomly (>=1)", "pytest-timeout (>=1)", "packaging (>=20.0)"] + [metadata] lock-version = "1.1" python-versions = "^3.8" -content-hash = "bbd96ec5ca0f566795f5603ec877c05faaadf87131a847c38d2c77697b260d10" +content-hash = "f5c31fcf9a61a3166ef805b2e50aa5ca2918526cf131aab407244d7671f546f1" [metadata.files] atomicwrites = [ @@ -573,10 +633,18 @@ decorator = [ {file = "decorator-5.1.1-py3-none-any.whl", hash = "sha256:b8c3f85900b9dc423225913c5aace94729fe1fa9763b38939a95226f02d37186"}, {file = "decorator-5.1.1.tar.gz", hash = "sha256:637996211036b6385ef91435e4fae22989472f9d571faba8927ba8253acbc330"}, ] +distlib = [ + {file = "distlib-0.3.4-py2.py3-none-any.whl", hash = "sha256:6564fe0a8f51e734df6333d08b8b94d4ea8ee6b99b5ed50613f731fd4089f34b"}, + {file = "distlib-0.3.4.zip", hash = "sha256:e4b58818180336dc9c529bfb9a0b58728ffc09ad92027a3f30b7cd91e3458579"}, +] expandvars = [ {file = "expandvars-0.6.5-py2.py3-none-any.whl", hash = "sha256:1cba07c76da50c2528cf8d70c78e98a62ec3e9cd279ba80fa6b136330f4ad8d3"}, {file = "expandvars-0.6.5.tar.gz", hash = "sha256:1093a7a58ee5087c279a4cc5fd5758ad9c858c2f5bee256927b18b26a6ecc9d3"}, ] +filelock = [ + {file = "filelock-3.6.0-py3-none-any.whl", hash = "sha256:f8314284bfffbdcfa0ff3d7992b023d4c628ced6feb957351d4c48d059f56bc0"}, + {file = "filelock-3.6.0.tar.gz", hash = "sha256:9cd540a9352e432c7246a48fe4e8712b10acb1df2ad1f30e8c070b82ae1fed85"}, +] idna = [ {file = "idna-3.3-py3-none-any.whl", hash = "sha256:84d9dd047ffa80596e0f246e2eab0b391788b0503584e8945f2368256d2735ff"}, {file = "idna-3.3.tar.gz", hash = "sha256:9d643ff0a55b762d5cdb124b8eaa99c66322e2157b69160bc32796e824360e6d"}, @@ -749,10 +817,6 @@ requests = [ {file = "ruamel.yaml-0.17.21.tar.gz", hash = "sha256:8b7ce697a2f212752a35c1ac414471dc16c424c9573be4926b56ff3f5d23b7af"}, ] "ruamel.yaml.clib" = [ - {file = "ruamel.yaml.clib-0.2.6-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:6e7be2c5bcb297f5b82fee9c665eb2eb7001d1050deaba8471842979293a80b0"}, - {file = "ruamel.yaml.clib-0.2.6-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_24_x86_64.whl", hash = "sha256:221eca6f35076c6ae472a531afa1c223b9c29377e62936f61bc8e6e8bdc5f9e7"}, - {file = "ruamel.yaml.clib-0.2.6-cp310-cp310-win32.whl", hash = "sha256:1070ba9dd7f9370d0513d649420c3b362ac2d687fe78c6e888f5b12bf8bc7bee"}, - {file = "ruamel.yaml.clib-0.2.6-cp310-cp310-win_amd64.whl", hash = "sha256:77df077d32921ad46f34816a9a16e6356d8100374579bc35e15bab5d4e9377de"}, {file = "ruamel.yaml.clib-0.2.6-cp35-cp35m-macosx_10_6_intel.whl", hash = "sha256:cfdb9389d888c5b74af297e51ce357b800dd844898af9d4a547ffc143fa56751"}, {file = "ruamel.yaml.clib-0.2.6-cp35-cp35m-manylinux1_x86_64.whl", hash = "sha256:7b2927e92feb51d830f531de4ccb11b320255ee95e791022555971c466af4527"}, {file = "ruamel.yaml.clib-0.2.6-cp35-cp35m-win32.whl", hash = "sha256:ada3f400d9923a190ea8b59c8f60680c4ef8a4b0dfae134d2f2ff68429adfab5"}, @@ -825,6 +889,10 @@ tomli = [ {file = "tomli-2.0.1-py3-none-any.whl", hash = "sha256:939de3e7a6161af0c887ef91b7d41a53e7c5a1ca976325f429cb46ea9bc30ecc"}, {file = "tomli-2.0.1.tar.gz", hash = "sha256:de526c12914f0c550d15924c62d72abc48d6fe7364aa87328337a31007fe8a4f"}, ] +tox = [ + {file = "tox-3.25.0-py2.py3-none-any.whl", hash = "sha256:0805727eb4d6b049de304977dfc9ce315a1938e6619c3ab9f38682bb04662a5a"}, + {file = "tox-3.25.0.tar.gz", hash = "sha256:37888f3092aa4e9f835fc8cc6dadbaaa0782651c41ef359e3a5743fcb0308160"}, +] typing-extensions = [ {file = "typing_extensions-3.10.0.2-py2-none-any.whl", hash = "sha256:d8226d10bc02a29bcc81df19a26e56a9647f8b0a6d4a83924139f4a8b01f17b7"}, {file = "typing_extensions-3.10.0.2-py3-none-any.whl", hash = "sha256:f1d25edafde516b146ecd0613dabcc61409817af4766fbbcfb8d1ad4ec441a34"}, @@ -846,3 +914,7 @@ validators = [ {file = "validators-0.18.2-py3-none-any.whl", hash = "sha256:0143dcca8a386498edaf5780cbd5960da1a4c85e0719f3ee5c9b41249c4fefbd"}, {file = "validators-0.18.2.tar.gz", hash = "sha256:37cd9a9213278538ad09b5b9f9134266e7c226ab1fede1d500e29e0a8fbb9ea6"}, ] +virtualenv = [ + {file = "virtualenv-20.14.1-py2.py3-none-any.whl", hash = "sha256:e617f16e25b42eb4f6e74096b9c9e37713cf10bf30168fb4a739f3fa8f898a3a"}, + {file = "virtualenv-20.14.1.tar.gz", hash = "sha256:ef589a79795589aada0c1c5b319486797c03b67ac3984c48c669c0e4f50df3a5"}, +] diff --git a/poetryw b/poetryw new file mode 100755 index 00000000..61fc2113 --- /dev/null +++ b/poetryw @@ -0,0 +1,9 @@ +#!/bin/bash -e + +thisdir="$(cd "$(dirname "$0")" && pwd)" + +POETRY_VERSION="${POETRY_VERSION:-1.1.13}" + +source "ci-tools/wrappers.sh" + +install_and_run_tool poetry "poetry==$POETRY_VERSION" "$@" diff --git a/pyproject.toml b/pyproject.toml index 7125d2a3..81446342 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -22,6 +22,7 @@ slack-sdk = "^3.4.2" [tool.poetry.dev-dependencies] pytest = "^6.2.2" pytz = "2021.1" +tox = "^3.25.0" [tool.pytest.ini_options] filterwarnings = [ diff --git a/toxw b/toxw new file mode 100755 index 00000000..7de93990 --- /dev/null +++ b/toxw @@ -0,0 +1,15 @@ +#!/bin/bash -e + +thisdir="$(cd "$(dirname "$0")" && pwd)" + +source "$thisdir/ci-tools/wrappers.sh" + +requirements="$build_dir/requirements-tox.txt" + +test -f $requirements || ( + mkdir -p "$build_dir" + run "$thisdir/poetryw" export --verbose --dev --without-hashes | \ + grep -E -o 'tox==[0-9\.]+' > "$requirements" +) + +install_and_run_tool tox "-r$requirements" "$@" From 5dcc5ea52b304cf8f6a56077d5821c3951437f32 Mon Sep 17 00:00:00 2001 From: Guy Bolton King Date: Wed, 20 Apr 2022 13:04:26 +0100 Subject: [PATCH 2/6] Simplify tox.ini and use poetryw to install deps --- tox.ini | 26 +++++++++++--------------- 1 file changed, 11 insertions(+), 15 deletions(-) diff --git a/tox.ini b/tox.ini index 1e9b4b08..e561a220 100644 --- a/tox.ini +++ b/tox.ini @@ -1,10 +1,7 @@ [tox] -isolated_build = true -basepython = python3.8 -ignore_basepython_conflict = true - -[tox:jenkins] -envlist = ci +skipsdist = true +toxworkdir = {toxinidir}/build/.tox +envlist = test # This is the default test environment; see # https://tox.readthedocs.io/en/latest/config.html#generating-environments-conditional-settings @@ -16,7 +13,7 @@ envlist = ci [testenv] skip_install = true allowlist_externals = - poetry + poetryw mkdir passenv = SSH_AUTH_SOCK @@ -26,14 +23,12 @@ setenv = POETRY_OPTS = -v PYTEST_OPTS = - # When running in CI, log test results so that jenkins can publish them - ci: PYTEST_OPTS = --junit-prefix="{envname}.pytest" --junitxml={env:BUILD_DIR}/{envname}.pytest.results.xml - # Linting should be quiet and fast lint: BLACK_OPTS = --quiet --fast lint: POETRY_OPTS = --quiet --no-root +commands_pre = + ./poetryw install {env:POETRY_OPTS} commands = - poetry install {env:POETRY_OPTS} black {env:BLACK_OPTS} --check --diff . !lint: mkdir -p {env:BUILD_DIR} !lint: pytest --verbose {env:PYTEST_OPTS} {posargs} tests @@ -41,11 +36,7 @@ commands = # The format environment should fix any errors detected by the lint # environment [testenv:format] -skip_install = true -allowlist_externals = - poetry commands = - poetry install -v --no-root black . # docker-build and docker-push environments; docker-push requires @@ -72,3 +63,8 @@ commands = push: docker login -u {env:DOCKER_REGISTRY_CREDS_USR} -p {env:DOCKER_REGISTRY_CREDS_PSW} {env:DOCKER_REGISTRY} push: docker image push {env:DOCKER_REGISTRY}/{env:DOCKER_PROJECT}:{env:RELEASE_VERSION} push: docker image push {env:DOCKER_REGISTRY}/{env:DOCKER_PROJECT}:latest + +[pytest] +# Ensure we do not include BUILD_DIR by explicitly specifying where to search for tests +testpaths = + tests From 0fa9d323c64182b92c91f1119c3553814ea364ce Mon Sep 17 00:00:00 2001 From: Guy Bolton King Date: Wed, 20 Apr 2022 13:38:30 +0100 Subject: [PATCH 3/6] Add flake8 to tox Also fix minor flake8 errors in util.py and config.py --- hunter/config.py | 2 +- hunter/util.py | 5 ++-- poetry.lock | 69 ++++++++++++++++++++++++++++++++++++++++++------ pyproject.toml | 3 ++- tox.ini | 11 ++++++++ 5 files changed, 77 insertions(+), 13 deletions(-) diff --git a/hunter/config.py b/hunter/config.py index e1a96c55..323acde9 100644 --- a/hunter/config.py +++ b/hunter/config.py @@ -82,7 +82,7 @@ def load_config_from(config_file: Path) -> Config: yaml = YAML(typ="safe") config = yaml.load(content) """ - if Grafana configs not explicitly set in yaml file, default to same as Graphite + if Grafana configs not explicitly set in yaml file, default to same as Graphite server at port 3000 """ graphite_config = None diff --git a/hunter/util.py b/hunter/util.py index 86fdf2b0..1febe76d 100644 --- a/hunter/util.py +++ b/hunter/util.py @@ -1,4 +1,3 @@ -import datetime import math import re import sys @@ -61,8 +60,8 @@ def merge_sorted(lists: List[List[T]]) -> List[T]: - output: [0, 1, 2, 3, 4, 5] """ output = set() - for l in lists: - for item in l: + for list_ in lists: + for item in list_: output.add(item) output = list(output) diff --git a/poetry.lock b/poetry.lock index 7afd71de..e418936c 100644 --- a/poetry.lock +++ b/poetry.lock @@ -35,7 +35,7 @@ tzdata = ["tzdata"] name = "black" version = "22.3.0" description = "The uncompromising code formatter." -category = "main" +category = "dev" optional = false python-versions = ">=3.6.2" @@ -76,7 +76,7 @@ unicode_backport = ["unicodedata2"] name = "click" version = "8.1.2" description = "Composable command line interface toolkit" -category = "main" +category = "dev" optional = false python-versions = ">=3.7" @@ -87,7 +87,7 @@ colorama = {version = "*", markers = "platform_system == \"Windows\""} name = "colorama" version = "0.4.4" description = "Cross-platform colored terminal text." -category = "main" +category = "dev" optional = false python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*" @@ -146,6 +146,19 @@ python-versions = ">=3.7" docs = ["furo (>=2021.8.17b43)", "sphinx (>=4.1)", "sphinx-autodoc-typehints (>=1.12)"] testing = ["covdefaults (>=1.2.0)", "coverage (>=4)", "pytest (>=4)", "pytest-cov", "pytest-timeout (>=1.4.2)"] +[[package]] +name = "flake8" +version = "4.0.1" +description = "the modular source code checker: pep8 pyflakes and co" +category = "dev" +optional = false +python-versions = ">=3.6" + +[package.dependencies] +mccabe = ">=0.6.0,<0.7.0" +pycodestyle = ">=2.8.0,<2.9.0" +pyflakes = ">=2.4.0,<2.5.0" + [[package]] name = "idna" version = "3.3" @@ -162,6 +175,14 @@ category = "dev" optional = false python-versions = "*" +[[package]] +name = "mccabe" +version = "0.6.1" +description = "McCabe checker, plugin for flake8" +category = "dev" +optional = false +python-versions = "*" + [[package]] name = "more-itertools" version = "8.12.0" @@ -174,7 +195,7 @@ python-versions = ">=3.5" name = "mypy-extensions" version = "0.4.3" description = "Experimental type system extensions for programs checked with the mypy typechecker." -category = "main" +category = "dev" optional = false python-versions = "*" @@ -201,7 +222,7 @@ pyparsing = ">=2.0.2,<3.0.5 || >3.0.5" name = "pathspec" version = "0.9.0" description = "Utility library for gitignore style pattern matching of file paths." -category = "main" +category = "dev" optional = false python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*,>=2.7" @@ -209,7 +230,7 @@ python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*,>=2.7" name = "platformdirs" version = "2.5.2" description = "A small Python module for determining appropriate platform-specific dirs, e.g. a \"user data dir\"." -category = "main" +category = "dev" optional = false python-versions = ">=3.7" @@ -237,6 +258,22 @@ category = "dev" optional = false python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*" +[[package]] +name = "pycodestyle" +version = "2.8.0" +description = "Python style guide checker" +category = "dev" +optional = false +python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*" + +[[package]] +name = "pyflakes" +version = "2.4.0" +description = "passive checker of Python programs" +category = "dev" +optional = false +python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" + [[package]] name = "pyparsing" version = "3.0.8" @@ -447,7 +484,7 @@ python-versions = ">=2.6, !=3.0.*, !=3.1.*, !=3.2.*" name = "tomli" version = "2.0.1" description = "A lil' TOML parser" -category = "main" +category = "dev" optional = false python-versions = ">=3.7" @@ -555,7 +592,7 @@ testing = ["coverage (>=4)", "coverage-enable-subprocess (>=1)", "flaky (>=3)", [metadata] lock-version = "1.1" python-versions = "^3.8" -content-hash = "f5c31fcf9a61a3166ef805b2e50aa5ca2918526cf131aab407244d7671f546f1" +content-hash = "1fd83a138833ecdb2081f0ae4b5cc81a9587544cc0057d9dff075637093d044f" [metadata.files] atomicwrites = [ @@ -645,6 +682,10 @@ filelock = [ {file = "filelock-3.6.0-py3-none-any.whl", hash = "sha256:f8314284bfffbdcfa0ff3d7992b023d4c628ced6feb957351d4c48d059f56bc0"}, {file = "filelock-3.6.0.tar.gz", hash = "sha256:9cd540a9352e432c7246a48fe4e8712b10acb1df2ad1f30e8c070b82ae1fed85"}, ] +flake8 = [ + {file = "flake8-4.0.1-py2.py3-none-any.whl", hash = "sha256:479b1304f72536a55948cb40a32dce8bb0ffe3501e26eaf292c7e60eb5e0428d"}, + {file = "flake8-4.0.1.tar.gz", hash = "sha256:806e034dda44114815e23c16ef92f95c91e4c71100ff52813adf7132a6ad870d"}, +] idna = [ {file = "idna-3.3-py3-none-any.whl", hash = "sha256:84d9dd047ffa80596e0f246e2eab0b391788b0503584e8945f2368256d2735ff"}, {file = "idna-3.3.tar.gz", hash = "sha256:9d643ff0a55b762d5cdb124b8eaa99c66322e2157b69160bc32796e824360e6d"}, @@ -653,6 +694,10 @@ iniconfig = [ {file = "iniconfig-1.1.1-py2.py3-none-any.whl", hash = "sha256:011e24c64b7f47f6ebd835bb12a743f2fbe9a26d4cecaa7f53bc4f35ee9da8b3"}, {file = "iniconfig-1.1.1.tar.gz", hash = "sha256:bc3af051d7d14b2ee5ef9969666def0cd1a000e121eaea580d4a313df4b37f32"}, ] +mccabe = [ + {file = "mccabe-0.6.1-py2.py3-none-any.whl", hash = "sha256:ab8a6258860da4b6677da4bd2fe5dc2c659cff31b3ee4f7f5d64e79735b80d42"}, + {file = "mccabe-0.6.1.tar.gz", hash = "sha256:dd8d182285a0fe56bace7f45b5e7d1a6ebcbf524e8f3bd87eb0f125271b8831f"}, +] more-itertools = [ {file = "more-itertools-8.12.0.tar.gz", hash = "sha256:7dc6ad46f05f545f900dd59e8dfb4e84a4827b97b3cfecb175ea0c7d247f6064"}, {file = "more_itertools-8.12.0-py3-none-any.whl", hash = "sha256:43e6dd9942dffd72661a2c4ef383ad7da1e6a3e968a927ad7a6083ab410a688b"}, @@ -709,6 +754,14 @@ py = [ {file = "py-1.11.0-py2.py3-none-any.whl", hash = "sha256:607c53218732647dff4acdfcd50cb62615cedf612e72d1724fb1a0cc6405b378"}, {file = "py-1.11.0.tar.gz", hash = "sha256:51c75c4126074b472f746a24399ad32f6053d1b34b68d2fa41e558e6f4a98719"}, ] +pycodestyle = [ + {file = "pycodestyle-2.8.0-py2.py3-none-any.whl", hash = "sha256:720f8b39dde8b293825e7ff02c475f3077124006db4f440dcbc9a20b76548a20"}, + {file = "pycodestyle-2.8.0.tar.gz", hash = "sha256:eddd5847ef438ea1c7870ca7eb78a9d47ce0cdb4851a5523949f2601d0cbbe7f"}, +] +pyflakes = [ + {file = "pyflakes-2.4.0-py2.py3-none-any.whl", hash = "sha256:3bb3a3f256f4b7968c9c788781e4ff07dce46bdf12339dcda61053375426ee2e"}, + {file = "pyflakes-2.4.0.tar.gz", hash = "sha256:05a85c2872edf37a4ed30b0cce2f6093e1d0581f8c19d7393122da7e25b2b24c"}, +] pyparsing = [ {file = "pyparsing-3.0.8-py3-none-any.whl", hash = "sha256:ef7b523f6356f763771559412c0d7134753f037822dad1b16945b7b846f7ad06"}, {file = "pyparsing-3.0.8.tar.gz", hash = "sha256:7bf433498c016c4314268d95df76c81b842a4cb2b276fa3312cfb1e1d85f6954"}, diff --git a/pyproject.toml b/pyproject.toml index 81446342..2ac9d9fa 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -15,7 +15,6 @@ signal-processing-algorithms = "^1.3.2" requests = "^2.25.1" pystache = "^0.6.0" tabulate = "^0.8.7" -black = "^22.3.0" validators = "^0.18.2" slack-sdk = "^3.4.2" @@ -23,6 +22,8 @@ slack-sdk = "^3.4.2" pytest = "^6.2.2" pytz = "2021.1" tox = "^3.25.0" +black = "^22.3.0" +flake8 = "^4.0.1" [tool.pytest.ini_options] filterwarnings = [ diff --git a/tox.ini b/tox.ini index e561a220..8ba2c92e 100644 --- a/tox.ini +++ b/tox.ini @@ -20,16 +20,19 @@ passenv = setenv = BUILD_DIR = {toxinidir}/build/{envname} BLACK_OPTS = + FLAKE8_OPTS = --count --show-source --statistics POETRY_OPTS = -v PYTEST_OPTS = # Linting should be quiet and fast lint: BLACK_OPTS = --quiet --fast + lint: FLAKE8_OPTS = lint: POETRY_OPTS = --quiet --no-root commands_pre = ./poetryw install {env:POETRY_OPTS} commands = black {env:BLACK_OPTS} --check --diff . + flake8 {env:FLAKE8_OPTS} !lint: mkdir -p {env:BUILD_DIR} !lint: pytest --verbose {env:PYTEST_OPTS} {posargs} tests @@ -68,3 +71,11 @@ commands = # Ensure we do not include BUILD_DIR by explicitly specifying where to search for tests testpaths = tests + +[flake8] +extend_exclude = build +extend_ignore = + # Black compatibility; see https://black.readthedocs.io/en/stable/guides/using_black_with_other_tools.html#flake8 + E203 + # Let black determine whether a line is too long + E501 From 133b140456be29e42e4523b4937c670119df767c Mon Sep 17 00:00:00 2001 From: Guy Bolton King Date: Wed, 20 Apr 2022 14:03:47 +0100 Subject: [PATCH 4/6] Use autoflake and isort to optimize imports --- hunter/analysis.py | 3 +-- hunter/csv_options.py | 1 - hunter/graphite.py | 2 +- hunter/importer.py | 12 +++++------ hunter/main.py | 18 +++++++---------- hunter/report.py | 2 +- hunter/series.py | 6 +++--- hunter/slack.py | 2 +- hunter/util.py | 4 ++-- poetry.lock | 34 +++++++++++++++++++++++++++++++- pyproject.toml | 5 +++++ tests/analysis_test.py | 2 +- tests/config_test.py | 2 +- tests/importer_test.py | 2 +- tests/report_test.py | 2 +- tests/series_test.py | 2 +- tests/slack_notification_test.py | 4 ++-- tests/util_test.py | 8 ++++---- tox.ini | 5 +++++ 19 files changed, 76 insertions(+), 40 deletions(-) diff --git a/hunter/analysis.py b/hunter/analysis.py index 69380933..faf1fc94 100644 --- a/hunter/analysis.py +++ b/hunter/analysis.py @@ -1,6 +1,5 @@ from dataclasses import dataclass -from typing import Iterable, Reversible -from typing import List +from typing import Iterable, List, Reversible import numpy as np from scipy.stats import ttest_ind_from_stats diff --git a/hunter/csv_options.py b/hunter/csv_options.py index c26782e6..c3833476 100644 --- a/hunter/csv_options.py +++ b/hunter/csv_options.py @@ -1,5 +1,4 @@ import enum - from dataclasses import dataclass diff --git a/hunter/graphite.py b/hunter/graphite.py index 2ffb33bd..5d3a9a26 100644 --- a/hunter/graphite.py +++ b/hunter/graphite.py @@ -4,7 +4,7 @@ from dataclasses import dataclass from datetime import datetime from logging import info -from typing import Dict, List, Optional, Iterable +from typing import Dict, Iterable, List, Optional from hunter.data_selector import DataSelector from hunter.util import parse_datetime diff --git a/hunter/importer.py b/hunter/importer.py index 7caa71bd..f11392cd 100644 --- a/hunter/importer.py +++ b/hunter/importer.py @@ -4,24 +4,24 @@ from dataclasses import dataclass from datetime import datetime, timedelta from pathlib import Path -from typing import List, Optional, Dict +from typing import Dict, List, Optional from hunter.config import Config from hunter.data_selector import DataSelector from hunter.graphite import DataPoint, Graphite, GraphiteError -from hunter.series import Series, Metric +from hunter.series import Metric, Series from hunter.test_config import ( + CsvMetric, CsvTestConfig, - TestConfig, GraphiteTestConfig, - CsvMetric, HistoStatTestConfig, + TestConfig, ) from hunter.util import ( - merge_sorted, - parse_datetime, DateFormatError, format_timestamp, + merge_sorted, + parse_datetime, resolution, round, ) diff --git a/hunter/main.py b/hunter/main.py index b663478e..6f046815 100644 --- a/hunter/main.py +++ b/hunter/main.py @@ -4,27 +4,23 @@ import sys from dataclasses import dataclass from datetime import datetime, timedelta -from typing import Dict, Optional, List +from typing import Dict, List, Optional import pytz from slack_sdk import WebClient from hunter import config from hunter.attributes import get_back_links -from hunter.config import ConfigError, Config +from hunter.config import Config, ConfigError from hunter.data_selector import DataSelector -from hunter.grafana import GrafanaError, Grafana, Annotation +from hunter.grafana import Annotation, Grafana, GrafanaError from hunter.graphite import GraphiteError from hunter.importer import DataImportError, Importers from hunter.report import Report, ReportType -from hunter.series import ( - AnalysisOptions, - compare, - AnalyzedSeries, -) -from hunter.slack import SlackNotifier, NotificationError -from hunter.test_config import TestConfigError, TestConfig, GraphiteTestConfig -from hunter.util import parse_datetime, DateFormatError, interpolate +from hunter.series import AnalysisOptions, AnalyzedSeries, compare +from hunter.slack import NotificationError, SlackNotifier +from hunter.test_config import GraphiteTestConfig, TestConfig, TestConfigError +from hunter.util import DateFormatError, interpolate, parse_datetime @dataclass diff --git a/hunter/report.py b/hunter/report.py index 58a84b0a..f4838c79 100644 --- a/hunter/report.py +++ b/hunter/report.py @@ -4,7 +4,7 @@ from tabulate import tabulate -from hunter.series import Series, ChangePointGroup +from hunter.series import ChangePointGroup, Series from hunter.util import format_timestamp, insert_multiple, remove_common_prefix diff --git a/hunter/series.py b/hunter/series.py index 5ad0279e..66354757 100644 --- a/hunter/series.py +++ b/hunter/series.py @@ -2,15 +2,15 @@ from dataclasses import dataclass from datetime import datetime from itertools import groupby -from typing import Dict, List, Optional, Iterable +from typing import Dict, Iterable, List, Optional import numpy as np from hunter.analysis import ( - fill_missing, - compute_change_points, ComparativeStats, TTestSignificanceTester, + compute_change_points, + fill_missing, ) diff --git a/hunter/slack.py b/hunter/slack.py index 695395eb..649e4a09 100644 --- a/hunter/slack.py +++ b/hunter/slack.py @@ -7,7 +7,7 @@ from slack_sdk import WebClient from hunter.data_selector import DataSelector -from hunter.series import ChangePointGroup, AnalyzedSeries +from hunter.series import AnalyzedSeries, ChangePointGroup @dataclass diff --git a/hunter/util.py b/hunter/util.py index 1febe76d..bd4a3ec9 100644 --- a/hunter/util.py +++ b/hunter/util.py @@ -1,12 +1,12 @@ import math import re import sys -from collections import deque, OrderedDict +from collections import OrderedDict, deque from dataclasses import dataclass from datetime import datetime from functools import reduce from itertools import islice -from typing import List, TypeVar, Optional, Dict, Set +from typing import Dict, List, Optional, Set, TypeVar import dateparser from pytz import UTC diff --git a/poetry.lock b/poetry.lock index e418936c..e5f0f178 100644 --- a/poetry.lock +++ b/poetry.lock @@ -20,6 +20,17 @@ docs = ["furo", "sphinx", "zope.interface", "sphinx-notfound-page"] tests = ["coverage[toml] (>=5.0.2)", "hypothesis", "pympler", "pytest (>=4.3.0)", "six", "mypy", "pytest-mypy-plugins", "zope.interface", "cloudpickle"] tests_no_zope = ["coverage[toml] (>=5.0.2)", "hypothesis", "pympler", "pytest (>=4.3.0)", "six", "mypy", "pytest-mypy-plugins", "cloudpickle"] +[[package]] +name = "autoflake" +version = "1.4" +description = "Removes unused imports and unused variables" +category = "dev" +optional = false +python-versions = "*" + +[package.dependencies] +pyflakes = ">=1.1.0" + [[package]] name = "backports.zoneinfo" version = "0.2.1" @@ -175,6 +186,20 @@ category = "dev" optional = false python-versions = "*" +[[package]] +name = "isort" +version = "5.10.1" +description = "A Python utility / library to sort Python imports." +category = "dev" +optional = false +python-versions = ">=3.6.1,<4.0" + +[package.extras] +pipfile_deprecated_finder = ["pipreqs", "requirementslib"] +requirements_deprecated_finder = ["pipreqs", "pip-api"] +colors = ["colorama (>=0.4.3,<0.5.0)"] +plugins = ["setuptools"] + [[package]] name = "mccabe" version = "0.6.1" @@ -592,7 +617,7 @@ testing = ["coverage (>=4)", "coverage-enable-subprocess (>=1)", "flaky (>=3)", [metadata] lock-version = "1.1" python-versions = "^3.8" -content-hash = "1fd83a138833ecdb2081f0ae4b5cc81a9587544cc0057d9dff075637093d044f" +content-hash = "53e447e93d71f788116d3f8320cfa8f060ba67a6799b8829c68b8404adb1412e" [metadata.files] atomicwrites = [ @@ -603,6 +628,9 @@ attrs = [ {file = "attrs-21.4.0-py2.py3-none-any.whl", hash = "sha256:2d27e3784d7a565d36ab851fe94887c5eccd6a463168875832a1be79c82828b4"}, {file = "attrs-21.4.0.tar.gz", hash = "sha256:626ba8234211db98e869df76230a137c4c40a12d72445c45d5f5b716f076e2fd"}, ] +autoflake = [ + {file = "autoflake-1.4.tar.gz", hash = "sha256:61a353012cff6ab94ca062823d1fb2f692c4acda51c76ff83a8d77915fba51ea"}, +] "backports.zoneinfo" = [ {file = "backports.zoneinfo-0.2.1-cp36-cp36m-macosx_10_14_x86_64.whl", hash = "sha256:da6013fd84a690242c310d77ddb8441a559e9cb3d3d59ebac9aca1a57b2e18bc"}, {file = "backports.zoneinfo-0.2.1-cp36-cp36m-manylinux1_i686.whl", hash = "sha256:89a48c0d158a3cc3f654da4c2de1ceba85263fafb861b98b59040a5086259722"}, @@ -694,6 +722,10 @@ iniconfig = [ {file = "iniconfig-1.1.1-py2.py3-none-any.whl", hash = "sha256:011e24c64b7f47f6ebd835bb12a743f2fbe9a26d4cecaa7f53bc4f35ee9da8b3"}, {file = "iniconfig-1.1.1.tar.gz", hash = "sha256:bc3af051d7d14b2ee5ef9969666def0cd1a000e121eaea580d4a313df4b37f32"}, ] +isort = [ + {file = "isort-5.10.1-py3-none-any.whl", hash = "sha256:6f62d78e2f89b4500b080fe3a81690850cd254227f27f75c3a0c491a1f351ba7"}, + {file = "isort-5.10.1.tar.gz", hash = "sha256:e8443a5e7a020e9d7f97f1d7d9cd17c88bcb3bc7e218bf9cf5095fe550be2951"}, +] mccabe = [ {file = "mccabe-0.6.1-py2.py3-none-any.whl", hash = "sha256:ab8a6258860da4b6677da4bd2fe5dc2c659cff31b3ee4f7f5d64e79735b80d42"}, {file = "mccabe-0.6.1.tar.gz", hash = "sha256:dd8d182285a0fe56bace7f45b5e7d1a6ebcbf524e8f3bd87eb0f125271b8831f"}, diff --git a/pyproject.toml b/pyproject.toml index 2ac9d9fa..e30e77b3 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -24,6 +24,8 @@ pytz = "2021.1" tox = "^3.25.0" black = "^22.3.0" flake8 = "^4.0.1" +autoflake = "^1.4" +isort = "^5.10.1" [tool.pytest.ini_options] filterwarnings = [ @@ -37,6 +39,9 @@ hunter = 'hunter.main:main' [tool.black] line-length = 100 +[tool.isort] +profile = "black" + [build-system] requires = ["poetry-core>=1.0.0"] build-backend = "poetry.core.masonry.api" diff --git a/tests/analysis_test.py b/tests/analysis_test.py index d83722ed..28a65571 100644 --- a/tests/analysis_test.py +++ b/tests/analysis_test.py @@ -1,7 +1,7 @@ import numpy as np from signal_processing_algorithms.e_divisive.change_points import EDivisiveChangePoint -from hunter.analysis import fill_missing, compute_change_points, TTestSignificanceTester +from hunter.analysis import TTestSignificanceTester, compute_change_points, fill_missing def test_fill_missing(): diff --git a/tests/config_test.py b/tests/config_test.py index dbf260f6..ef5bfa57 100644 --- a/tests/config_test.py +++ b/tests/config_test.py @@ -1,7 +1,7 @@ from pathlib import Path from hunter.config import load_config_from -from hunter.test_config import GraphiteTestConfig, CsvTestConfig, HistoStatTestConfig +from hunter.test_config import CsvTestConfig, GraphiteTestConfig, HistoStatTestConfig def test_load_graphite_tests(): diff --git a/tests/importer_test.py b/tests/importer_test.py index 676f4e8b..fad2fa6b 100644 --- a/tests/importer_test.py +++ b/tests/importer_test.py @@ -5,7 +5,7 @@ from hunter.csv_options import CsvOptions from hunter.graphite import DataSelector from hunter.importer import CsvImporter, HistoStatImporter -from hunter.test_config import CsvTestConfig, CsvMetric, HistoStatTestConfig +from hunter.test_config import CsvMetric, CsvTestConfig, HistoStatTestConfig SAMPLE_CSV = "tests/resources/sample.csv" diff --git a/tests/report_test.py b/tests/report_test.py index fe15a9c7..b33d209f 100644 --- a/tests/report_test.py +++ b/tests/report_test.py @@ -3,7 +3,7 @@ import pytest from hunter.report import Report, ReportType -from hunter.series import Series, Metric +from hunter.series import Metric, Series @pytest.fixture(scope="module") diff --git a/tests/series_test.py b/tests/series_test.py index 70bc822e..0bc3f2af 100644 --- a/tests/series_test.py +++ b/tests/series_test.py @@ -1,7 +1,7 @@ import time from random import random -from hunter.series import Series, AnalysisOptions, compare, Metric +from hunter.series import AnalysisOptions, Metric, Series, compare def test_change_point_detection(): diff --git a/tests/slack_notification_test.py b/tests/slack_notification_test.py index a224c2d6..176e53c3 100644 --- a/tests/slack_notification_test.py +++ b/tests/slack_notification_test.py @@ -5,8 +5,8 @@ from dateutil import tz from hunter.data_selector import DataSelector -from hunter.series import Series, Metric -from hunter.slack import SlackNotifier, NotificationError +from hunter.series import Metric, Series +from hunter.slack import NotificationError, SlackNotifier NOTIFICATION_CHANNELS = ["a-channel", "b-channel"] diff --git a/tests/util_test.py b/tests/util_test.py index 63586bad..6433c601 100644 --- a/tests/util_test.py +++ b/tests/util_test.py @@ -1,11 +1,11 @@ from hunter.util import ( + insert_multiple, + interpolate, + merge_dict_list, + merge_dicts, merge_sorted, remove_common_prefix, - insert_multiple, sliding_window, - merge_dicts, - merge_dict_list, - interpolate, ) diff --git a/tox.ini b/tox.ini index 8ba2c92e..508c04c4 100644 --- a/tox.ini +++ b/tox.ini @@ -21,6 +21,7 @@ setenv = BUILD_DIR = {toxinidir}/build/{envname} BLACK_OPTS = FLAKE8_OPTS = --count --show-source --statistics + AUTOFLAKE_OPTS = --exclude build --recursive --remove-all-unused-imports POETRY_OPTS = -v PYTEST_OPTS = @@ -32,6 +33,8 @@ commands_pre = ./poetryw install {env:POETRY_OPTS} commands = black {env:BLACK_OPTS} --check --diff . + autoflake {env:AUTOFLAKE_OPTS} --check . + isort --check --diff . flake8 {env:FLAKE8_OPTS} !lint: mkdir -p {env:BUILD_DIR} !lint: pytest --verbose {env:PYTEST_OPTS} {posargs} tests @@ -41,6 +44,8 @@ commands = [testenv:format] commands = black . + autoflake {env:AUTOFLAKE_OPTS} --in-place . + isort . # docker-build and docker-push environments; docker-push requires # RELEASE_VERSION (x.y.z), DOCKER_REGISTRY, DOCKER_REGISTRY_CREDS_USR and From 3e61b1353a5c6198fca96024a9c9a660726058b8 Mon Sep 17 00:00:00 2001 From: Guy Bolton King Date: Wed, 20 Apr 2022 14:05:04 +0100 Subject: [PATCH 5/6] Make github actions use tox --- .github/workflows/python-app.yml | 22 +++++----------------- 1 file changed, 5 insertions(+), 17 deletions(-) diff --git a/.github/workflows/python-app.yml b/.github/workflows/python-app.yml index c1a8652b..04c0c655 100644 --- a/.github/workflows/python-app.yml +++ b/.github/workflows/python-app.yml @@ -16,23 +16,11 @@ jobs: steps: - uses: actions/checkout@v2 + - name: Set up Python 3.8 uses: actions/setup-python@v2 with: - python-version: 3.8 - - name: Install dependencies - run: | - python -m pip install --upgrade pip - pip install poetry flake8 pytest - poetry install - if [ -f requirements.txt ]; then pip install -r requirements.txt; fi - - name: Lint with flake8 - run: | - # stop the build if there are Python syntax errors or undefined names - flake8 . --count --select=E9,F63,F7,F82 --show-source --statistics - # exit-zero treats all errors as warnings. The GitHub editor is 127 chars wide - # Black declares E203 is not PEP8 compliant: https://github.com/psf/black/issues/315#issuecomment-395457972 - flake8 . --count --ignore=E203 --exit-zero --max-complexity=10 --max-line-length=127 --statistics - - name: Test with pytest - run: | - poetry run pytest tests + python-version: 3.8.x + + - name: Run CI + run: ./toxw From 8b044a11962dffdf6e75a5cecb8a91aeaa7e12ef Mon Sep 17 00:00:00 2001 From: Guy Bolton King Date: Thu, 21 Apr 2022 10:02:38 +0100 Subject: [PATCH 6/6] Minor documentation improvements --- CONTRIBUTING.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index fb6653a7..e6af35ab 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -1,8 +1,8 @@ # Setting up for development -* Ensure that `python3` points to a version of python >= 3.8 (`python3 --version` will tell you). If it does not, use [pyenv](https://github.com/pyenv/pyenv) to install a recent python version. +* Ensure that `python3` points to a version of python >= 3.8 (`python3 --version` will tell you). If it does not, use [pyenv](https://github.com/pyenv/pyenv) to both install a recent python version and make it your current python. -* There are two wrappers (`poetryw` and `toxw`) that install and run the correct versions of [poetry](https://python-poetry.org) and [tox](https://tox.wiki) for you; respectively. +* There are two wrappers (`poetryw` and `toxw`) that install and run the correct versions of [poetry](https://python-poetry.org) and [tox](https://tox.wiki) for you. * Run poetry to install dependencies: @@ -21,7 +21,7 @@ See the [poetry docs](https://python-poetry.org/docs) for more. # Running tests ``` -./poetryw run pytest tests +./poetryw run pytest ``` ...or using [tox](https://tox.readthedocs.io/): @@ -32,7 +32,7 @@ See the [poetry docs](https://python-poetry.org/docs) for more. # Linting and formatting -Code-style is enforced using [black](https://black.readthedocs.io/). Linting is automatically applied when tox runs tests; if linting fails, you can fix it with: +Code-style is enforced using [black](https://black.readthedocs.io/) and [flake8](https://flake8.pycqa.org/); import optimisation is handled by [isort](https://pycqa.github.io/isort/) and [autoflake](https://pypi.org/project/autoflake/). Linting is automatically applied when tox runs tests; if linting fails, you can fix trivial problems with: ``` ./toxw -e format