test: Add skyline-config unit test

1. Add skyline-config unit test case and tools
2. Update immutables package type annotation
3. Adjust get_config_path function

Change-Id: Idc70ac164247c0d9cd5135f4e5bbef3994d05f22
This commit is contained in:
Gao Hanxiang 2021-09-13 09:11:23 -04:00 committed by hanxiang gao
parent 1d14b4067c
commit c81b6e11d2
11 changed files with 1014 additions and 123 deletions

View File

@ -1,4 +1,5 @@
PYTHON ?= python3
PY_FILES := $(shell git ls-files -- *.py | xargs)
.PHONY: all
@ -24,24 +25,24 @@ package:
.PHONY: fmt
fmt:
poetry run isort $$(git ls-files -- **/*.py)
poetry run black --config ../../pyproject.toml $$(git ls-files -- **/*.py)
poetry run add-trailing-comma --py36-plus --exit-zero-even-if-changed $$(git ls-files -- **/*.py)
poetry run isort $(PY_FILES)
poetry run black --config ../../pyproject.toml $(PY_FILES)
poetry run add-trailing-comma --py36-plus --exit-zero-even-if-changed $(PY_FILES)
.PHONY: lint
lint:
poetry run mypy --config-file=../../mypy.ini $$(git ls-files -- **/*.py)
poetry run isort --check-only --diff $$(git ls-files -- **/*.py)
poetry run black --check --diff --color --config ../../pyproject.toml $$(git ls-files -- **/*.py)
poetry run flake8 $$(git ls-files -- **/*.py)
poetry run mypy --strict --config-file=../../mypy.ini $(PY_FILES)
poetry run isort --check-only --diff $(PY_FILES)
poetry run black --check --diff --color --config ../../pyproject.toml $(PY_FILES)
poetry run flake8 --config ../../.flake8 $(PY_FILES)
.PHONY: test
test:
echo TODO
poetry run pytest
.PHONY: clean
clean:
rm -rf .venv dist
rm -rf .venv dist htmlcov .coverage

View File

@ -77,6 +77,17 @@ category = "dev"
optional = false
python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*"
[[package]]
name = "coverage"
version = "5.5"
description = "Code coverage measurement for Python"
category = "dev"
optional = false
python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*, <4"
[package.extras]
toml = ["toml"]
[[package]]
name = "execnet"
version = "1.9.0"
@ -142,6 +153,14 @@ category = "dev"
optional = false
python-versions = "*"
[[package]]
name = "mimesis"
version = "4.1.3"
description = "Mimesis: fake data generator."
category = "dev"
optional = false
python-versions = "*"
[[package]]
name = "mypy"
version = "0.910"
@ -188,7 +207,7 @@ python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*,>=2.7"
[[package]]
name = "platformdirs"
version = "2.3.0"
version = "2.4.0"
description = "A small Python module for determining appropriate platform-specific dirs, e.g. a \"user data dir\"."
category = "dev"
optional = false
@ -210,17 +229,6 @@ python-versions = ">=3.6"
dev = ["pre-commit", "tox"]
testing = ["pytest", "pytest-benchmark"]
[[package]]
name = "psutil"
version = "5.8.0"
description = "Cross-platform lib for process and system monitoring in Python."
category = "dev"
optional = false
python-versions = ">=2.6, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*"
[package.extras]
test = ["ipaddress", "mock", "unittest2", "enum34", "pywin32", "wmi"]
[[package]]
name = "py"
version = "1.10.0"
@ -289,6 +297,22 @@ toml = "*"
[package.extras]
testing = ["argcomplete", "hypothesis (>=3.56)", "mock", "nose", "requests", "xmlschema"]
[[package]]
name = "pytest-cov"
version = "2.12.1"
description = "Pytest plugin for measuring coverage."
category = "dev"
optional = false
python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*"
[package.dependencies]
coverage = ">=5.2.1"
pytest = ">=4.6"
toml = "*"
[package.extras]
testing = ["fields", "hunter", "process-tests", "six", "pytest-xdist", "virtualenv"]
[[package]]
name = "pytest-forked"
version = "1.3.0"
@ -301,6 +325,29 @@ python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*"
py = "*"
pytest = ">=3.10"
[[package]]
name = "pytest-html"
version = "3.1.1"
description = "pytest plugin for generating HTML reports"
category = "dev"
optional = false
python-versions = ">=3.6"
[package.dependencies]
pytest = ">=5.0,<6.0.0 || >6.0.0"
pytest-metadata = "*"
[[package]]
name = "pytest-metadata"
version = "1.11.0"
description = "pytest plugin for test session metadata"
category = "dev"
optional = false
python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*, !=3.5.*"
[package.dependencies]
pytest = ">=2.9.0"
[[package]]
name = "pytest-xdist"
version = "2.4.0"
@ -311,7 +358,6 @@ python-versions = ">=3.6"
[package.dependencies]
execnet = ">=1.1"
psutil = {version = ">=3.0", optional = true, markers = "extra == \"psutil\""}
pytest = ">=6.0.0"
pytest-forked = "*"
@ -330,7 +376,7 @@ python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*, !=3.5.*"
[[package]]
name = "regex"
version = "2021.8.28"
version = "2021.9.24"
description = "Alternative regular expression module, to replace re."
category = "dev"
optional = false
@ -379,7 +425,7 @@ python-versions = "*"
[metadata]
lock-version = "1.1"
python-versions = "^3.8"
content-hash = "3d8e122d2e4fc549634018994b5df61bb57951291f33bfde5ed2372948be9aec"
content-hash = "e14add76d79d49759f5ec17e83ff7b71899bd6c13303b9acbf8c55ed57db7152"
[metadata.files]
add-trailing-comma = [
@ -406,6 +452,60 @@ colorama = [
{file = "colorama-0.4.4-py2.py3-none-any.whl", hash = "sha256:9f47eda37229f68eee03b24b9748937c7dc3868f906e8ba69fbcbdd3bc5dc3e2"},
{file = "colorama-0.4.4.tar.gz", hash = "sha256:5941b2b48a20143d2267e95b1c2a7603ce057ee39fd88e7329b0c292aa16869b"},
]
coverage = [
{file = "coverage-5.5-cp27-cp27m-macosx_10_9_x86_64.whl", hash = "sha256:b6d534e4b2ab35c9f93f46229363e17f63c53ad01330df9f2d6bd1187e5eaacf"},
{file = "coverage-5.5-cp27-cp27m-manylinux1_i686.whl", hash = "sha256:b7895207b4c843c76a25ab8c1e866261bcfe27bfaa20c192de5190121770672b"},
{file = "coverage-5.5-cp27-cp27m-manylinux1_x86_64.whl", hash = "sha256:c2723d347ab06e7ddad1a58b2a821218239249a9e4365eaff6649d31180c1669"},
{file = "coverage-5.5-cp27-cp27m-manylinux2010_i686.whl", hash = "sha256:900fbf7759501bc7807fd6638c947d7a831fc9fdf742dc10f02956ff7220fa90"},
{file = "coverage-5.5-cp27-cp27m-manylinux2010_x86_64.whl", hash = "sha256:004d1880bed2d97151facef49f08e255a20ceb6f9432df75f4eef018fdd5a78c"},
{file = "coverage-5.5-cp27-cp27m-win32.whl", hash = "sha256:06191eb60f8d8a5bc046f3799f8a07a2d7aefb9504b0209aff0b47298333302a"},
{file = "coverage-5.5-cp27-cp27m-win_amd64.whl", hash = "sha256:7501140f755b725495941b43347ba8a2777407fc7f250d4f5a7d2a1050ba8e82"},
{file = "coverage-5.5-cp27-cp27mu-manylinux1_i686.whl", hash = "sha256:372da284cfd642d8e08ef606917846fa2ee350f64994bebfbd3afb0040436905"},
{file = "coverage-5.5-cp27-cp27mu-manylinux1_x86_64.whl", hash = "sha256:8963a499849a1fc54b35b1c9f162f4108017b2e6db2c46c1bed93a72262ed083"},
{file = "coverage-5.5-cp27-cp27mu-manylinux2010_i686.whl", hash = "sha256:869a64f53488f40fa5b5b9dcb9e9b2962a66a87dab37790f3fcfb5144b996ef5"},
{file = "coverage-5.5-cp27-cp27mu-manylinux2010_x86_64.whl", hash = "sha256:4a7697d8cb0f27399b0e393c0b90f0f1e40c82023ea4d45d22bce7032a5d7b81"},
{file = "coverage-5.5-cp310-cp310-macosx_10_14_x86_64.whl", hash = "sha256:8d0a0725ad7c1a0bcd8d1b437e191107d457e2ec1084b9f190630a4fb1af78e6"},
{file = "coverage-5.5-cp310-cp310-manylinux1_x86_64.whl", hash = "sha256:51cb9476a3987c8967ebab3f0fe144819781fca264f57f89760037a2ea191cb0"},
{file = "coverage-5.5-cp310-cp310-win_amd64.whl", hash = "sha256:c0891a6a97b09c1f3e073a890514d5012eb256845c451bd48f7968ef939bf4ae"},
{file = "coverage-5.5-cp35-cp35m-macosx_10_9_x86_64.whl", hash = "sha256:3487286bc29a5aa4b93a072e9592f22254291ce96a9fbc5251f566b6b7343cdb"},
{file = "coverage-5.5-cp35-cp35m-manylinux1_i686.whl", hash = "sha256:deee1077aae10d8fa88cb02c845cfba9b62c55e1183f52f6ae6a2df6a2187160"},
{file = "coverage-5.5-cp35-cp35m-manylinux1_x86_64.whl", hash = "sha256:f11642dddbb0253cc8853254301b51390ba0081750a8ac03f20ea8103f0c56b6"},
{file = "coverage-5.5-cp35-cp35m-manylinux2010_i686.whl", hash = "sha256:6c90e11318f0d3c436a42409f2749ee1a115cd8b067d7f14c148f1ce5574d701"},
{file = "coverage-5.5-cp35-cp35m-manylinux2010_x86_64.whl", hash = "sha256:30c77c1dc9f253283e34c27935fded5015f7d1abe83bc7821680ac444eaf7793"},
{file = "coverage-5.5-cp35-cp35m-win32.whl", hash = "sha256:9a1ef3b66e38ef8618ce5fdc7bea3d9f45f3624e2a66295eea5e57966c85909e"},
{file = "coverage-5.5-cp35-cp35m-win_amd64.whl", hash = "sha256:972c85d205b51e30e59525694670de6a8a89691186012535f9d7dbaa230e42c3"},
{file = "coverage-5.5-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:af0e781009aaf59e25c5a678122391cb0f345ac0ec272c7961dc5455e1c40066"},
{file = "coverage-5.5-cp36-cp36m-manylinux1_i686.whl", hash = "sha256:74d881fc777ebb11c63736622b60cb9e4aee5cace591ce274fb69e582a12a61a"},
{file = "coverage-5.5-cp36-cp36m-manylinux1_x86_64.whl", hash = "sha256:92b017ce34b68a7d67bd6d117e6d443a9bf63a2ecf8567bb3d8c6c7bc5014465"},
{file = "coverage-5.5-cp36-cp36m-manylinux2010_i686.whl", hash = "sha256:d636598c8305e1f90b439dbf4f66437de4a5e3c31fdf47ad29542478c8508bbb"},
{file = "coverage-5.5-cp36-cp36m-manylinux2010_x86_64.whl", hash = "sha256:41179b8a845742d1eb60449bdb2992196e211341818565abded11cfa90efb821"},
{file = "coverage-5.5-cp36-cp36m-win32.whl", hash = "sha256:040af6c32813fa3eae5305d53f18875bedd079960822ef8ec067a66dd8afcd45"},
{file = "coverage-5.5-cp36-cp36m-win_amd64.whl", hash = "sha256:5fec2d43a2cc6965edc0bb9e83e1e4b557f76f843a77a2496cbe719583ce8184"},
{file = "coverage-5.5-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:18ba8bbede96a2c3dde7b868de9dcbd55670690af0988713f0603f037848418a"},
{file = "coverage-5.5-cp37-cp37m-manylinux1_i686.whl", hash = "sha256:2910f4d36a6a9b4214bb7038d537f015346f413a975d57ca6b43bf23d6563b53"},
{file = "coverage-5.5-cp37-cp37m-manylinux1_x86_64.whl", hash = "sha256:f0b278ce10936db1a37e6954e15a3730bea96a0997c26d7fee88e6c396c2086d"},
{file = "coverage-5.5-cp37-cp37m-manylinux2010_i686.whl", hash = "sha256:796c9c3c79747146ebd278dbe1e5c5c05dd6b10cc3bcb8389dfdf844f3ead638"},
{file = "coverage-5.5-cp37-cp37m-manylinux2010_x86_64.whl", hash = "sha256:53194af30d5bad77fcba80e23a1441c71abfb3e01192034f8246e0d8f99528f3"},
{file = "coverage-5.5-cp37-cp37m-win32.whl", hash = "sha256:184a47bbe0aa6400ed2d41d8e9ed868b8205046518c52464fde713ea06e3a74a"},
{file = "coverage-5.5-cp37-cp37m-win_amd64.whl", hash = "sha256:2949cad1c5208b8298d5686d5a85b66aae46d73eec2c3e08c817dd3513e5848a"},
{file = "coverage-5.5-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:217658ec7187497e3f3ebd901afdca1af062b42cfe3e0dafea4cced3983739f6"},
{file = "coverage-5.5-cp38-cp38-manylinux1_i686.whl", hash = "sha256:1aa846f56c3d49205c952d8318e76ccc2ae23303351d9270ab220004c580cfe2"},
{file = "coverage-5.5-cp38-cp38-manylinux1_x86_64.whl", hash = "sha256:24d4a7de75446be83244eabbff746d66b9240ae020ced65d060815fac3423759"},
{file = "coverage-5.5-cp38-cp38-manylinux2010_i686.whl", hash = "sha256:d1f8bf7b90ba55699b3a5e44930e93ff0189aa27186e96071fac7dd0d06a1873"},
{file = "coverage-5.5-cp38-cp38-manylinux2010_x86_64.whl", hash = "sha256:970284a88b99673ccb2e4e334cfb38a10aab7cd44f7457564d11898a74b62d0a"},
{file = "coverage-5.5-cp38-cp38-win32.whl", hash = "sha256:01d84219b5cdbfc8122223b39a954820929497a1cb1422824bb86b07b74594b6"},
{file = "coverage-5.5-cp38-cp38-win_amd64.whl", hash = "sha256:2e0d881ad471768bf6e6c2bf905d183543f10098e3b3640fc029509530091502"},
{file = "coverage-5.5-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:d1f9ce122f83b2305592c11d64f181b87153fc2c2bbd3bb4a3dde8303cfb1a6b"},
{file = "coverage-5.5-cp39-cp39-manylinux1_i686.whl", hash = "sha256:13c4ee887eca0f4c5a247b75398d4114c37882658300e153113dafb1d76de529"},
{file = "coverage-5.5-cp39-cp39-manylinux1_x86_64.whl", hash = "sha256:52596d3d0e8bdf3af43db3e9ba8dcdaac724ba7b5ca3f6358529d56f7a166f8b"},
{file = "coverage-5.5-cp39-cp39-manylinux2010_i686.whl", hash = "sha256:2cafbbb3af0733db200c9b5f798d18953b1a304d3f86a938367de1567f4b5bff"},
{file = "coverage-5.5-cp39-cp39-manylinux2010_x86_64.whl", hash = "sha256:44d654437b8ddd9eee7d1eaee28b7219bec228520ff809af170488fd2fed3e2b"},
{file = "coverage-5.5-cp39-cp39-win32.whl", hash = "sha256:d314ed732c25d29775e84a960c3c60808b682c08d86602ec2c3008e1202e3bb6"},
{file = "coverage-5.5-cp39-cp39-win_amd64.whl", hash = "sha256:13034c4409db851670bc9acd836243aeee299949bd5673e11844befcb0149f03"},
{file = "coverage-5.5-pp36-none-any.whl", hash = "sha256:f030f8873312a16414c0d8e1a1ddff2d3235655a2174e3648b4fa66b3f2f1079"},
{file = "coverage-5.5-pp37-none-any.whl", hash = "sha256:2a3859cb82dcbda1cfd3e6f71c27081d18aa251d20a17d87d26d4cd216fb0af4"},
{file = "coverage-5.5.tar.gz", hash = "sha256:ebe78fe9a0e874362175b02371bdfbee64d8edc42a044253ddf4ee7d3c15212c"},
]
execnet = [
{file = "execnet-1.9.0-py2.py3-none-any.whl", hash = "sha256:a295f7cc774947aac58dde7fdc85f4aa00c42adf5d8f5468fc630c1acf30a142"},
{file = "execnet-1.9.0.tar.gz", hash = "sha256:8f694f3ba9cc92cab508b152dcfe322153975c29bda272e2fd7f3f00f36e47c5"},
@ -455,6 +555,9 @@ mccabe = [
{file = "mccabe-0.6.1-py2.py3-none-any.whl", hash = "sha256:ab8a6258860da4b6677da4bd2fe5dc2c659cff31b3ee4f7f5d64e79735b80d42"},
{file = "mccabe-0.6.1.tar.gz", hash = "sha256:dd8d182285a0fe56bace7f45b5e7d1a6ebcbf524e8f3bd87eb0f125271b8831f"},
]
mimesis = [
{file = "mimesis-4.1.3.tar.gz", hash = "sha256:90f36c21c1bb9944afc17178eb5868b0c85aa1fe49eb04bcbdafafd1ad4ca2ba"},
]
mypy = [
{file = "mypy-0.910-cp35-cp35m-macosx_10_9_x86_64.whl", hash = "sha256:a155d80ea6cee511a3694b108c4494a39f42de11ee4e61e72bc424c490e46457"},
{file = "mypy-0.910-cp35-cp35m-manylinux1_x86_64.whl", hash = "sha256:b94e4b785e304a04ea0828759172a15add27088520dc7e49ceade7834275bedb"},
@ -493,43 +596,13 @@ pathspec = [
{file = "pathspec-0.9.0.tar.gz", hash = "sha256:e564499435a2673d586f6b2130bb5b95f04a3ba06f81b8f895b651a3c76aabb1"},
]
platformdirs = [
{file = "platformdirs-2.3.0-py3-none-any.whl", hash = "sha256:8003ac87717ae2c7ee1ea5a84a1a61e87f3fbd16eb5aadba194ea30a9019f648"},
{file = "platformdirs-2.3.0.tar.gz", hash = "sha256:15b056538719b1c94bdaccb29e5f81879c7f7f0f4a153f46086d155dffcd4f0f"},
{file = "platformdirs-2.4.0-py3-none-any.whl", hash = "sha256:8868bbe3c3c80d42f20156f22e7131d2fb321f5bc86a2a345375c6481a67021d"},
{file = "platformdirs-2.4.0.tar.gz", hash = "sha256:367a5e80b3d04d2428ffa76d33f124cf11e8fff2acdaa9b43d545f5c7d661ef2"},
]
pluggy = [
{file = "pluggy-1.0.0-py2.py3-none-any.whl", hash = "sha256:74134bbf457f031a36d68416e1509f34bd5ccc019f0bcc952c7b909d06b37bd3"},
{file = "pluggy-1.0.0.tar.gz", hash = "sha256:4224373bacce55f955a878bf9cfa763c1e360858e330072059e10bad68531159"},
]
psutil = [
{file = "psutil-5.8.0-cp27-cp27m-macosx_10_9_x86_64.whl", hash = "sha256:0066a82f7b1b37d334e68697faba68e5ad5e858279fd6351c8ca6024e8d6ba64"},
{file = "psutil-5.8.0-cp27-cp27m-manylinux2010_i686.whl", hash = "sha256:0ae6f386d8d297177fd288be6e8d1afc05966878704dad9847719650e44fc49c"},
{file = "psutil-5.8.0-cp27-cp27m-manylinux2010_x86_64.whl", hash = "sha256:12d844996d6c2b1d3881cfa6fa201fd635971869a9da945cf6756105af73d2df"},
{file = "psutil-5.8.0-cp27-cp27mu-manylinux2010_i686.whl", hash = "sha256:02b8292609b1f7fcb34173b25e48d0da8667bc85f81d7476584d889c6e0f2131"},
{file = "psutil-5.8.0-cp27-cp27mu-manylinux2010_x86_64.whl", hash = "sha256:6ffe81843131ee0ffa02c317186ed1e759a145267d54fdef1bc4ea5f5931ab60"},
{file = "psutil-5.8.0-cp27-none-win32.whl", hash = "sha256:ea313bb02e5e25224e518e4352af4bf5e062755160f77e4b1767dd5ccb65f876"},
{file = "psutil-5.8.0-cp27-none-win_amd64.whl", hash = "sha256:5da29e394bdedd9144c7331192e20c1f79283fb03b06e6abd3a8ae45ffecee65"},
{file = "psutil-5.8.0-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:74fb2557d1430fff18ff0d72613c5ca30c45cdbfcddd6a5773e9fc1fe9364be8"},
{file = "psutil-5.8.0-cp36-cp36m-manylinux2010_i686.whl", hash = "sha256:74f2d0be88db96ada78756cb3a3e1b107ce8ab79f65aa885f76d7664e56928f6"},
{file = "psutil-5.8.0-cp36-cp36m-manylinux2010_x86_64.whl", hash = "sha256:99de3e8739258b3c3e8669cb9757c9a861b2a25ad0955f8e53ac662d66de61ac"},
{file = "psutil-5.8.0-cp36-cp36m-win32.whl", hash = "sha256:36b3b6c9e2a34b7d7fbae330a85bf72c30b1c827a4366a07443fc4b6270449e2"},
{file = "psutil-5.8.0-cp36-cp36m-win_amd64.whl", hash = "sha256:52de075468cd394ac98c66f9ca33b2f54ae1d9bff1ef6b67a212ee8f639ec06d"},
{file = "psutil-5.8.0-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:c6a5fd10ce6b6344e616cf01cc5b849fa8103fbb5ba507b6b2dee4c11e84c935"},
{file = "psutil-5.8.0-cp37-cp37m-manylinux2010_i686.whl", hash = "sha256:61f05864b42fedc0771d6d8e49c35f07efd209ade09a5afe6a5059e7bb7bf83d"},
{file = "psutil-5.8.0-cp37-cp37m-manylinux2010_x86_64.whl", hash = "sha256:0dd4465a039d343925cdc29023bb6960ccf4e74a65ad53e768403746a9207023"},
{file = "psutil-5.8.0-cp37-cp37m-win32.whl", hash = "sha256:1bff0d07e76114ec24ee32e7f7f8d0c4b0514b3fae93e3d2aaafd65d22502394"},
{file = "psutil-5.8.0-cp37-cp37m-win_amd64.whl", hash = "sha256:fcc01e900c1d7bee2a37e5d6e4f9194760a93597c97fee89c4ae51701de03563"},
{file = "psutil-5.8.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:6223d07a1ae93f86451d0198a0c361032c4c93ebd4bf6d25e2fb3edfad9571ef"},
{file = "psutil-5.8.0-cp38-cp38-manylinux2010_i686.whl", hash = "sha256:d225cd8319aa1d3c85bf195c4e07d17d3cd68636b8fc97e6cf198f782f99af28"},
{file = "psutil-5.8.0-cp38-cp38-manylinux2010_x86_64.whl", hash = "sha256:28ff7c95293ae74bf1ca1a79e8805fcde005c18a122ca983abf676ea3466362b"},
{file = "psutil-5.8.0-cp38-cp38-win32.whl", hash = "sha256:ce8b867423291cb65cfc6d9c4955ee9bfc1e21fe03bb50e177f2b957f1c2469d"},
{file = "psutil-5.8.0-cp38-cp38-win_amd64.whl", hash = "sha256:90f31c34d25b1b3ed6c40cdd34ff122b1887a825297c017e4cbd6796dd8b672d"},
{file = "psutil-5.8.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:6323d5d845c2785efb20aded4726636546b26d3b577aded22492908f7c1bdda7"},
{file = "psutil-5.8.0-cp39-cp39-manylinux2010_i686.whl", hash = "sha256:245b5509968ac0bd179287d91210cd3f37add77dad385ef238b275bad35fa1c4"},
{file = "psutil-5.8.0-cp39-cp39-manylinux2010_x86_64.whl", hash = "sha256:90d4091c2d30ddd0a03e0b97e6a33a48628469b99585e2ad6bf21f17423b112b"},
{file = "psutil-5.8.0-cp39-cp39-win32.whl", hash = "sha256:ea372bcc129394485824ae3e3ddabe67dc0b118d262c568b4d2602a7070afdb0"},
{file = "psutil-5.8.0-cp39-cp39-win_amd64.whl", hash = "sha256:f4634b033faf0d968bb9220dd1c793b897ab7f1189956e1aa9eae752527127d3"},
{file = "psutil-5.8.0.tar.gz", hash = "sha256:0c9ccb99ab76025f2f0bbecf341d4656e9c1351db8cc8a03ccd62e318ab4b5c6"},
]
py = [
{file = "py-1.10.0-py2.py3-none-any.whl", hash = "sha256:3b80836aa6d1feeaa108e046da6423ab8f6ceda6468545ae8d02d9d58d18818a"},
{file = "py-1.10.0.tar.gz", hash = "sha256:21b81bda15b66ef5e1a777a21c4dcd9c20ad3efd0b3f817e7a809035269e1bd3"},
@ -574,10 +647,22 @@ pytest = [
{file = "pytest-6.2.5-py3-none-any.whl", hash = "sha256:7310f8d27bc79ced999e760ca304d69f6ba6c6649c0b60fb0e04a4a77cacc134"},
{file = "pytest-6.2.5.tar.gz", hash = "sha256:131b36680866a76e6781d13f101efb86cf674ebb9762eb70d3082b6f29889e89"},
]
pytest-cov = [
{file = "pytest-cov-2.12.1.tar.gz", hash = "sha256:261ceeb8c227b726249b376b8526b600f38667ee314f910353fa318caa01f4d7"},
{file = "pytest_cov-2.12.1-py2.py3-none-any.whl", hash = "sha256:261bb9e47e65bd099c89c3edf92972865210c36813f80ede5277dceb77a4a62a"},
]
pytest-forked = [
{file = "pytest-forked-1.3.0.tar.gz", hash = "sha256:6aa9ac7e00ad1a539c41bec6d21011332de671e938c7637378ec9710204e37ca"},
{file = "pytest_forked-1.3.0-py2.py3-none-any.whl", hash = "sha256:dc4147784048e70ef5d437951728825a131b81714b398d5d52f17c7c144d8815"},
]
pytest-html = [
{file = "pytest-html-3.1.1.tar.gz", hash = "sha256:3ee1cf319c913d19fe53aeb0bc400e7b0bc2dbeb477553733db1dad12eb75ee3"},
{file = "pytest_html-3.1.1-py3-none-any.whl", hash = "sha256:b7f82f123936a3f4d2950bc993c2c1ca09ce262c9ae12f9ac763a2401380b455"},
]
pytest-metadata = [
{file = "pytest-metadata-1.11.0.tar.gz", hash = "sha256:71b506d49d34e539cc3cfdb7ce2c5f072bea5c953320002c95968e0238f8ecf1"},
{file = "pytest_metadata-1.11.0-py2.py3-none-any.whl", hash = "sha256:576055b8336dd4a9006dd2a47615f76f2f8c30ab12b1b1c039d99e834583523f"},
]
pytest-xdist = [
{file = "pytest-xdist-2.4.0.tar.gz", hash = "sha256:89b330316f7fc475f999c81b577c2b926c9569f3d397ae432c0c2e2496d61ff9"},
{file = "pytest_xdist-2.4.0-py3-none-any.whl", hash = "sha256:7b61ebb46997a0820a263553179d6d1e25a8c50d8a8620cd1aa1e20e3be99168"},
@ -614,47 +699,47 @@ pyyaml = [
{file = "PyYAML-5.4.1.tar.gz", hash = "sha256:607774cbba28732bfa802b54baa7484215f530991055bb562efbed5b2f20a45e"},
]
regex = [
{file = "regex-2021.8.28-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:9d05ad5367c90814099000442b2125535e9d77581855b9bee8780f1b41f2b1a2"},
{file = "regex-2021.8.28-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f3bf1bc02bc421047bfec3343729c4bbbea42605bcfd6d6bfe2c07ade8b12d2a"},
{file = "regex-2021.8.28-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:5f6a808044faae658f546dd5f525e921de9fa409de7a5570865467f03a626fc0"},
{file = "regex-2021.8.28-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:a617593aeacc7a691cc4af4a4410031654f2909053bd8c8e7db837f179a630eb"},
{file = "regex-2021.8.28-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:79aef6b5cd41feff359acaf98e040844613ff5298d0d19c455b3d9ae0bc8c35a"},
{file = "regex-2021.8.28-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:0fc1f8f06977c2d4f5e3d3f0d4a08089be783973fc6b6e278bde01f0544ff308"},
{file = "regex-2021.8.28-cp310-cp310-win32.whl", hash = "sha256:6eebf512aa90751d5ef6a7c2ac9d60113f32e86e5687326a50d7686e309f66ed"},
{file = "regex-2021.8.28-cp310-cp310-win_amd64.whl", hash = "sha256:ac88856a8cbccfc14f1b2d0b829af354cc1743cb375e7f04251ae73b2af6adf8"},
{file = "regex-2021.8.28-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:c206587c83e795d417ed3adc8453a791f6d36b67c81416676cad053b4104152c"},
{file = "regex-2021.8.28-cp36-cp36m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e8690ed94481f219a7a967c118abaf71ccc440f69acd583cab721b90eeedb77c"},
{file = "regex-2021.8.28-cp36-cp36m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:328a1fad67445550b982caa2a2a850da5989fd6595e858f02d04636e7f8b0b13"},
{file = "regex-2021.8.28-cp36-cp36m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:c7cb4c512d2d3b0870e00fbbac2f291d4b4bf2634d59a31176a87afe2777c6f0"},
{file = "regex-2021.8.28-cp36-cp36m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:66256b6391c057305e5ae9209941ef63c33a476b73772ca967d4a2df70520ec1"},
{file = "regex-2021.8.28-cp36-cp36m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:8e44769068d33e0ea6ccdf4b84d80c5afffe5207aa4d1881a629cf0ef3ec398f"},
{file = "regex-2021.8.28-cp36-cp36m-win32.whl", hash = "sha256:08d74bfaa4c7731b8dac0a992c63673a2782758f7cfad34cf9c1b9184f911354"},
{file = "regex-2021.8.28-cp36-cp36m-win_amd64.whl", hash = "sha256:abb48494d88e8a82601af905143e0de838c776c1241d92021e9256d5515b3645"},
{file = "regex-2021.8.28-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:b4c220a1fe0d2c622493b0a1fd48f8f991998fb447d3cd368033a4b86cf1127a"},
{file = "regex-2021.8.28-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d4a332404baa6665b54e5d283b4262f41f2103c255897084ec8f5487ce7b9e8e"},
{file = "regex-2021.8.28-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c61dcc1cf9fd165127a2853e2c31eb4fb961a4f26b394ac9fe5669c7a6592892"},
{file = "regex-2021.8.28-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:ee329d0387b5b41a5dddbb6243a21cb7896587a651bebb957e2d2bb8b63c0791"},
{file = "regex-2021.8.28-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:f60667673ff9c249709160529ab39667d1ae9fd38634e006bec95611f632e759"},
{file = "regex-2021.8.28-cp37-cp37m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:b844fb09bd9936ed158ff9df0ab601e2045b316b17aa8b931857365ea8586906"},
{file = "regex-2021.8.28-cp37-cp37m-win32.whl", hash = "sha256:4cde065ab33bcaab774d84096fae266d9301d1a2f5519d7bd58fc55274afbf7a"},
{file = "regex-2021.8.28-cp37-cp37m-win_amd64.whl", hash = "sha256:1413b5022ed6ac0d504ba425ef02549a57d0f4276de58e3ab7e82437892704fc"},
{file = "regex-2021.8.28-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:ed4b50355b066796dacdd1cf538f2ce57275d001838f9b132fab80b75e8c84dd"},
{file = "regex-2021.8.28-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:28fc475f560d8f67cc8767b94db4c9440210f6958495aeae70fac8faec631797"},
{file = "regex-2021.8.28-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bdc178caebd0f338d57ae445ef8e9b737ddf8fbc3ea187603f65aec5b041248f"},
{file = "regex-2021.8.28-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:999ad08220467b6ad4bd3dd34e65329dd5d0df9b31e47106105e407954965256"},
{file = "regex-2021.8.28-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:808ee5834e06f57978da3e003ad9d6292de69d2bf6263662a1a8ae30788e080b"},
{file = "regex-2021.8.28-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:d5111d4c843d80202e62b4fdbb4920db1dcee4f9366d6b03294f45ed7b18b42e"},
{file = "regex-2021.8.28-cp38-cp38-win32.whl", hash = "sha256:473858730ef6d6ff7f7d5f19452184cd0caa062a20047f6d6f3e135a4648865d"},
{file = "regex-2021.8.28-cp38-cp38-win_amd64.whl", hash = "sha256:31a99a4796bf5aefc8351e98507b09e1b09115574f7c9dbb9cf2111f7220d2e2"},
{file = "regex-2021.8.28-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:04f6b9749e335bb0d2f68c707f23bb1773c3fb6ecd10edf0f04df12a8920d468"},
{file = "regex-2021.8.28-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:9b006628fe43aa69259ec04ca258d88ed19b64791693df59c422b607b6ece8bb"},
{file = "regex-2021.8.28-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:121f4b3185feaade3f85f70294aef3f777199e9b5c0c0245c774ae884b110a2d"},
{file = "regex-2021.8.28-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:a577a21de2ef8059b58f79ff76a4da81c45a75fe0bfb09bc8b7bb4293fa18983"},
{file = "regex-2021.8.28-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:1743345e30917e8c574f273f51679c294effba6ad372db1967852f12c76759d8"},
{file = "regex-2021.8.28-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:e1e8406b895aba6caa63d9fd1b6b1700d7e4825f78ccb1e5260551d168db38ed"},
{file = "regex-2021.8.28-cp39-cp39-win32.whl", hash = "sha256:ed283ab3a01d8b53de3a05bfdf4473ae24e43caee7dcb5584e86f3f3e5ab4374"},
{file = "regex-2021.8.28-cp39-cp39-win_amd64.whl", hash = "sha256:610b690b406653c84b7cb6091facb3033500ee81089867ee7d59e675f9ca2b73"},
{file = "regex-2021.8.28.tar.gz", hash = "sha256:f585cbbeecb35f35609edccb95efd95a3e35824cd7752b586503f7e6087303f1"},
{file = "regex-2021.9.24-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:0628ed7d6334e8f896f882a5c1240de8c4d9b0dd7c7fb8e9f4692f5684b7d656"},
{file = "regex-2021.9.24-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3baf3eaa41044d4ced2463fd5d23bf7bd4b03d68739c6c99a59ce1f95599a673"},
{file = "regex-2021.9.24-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c000635fd78400a558bd7a3c2981bb2a430005ebaa909d31e6e300719739a949"},
{file = "regex-2021.9.24-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:295bc8a13554a25ad31e44c4bedabd3c3e28bba027e4feeb9bb157647a2344a7"},
{file = "regex-2021.9.24-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:b0e3f59d3c772f2c3baaef2db425e6fc4149d35a052d874bb95ccfca10a1b9f4"},
{file = "regex-2021.9.24-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:aea4006b73b555fc5bdb650a8b92cf486d678afa168cf9b38402bb60bf0f9c18"},
{file = "regex-2021.9.24-cp310-cp310-win32.whl", hash = "sha256:09eb62654030f39f3ba46bc6726bea464069c29d00a9709e28c9ee9623a8da4a"},
{file = "regex-2021.9.24-cp310-cp310-win_amd64.whl", hash = "sha256:8d80087320632457aefc73f686f66139801959bf5b066b4419b92be85be3543c"},
{file = "regex-2021.9.24-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:7e3536f305f42ad6d31fc86636c54c7dafce8d634e56fef790fbacb59d499dd5"},
{file = "regex-2021.9.24-cp36-cp36m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c31f35a984caffb75f00a86852951a337540b44e4a22171354fb760cefa09346"},
{file = "regex-2021.9.24-cp36-cp36m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9c7cb25adba814d5f419733fe565f3289d6fa629ab9e0b78f6dff5fa94ab0456"},
{file = "regex-2021.9.24-cp36-cp36m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:85c61bee5957e2d7be390392feac7e1d7abd3a49cbaed0c8cee1541b784c8561"},
{file = "regex-2021.9.24-cp36-cp36m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:c94722bf403b8da744b7d0bb87e1f2529383003ceec92e754f768ef9323f69ad"},
{file = "regex-2021.9.24-cp36-cp36m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:6adc1bd68f81968c9d249aab8c09cdc2cbe384bf2d2cb7f190f56875000cdc72"},
{file = "regex-2021.9.24-cp36-cp36m-win32.whl", hash = "sha256:2054dea683f1bda3a804fcfdb0c1c74821acb968093d0be16233873190d459e3"},
{file = "regex-2021.9.24-cp36-cp36m-win_amd64.whl", hash = "sha256:7783d89bd5413d183a38761fbc68279b984b9afcfbb39fa89d91f63763fbfb90"},
{file = "regex-2021.9.24-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:b15dc34273aefe522df25096d5d087abc626e388a28a28ac75a4404bb7668736"},
{file = "regex-2021.9.24-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:10a7a9cbe30bd90b7d9a1b4749ef20e13a3528e4215a2852be35784b6bd070f0"},
{file = "regex-2021.9.24-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:fb9f5844db480e2ef9fce3a72e71122dd010ab7b2920f777966ba25f7eb63819"},
{file = "regex-2021.9.24-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:17310b181902e0bb42b29c700e2c2346b8d81f26e900b1328f642e225c88bce1"},
{file = "regex-2021.9.24-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:0bba1f6df4eafe79db2ecf38835c2626dbd47911e0516f6962c806f83e7a99ae"},
{file = "regex-2021.9.24-cp37-cp37m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:821e10b73e0898544807a0692a276e539e5bafe0a055506a6882814b6a02c3ec"},
{file = "regex-2021.9.24-cp37-cp37m-win32.whl", hash = "sha256:9c371dd326289d85906c27ec2bc1dcdedd9d0be12b543d16e37bad35754bde48"},
{file = "regex-2021.9.24-cp37-cp37m-win_amd64.whl", hash = "sha256:1e8d1898d4fb817120a5f684363b30108d7b0b46c7261264b100d14ec90a70e7"},
{file = "regex-2021.9.24-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:8a5c2250c0a74428fd5507ae8853706fdde0f23bfb62ee1ec9418eeacf216078"},
{file = "regex-2021.9.24-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8aec4b4da165c4a64ea80443c16e49e3b15df0f56c124ac5f2f8708a65a0eddc"},
{file = "regex-2021.9.24-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:650c4f1fc4273f4e783e1d8e8b51a3e2311c2488ba0fcae6425b1e2c248a189d"},
{file = "regex-2021.9.24-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:2cdb3789736f91d0b3333ac54d12a7e4f9efbc98f53cb905d3496259a893a8b3"},
{file = "regex-2021.9.24-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:4e61100200fa6ab7c99b61476f9f9653962ae71b931391d0264acfb4d9527d9c"},
{file = "regex-2021.9.24-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:8c268e78d175798cd71d29114b0a1f1391c7d011995267d3b62319ec1a4ecaa1"},
{file = "regex-2021.9.24-cp38-cp38-win32.whl", hash = "sha256:658e3477676009083422042c4bac2bdad77b696e932a3de001c42cc046f8eda2"},
{file = "regex-2021.9.24-cp38-cp38-win_amd64.whl", hash = "sha256:a731552729ee8ae9c546fb1c651c97bf5f759018fdd40d0e9b4d129e1e3a44c8"},
{file = "regex-2021.9.24-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:86f9931eb92e521809d4b64ec8514f18faa8e11e97d6c2d1afa1bcf6c20a8eab"},
{file = "regex-2021.9.24-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:dcbbc9cfa147d55a577d285fd479b43103188855074552708df7acc31a476dd9"},
{file = "regex-2021.9.24-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:29385c4dbb3f8b3a55ce13de6a97a3d21bd00de66acd7cdfc0b49cb2f08c906c"},
{file = "regex-2021.9.24-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:c50a6379763c733562b1fee877372234d271e5c78cd13ade5f25978aa06744db"},
{file = "regex-2021.9.24-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:6f74b6d8f59f3cfb8237e25c532b11f794b96f5c89a6f4a25857d85f84fbef11"},
{file = "regex-2021.9.24-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:6c4d83d21d23dd854ffbc8154cf293f4e43ba630aa9bd2539c899343d7f59da3"},
{file = "regex-2021.9.24-cp39-cp39-win32.whl", hash = "sha256:95e89a8558c8c48626dcffdf9c8abac26b7c251d352688e7ab9baf351e1c7da6"},
{file = "regex-2021.9.24-cp39-cp39-win_amd64.whl", hash = "sha256:835962f432bce92dc9bf22903d46c50003c8d11b1dc64084c8fae63bca98564a"},
{file = "regex-2021.9.24.tar.gz", hash = "sha256:6266fde576e12357b25096351aac2b4b880b0066263e7bc7a9a1b4307991bb0e"},
]
tokenize-rt = [
{file = "tokenize_rt-4.1.0-py2.py3-none-any.whl", hash = "sha256:b37251fa28c21e8cce2e42f7769a35fba2dd2ecafb297208f9a9a8add3ca7793"},

View File

@ -19,7 +19,20 @@ flake8 = "*"
mypy = "*"
types-PyYAML = "*"
pytest = "*"
pytest-xdist = {extras = ["psutil"], version = "*"}
pytest-xdist = "*"
mimesis = "*"
pytest-cov = "*"
pytest-html = "*"
[tool.pytest.ini_options]
minversion = "6.0"
addopts = "-v -s -p no:cacheprovider -n auto --cov=skyline_config --cov-append --cov-report=term-missing --cov-report=html"
testpaths = [
"tests",
]
markers = [
"ddt(*args: TestData): Mark the test as a data-driven test."
]
[build-system]
requires = ["poetry-core>=1.0.0"]

View File

@ -14,17 +14,21 @@
from __future__ import annotations
import os
import warnings
from dataclasses import InitVar, dataclass, field
from pathlib import Path, PurePath
from typing import Any, Dict, Iterator, Sequence, Tuple, Type
from typing import Any, Dict, Iterator, NamedTuple, Sequence, Tuple, Type
import yaml
from immutables import Map, MapItems, MapKeys, MapValues
from pydantic import BaseModel, create_model
class ConfigPath(NamedTuple):
config_dir_path: str
config_file_path: str
@dataclass(frozen=True)
class Opt:
name: str
@ -81,15 +85,15 @@ class Group:
items = ", ".join((f"{opt}=Opt(name='{opt}')" for opt in self._opts))
return f"Group({items})"
def items(self) -> MapItems[str, Opt]:
return self._opts.items()
def keys(self) -> MapKeys[str]:
return self._opts.keys()
def values(self) -> MapValues[Opt]:
return self._opts.values()
def items(self) -> MapItems[str, Opt]:
return self._opts.items()
@dataclass(repr=False, frozen=True)
class Configuration:
@ -101,22 +105,17 @@ class Configuration:
object.__setattr__(self, "_groups", Map({group.name: group for group in init_groups}))
@staticmethod
def _get_config_file(project: str, env: Dict[str, str]) -> Tuple[str, str]:
config_dir = env.get("OS_CONFIG_DIR", PurePath("/etc", project).as_posix()).strip()
config_file = env.get(
"OS_CONFIG_FILE",
os.path.join(config_dir, f"{project}.yaml"),
).strip()
return (config_dir, config_file)
def get_config_path(project: str, env: Dict[str, str]) -> Tuple[str, str]:
config_dir_path = env.get("OS_CONFIG_DIR", PurePath("/etc", project).as_posix())
config_file_path = PurePath(config_dir_path).joinpath(f"{project}.yaml").as_posix()
return ConfigPath(config_dir_path.strip(), config_file_path.strip())
def setup(self, project: str, env: Dict[str, str]) -> None:
config_dir, config_file = self._get_config_file(project, env)
if not Path(config_file).exists():
raise ValueError("Not found config file: %s" % config_file)
config_dir_path, config_file_path = self.get_config_path(project, env)
if not Path(config_file_path).exists():
raise ValueError(f"Not found config file: {config_file_path}")
with open(config_file) as f:
with open(config_file_path) as f:
try:
object.__setattr__(self, "config", yaml.safe_load(f))
except Exception:
@ -134,14 +133,14 @@ class Configuration:
object.__setattr__(self, "_groups", Map())
object.__setattr__(self, "config", {})
def __call__(self, init_groups: Sequence[Group]) -> Any:
object.__setattr__(self, "_groups", Map({group.name: group for group in init_groups}))
def __getattr__(self, name: str) -> Group:
if name in self._groups:
return self._groups[name]
raise AttributeError(name)
def __call__(self, init_groups: Sequence[Group]) -> Any:
object.__setattr__(self, "_groups", Map({group.name: group for group in init_groups}))
def __contains__(self, key: Any) -> bool:
return self._groups.__contains__(key)
@ -155,14 +154,14 @@ class Configuration:
items = ", ".join((f"{group}=Group(name='{group}')" for group in self._groups))
return f"Configuration({items})"
def items(self) -> MapItems[str, Group]:
return self._groups.items()
def keys(self) -> MapKeys[str]:
return self._groups.keys()
def values(self) -> MapValues[Group]:
return self._groups.values()
def items(self) -> MapItems[str, Group]:
return self._groups.items()
__all__ = ("Opt", "Group", "Configuration")

View File

@ -0,0 +1,47 @@
# Copyright 2021 99cloud
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
from __future__ import annotations
from typing import TYPE_CHECKING
from _pytest.mark import ParameterSet
from tests.models import TestData
if TYPE_CHECKING:
from _pytest.python import Metafunc
def pytest_generate_tests(metafunc: Metafunc) -> None:
for marker in metafunc.definition.iter_markers(name="ddt"):
test_data: TestData
for test_data in marker.args:
argument_length = len(test_data.arguments)
argvalues = []
for argument_data in test_data.argument_data_set:
if len(argument_data.values) != argument_length:
raise ValueError(
f'Argument data "{argument_data.id}" of method '
f'"{metafunc.function.__name__}" doesn\'t match '
"number of arguments.",
)
argvalues.append(
ParameterSet(
id=argument_data.id,
marks=argument_data.marks,
values=argument_data.values,
),
)
metafunc.parametrize(test_data.arguments, argvalues, indirect=test_data.indirect)

View File

@ -0,0 +1,36 @@
# Copyright 2021 99cloud
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
from __future__ import annotations
from dataclasses import dataclass, field
from typing import Any, Dict, List
from mimesis import Generic
from pydantic import StrictBool, StrictInt, StrictStr
FAKER = Generic()
@dataclass
class FakeOptData:
name: str = field(default_factory=lambda: "_".join(FAKER.text.words()))
description: str = field(default_factory=lambda: str(FAKER.text.text()))
schema: Any = field(
default_factory=lambda: FAKER.random.choice(
[StrictBool, StrictInt, StrictStr, List, Dict],
),
)
default: Any = None
deprecated: bool = False

View File

@ -0,0 +1,36 @@
# Copyright 2021 99cloud
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
from __future__ import annotations
from dataclasses import dataclass
from typing import Any, Collection, Sequence, Tuple, Union
@dataclass
class ArgumentData:
id: str
values: Sequence[object]
# TODO: Fix type annotation of `marks` after the pytest > 7.0.0
# marks: Collection[Union[pytest.MarkDecorator, pytest.Mark]]
marks: Collection[Any] = ()
@dataclass
class TestData:
arguments: Tuple[str, ...]
argument_data_set: Sequence[ArgumentData]
indirect: Union[bool, Tuple[str]] = False
__test__ = False

View File

@ -0,0 +1,672 @@
# Copyright 2021 99cloud
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
from __future__ import annotations
from dataclasses import asdict
from pathlib import Path
from typing import Any, Dict, List, Optional, Sequence, Tuple, Type
import pytest
from _pytest.fixtures import SubRequest
from pydantic import StrictBool, StrictFloat, StrictInt, StrictStr
from pydantic.error_wrappers import ValidationError
from skyline_config.config import Configuration, Group, Opt
from tests.fake import FAKER, FakeOptData
from tests.models import ArgumentData, TestData
class TestOpt:
@pytest.mark.ddt(
TestData(
arguments=("opt_data", "expected_schema_type"),
argument_data_set=[
ArgumentData(
id="bool_opt",
values=(asdict(FakeOptData(schema=StrictBool)), "boolean"),
),
ArgumentData(
id="int_opt",
values=(asdict(FakeOptData(schema=StrictInt)), "integer"),
),
ArgumentData(
id="float_opt",
values=(asdict(FakeOptData(schema=StrictFloat)), "number"),
),
ArgumentData(
id="str_opt",
values=(asdict(FakeOptData(schema=StrictStr)), "string"),
),
ArgumentData(
id="list_opt",
values=(asdict(FakeOptData(schema=List[StrictStr])), "array"),
),
ArgumentData(
id="dict_opt",
values=(asdict(FakeOptData(schema=Dict[StrictStr, StrictStr])), "object"),
),
],
),
)
def test_opt_init(self, opt_data: Dict[str, Any], expected_schema_type: str) -> None:
opt = Opt(**opt_data)
opt_value_schema = opt._schema_model.schema().get("properties", {}).get("value", {})
assert opt_value_schema.get("type") == expected_schema_type
@pytest.mark.ddt(
TestData(
arguments=("opt_data", "expected_exception"),
argument_data_set=[
ArgumentData(
id="missing_parameters",
values=({"name": FAKER.text.word()}, TypeError),
),
ArgumentData(
id="unknown_schema",
values=(
{
"name": FAKER.text.word(),
"description": FAKER.text.word(),
"schema": object,
},
RuntimeError,
),
),
],
),
)
def test_opt_init_error(
self,
opt_data: Dict[str, Any],
expected_exception: Type[Exception],
) -> None:
with pytest.raises(expected_exception):
Opt(**opt_data)
@pytest.mark.ddt(
TestData(
arguments=("opt_data",),
argument_data_set=[
ArgumentData(
id="when_has_default",
values=(
asdict(
FakeOptData(schema=Optional[StrictStr], default=FAKER.text.word()),
),
),
),
ArgumentData(
id="when_no_default",
values=(asdict(FakeOptData(schema=Optional[StrictStr])),),
),
],
),
TestData(
arguments=("opt_value",),
argument_data_set=[
ArgumentData(id="load_value", values=(FAKER.text.word(),)),
ArgumentData(id="load_none", values=(None,)),
],
),
)
def test_opt_load(self, opt_data: Dict[str, Any], opt_value: Optional[str]) -> None:
opt = Opt(**opt_data)
opt.load(opt_value)
if opt_value is not None:
expected_result = opt_value
else:
expected_result = opt.default
assert opt.value == expected_result
@pytest.mark.ddt(
TestData(
arguments=("opt_data",),
argument_data_set=[
ArgumentData(
id="deprecated_warning",
values=(asdict(FakeOptData(schema=Optional[StrictStr], deprecated=True)),),
),
],
),
)
def test_opt_deprecated(self, opt_data: Dict[str, Any]) -> None:
opt = Opt(**opt_data)
expected_warn = DeprecationWarning
with pytest.warns(expected_warn):
opt.load(None)
@pytest.mark.ddt(
TestData(
arguments=("opt_data", "opt_value"),
argument_data_set=[
ArgumentData(
id="validation_error",
values=(
asdict(FakeOptData(schema=StrictStr)),
FAKER.numbers.integer_number(),
),
),
],
),
)
def test_opt_schema_validation(self, opt_data: Dict[str, Any], opt_value: int) -> None:
opt = Opt(**opt_data)
expected_exception = ValidationError
with pytest.raises(expected_exception):
opt.load(opt_value)
class TestGroup:
@pytest.fixture
def group_opts(self, request: SubRequest) -> Sequence[Opt]:
count: int = request.param
opts = []
for _ in range(count):
opt_data = asdict(
FakeOptData(schema=StrictStr, default=FAKER.text.word()),
)
opt = Opt(**opt_data)
opt.load(None)
opts.append(opt)
return opts
@pytest.mark.ddt(
TestData(
arguments=("group_name", "group_opts"),
indirect=("group_opts",),
argument_data_set=[
ArgumentData(id="empty_group", values=(FAKER.text.word(), 0)),
ArgumentData(
id="normal_group",
values=(FAKER.text.word(), FAKER.numbers.integer_number(1, 10)),
),
],
),
)
def test_group_init(self, group_name: str, group_opts: Sequence[Opt]) -> None:
group = Group(group_name, group_opts)
for opt in group_opts:
assert opt.value == getattr(group, opt.name, None)
@pytest.mark.ddt(
TestData(
arguments=("group_name", "group_opts"),
indirect=("group_opts",),
argument_data_set=[
ArgumentData(id="access_non-existent_opt", values=(FAKER.text.word(), 1)),
],
),
)
def test_group_access_error(self, group_name: str, group_opts: Sequence[Opt]) -> None:
group = Group(group_name, group_opts)
expected_exception = AttributeError
with pytest.raises(expected_exception):
getattr(group, f"{FAKER.text.word()}-test")
@pytest.mark.ddt(
TestData(
arguments=("group_name", "group_opts"),
indirect=("group_opts",),
argument_data_set=[
ArgumentData(
id="normal_group",
values=(FAKER.text.word(), FAKER.numbers.integer_number(1, 10)),
),
],
),
)
def test_group_like_collection(self, group_name: str, group_opts: Sequence[Opt]) -> None:
group = Group(group_name, group_opts)
for opt in group_opts:
assert opt.name in group
assert len(group) == len(group_opts)
opt_names = {opt.name for opt in group_opts}
for item in group:
assert item in opt_names
@pytest.mark.ddt(
TestData(
arguments=("group_name", "group_opts"),
indirect=("group_opts",),
argument_data_set=[
ArgumentData(
id="normal_group",
values=(FAKER.text.word(), FAKER.numbers.integer_number(1, 10)),
),
],
),
)
def test_group_repr(self, group_name: str, group_opts: Sequence[Opt]) -> None:
group = Group(group_name, group_opts)
opt_template = "{}=Opt(name='{}')"
for opt in group_opts:
opt_str = opt_template.format(opt.name, opt.name)
assert opt_str in repr(group)
@pytest.mark.ddt(
TestData(
arguments=("group_name", "group_opts"),
indirect=("group_opts",),
argument_data_set=[
ArgumentData(
id="normal_group",
values=(FAKER.text.word(), FAKER.numbers.integer_number(1, 10)),
),
],
),
)
def test_group_keys(self, group_name: str, group_opts: Sequence[Opt]) -> None:
group = Group(group_name, group_opts)
opt_names = {opt.name for opt in group_opts}
for item in group.keys():
assert item in opt_names
@pytest.mark.ddt(
TestData(
arguments=("group_name", "group_opts"),
indirect=("group_opts",),
argument_data_set=[
ArgumentData(
id="normal_group",
values=(FAKER.text.word(), FAKER.numbers.integer_number(1, 10)),
),
],
),
)
def test_group_values(self, group_name: str, group_opts: Sequence[Opt]) -> None:
group = Group(group_name, group_opts)
opts = {opt for opt in group_opts}
opt_ids = {id(opt) for opt in group_opts}
for item in group.values():
assert item in opts
assert id(item) in opt_ids
@pytest.mark.ddt(
TestData(
arguments=("group_name", "group_opts"),
indirect=("group_opts",),
argument_data_set=[
ArgumentData(
id="normal_group",
values=(FAKER.text.word(), FAKER.numbers.integer_number(1, 10)),
),
],
),
)
def test_group_items(self, group_name: str, group_opts: Sequence[Opt]) -> None:
group = Group(group_name, group_opts)
opt_names = {opt.name for opt in group_opts}
opts = {opt for opt in group_opts}
opt_ids = {id(opt) for opt in group_opts}
for name, item in group.items():
assert name in opt_names
assert item in opts
assert id(item) in opt_ids
class TestConfiguration:
@pytest.fixture
def config_groups(self, request: SubRequest) -> Sequence[Group]:
count: int = request.param
groups = []
for _ in range(count):
opts = []
for __ in range(FAKER.numbers.integer_number(1, 10)):
opt_data = asdict(
FakeOptData(schema=StrictStr, default=FAKER.text.word()),
)
opt = Opt(**opt_data)
opt.load(None)
opts.append(opt)
group = Group(FAKER.text.word(), opts)
groups.append(group)
return groups
@pytest.fixture
def config_setup_params(
self,
request: SubRequest,
tmp_path: Path,
) -> Tuple[str, Dict[str, str]]:
project: str = request.param.get("project", "")
env: Dict[str, str] = request.param.get("env", "")
env["OS_CONFIG_DIR"] = tmp_path.as_posix()
tmp_path.joinpath(f"{project}.yaml").write_text("{}")
return (project, env)
@pytest.mark.ddt(
TestData(
arguments=("config_groups",),
indirect=("config_groups",),
argument_data_set=[
ArgumentData(id="empty_config", values=(0,)),
ArgumentData(
id="normal_config",
values=(FAKER.numbers.integer_number(1, 10),),
),
],
),
)
def test_configuration_init(self, config_groups: Sequence[Group]) -> None:
config = Configuration(config_groups)
for group in config_groups:
assert group is getattr(config, group.name, None)
assert id(group) == id(getattr(config, group.name, None))
@pytest.mark.ddt(
TestData(
arguments=("config_groups",),
indirect=("config_groups",),
argument_data_set=[
ArgumentData(
id="access_non-existent_group",
values=(1,),
),
],
),
)
def test_configuration_access_error(self, config_groups: Sequence[Group]) -> None:
config = Configuration(config_groups)
expected_exception = AttributeError
with pytest.raises(expected_exception):
getattr(config, f"{FAKER.text.word()}-test")
@pytest.mark.ddt(
TestData(
arguments=(
"project",
"env",
"expected_config_path",
),
argument_data_set=[
ArgumentData(
id="set_env_config_dir",
values=(
"fake_project_name",
{"OS_CONFIG_DIR": "env_config_dir"},
("env_config_dir", "env_config_dir/fake_project_name.yaml"),
),
),
ArgumentData(
id="no_set_env",
values=(
"fake_project_name",
{},
(
"/etc/fake_project_name",
"/etc/fake_project_name/fake_project_name.yaml",
),
),
),
],
),
)
def test_configuration_get_config_path(
self,
project: str,
env: Dict[str, str],
expected_config_path: Tuple[str, str],
) -> None:
assert Configuration.get_config_path(project, env) == expected_config_path
@pytest.mark.ddt(
TestData(
arguments=("config_setup_params",),
indirect=("config_setup_params",),
argument_data_set=[
ArgumentData(
id="set_env_config_dir",
values=(
{
"project": "fake_project_name",
"env": {"OS_CONFIG_DIR": ""},
},
),
),
],
),
)
def test_configuration_setup(self, config_setup_params: Tuple[str, Dict[str, str]]) -> None:
groups = []
for _ in range(FAKER.numbers.integer_number(1, 10)):
opts = []
for __ in range(FAKER.numbers.integer_number(1, 10)):
opt_data = asdict(
FakeOptData(schema=StrictStr, default=FAKER.text.word()),
)
opts.append(Opt(**opt_data))
groups.append(Group(FAKER.text.word(), opts))
config = Configuration(groups)
project = config_setup_params[0]
env = config_setup_params[1]
config.setup(project, env)
for group in config:
for opt in getattr(config, group):
opt_value = getattr(getattr(config, group, None), opt)
assert isinstance(opt_value, str)
@pytest.mark.ddt(
TestData(
arguments=("config_setup_params",),
indirect=("config_setup_params",),
argument_data_set=[
ArgumentData(
id="not_found_config_file",
values=(
{
"project": "fake_project_name",
"env": {"OS_CONFIG_DIR": ""},
},
),
),
],
),
)
def test_configuration_setup_non_existent_error(
self,
config_setup_params: Tuple[str, Dict[str, str]],
) -> None:
groups = []
for _ in range(FAKER.numbers.integer_number(1, 10)):
opts = []
for __ in range(FAKER.numbers.integer_number(1, 10)):
opt_data = asdict(
FakeOptData(schema=StrictStr, default=FAKER.text.word()),
)
opts.append(Opt(**opt_data))
groups.append(Group(FAKER.text.word(), opts))
config = Configuration(groups)
project = config_setup_params[0]
env = config_setup_params[1]
config_dir_path, config_file_path = config.get_config_path(project, env)
Path(config_file_path).unlink(missing_ok=True)
expected_exception = ValueError
with pytest.raises(expected_exception, match="Not found config file"):
config.setup(project, env)
@pytest.mark.ddt(
TestData(
arguments=("config_setup_params",),
indirect=("config_setup_params",),
argument_data_set=[
ArgumentData(
id="file_is_not_yaml",
values=(
{
"project": "fake_project_name",
"env": {"OS_CONFIG_DIR": ""},
},
),
),
],
),
)
def test_configuration_setup_yaml_format_error(
self,
config_setup_params: Tuple[str, Dict[str, str]],
) -> None:
groups = []
for _ in range(FAKER.numbers.integer_number(1, 10)):
opts = []
for __ in range(FAKER.numbers.integer_number(1, 10)):
opt_data = asdict(
FakeOptData(schema=StrictStr, default=FAKER.text.word()),
)
opts.append(Opt(**opt_data))
groups.append(Group(FAKER.text.word(), opts))
config = Configuration(groups)
project = config_setup_params[0]
env = config_setup_params[1]
config_dir_path, config_file_path = config.get_config_path(project, env)
Path(config_file_path).write_text("{")
expected_exception = ValueError
with pytest.raises(expected_exception, match="Load config file error"):
config.setup(project, env)
@pytest.mark.ddt(
TestData(
arguments=("config_groups",),
indirect=("config_groups",),
argument_data_set=[
ArgumentData(
id="normal_config",
values=(FAKER.numbers.integer_number(1, 10),),
),
],
),
)
def test_configuration_cleanup(self, config_groups: Sequence[Group]) -> None:
config = Configuration(config_groups)
assert len(config) == len(config_groups)
config.cleanup()
assert len(config) == 0
@pytest.mark.ddt(
TestData(
arguments=("config_groups",),
indirect=("config_groups",),
argument_data_set=[
ArgumentData(
id="normal_config",
values=(FAKER.numbers.integer_number(1, 10),),
),
],
),
)
def test_configuration_call(self, config_groups: Sequence[Group]) -> None:
config = Configuration()
config(config_groups)
for group in config_groups:
assert group is getattr(config, group.name, None)
assert id(group) == id(getattr(config, group.name, None))
@pytest.mark.ddt(
TestData(
arguments=("config_groups",),
indirect=("config_groups",),
argument_data_set=[
ArgumentData(
id="normal_config",
values=(FAKER.numbers.integer_number(1, 10),),
),
],
),
)
def test_configuration_like_collection(self, config_groups: Sequence[Group]) -> None:
config = Configuration(config_groups)
for group in config_groups:
assert group.name in config
assert len(config) == len(config_groups)
group_names = {group.name for group in config_groups}
for item in config:
assert item in group_names
@pytest.mark.ddt(
TestData(
arguments=("config_groups",),
indirect=("config_groups",),
argument_data_set=[
ArgumentData(
id="normal_config",
values=(FAKER.numbers.integer_number(1, 10),),
),
],
),
)
def test_configuration_repr(self, config_groups: Sequence[Group]) -> None:
config = Configuration(config_groups)
group_template = "{}=Group(name='{}')"
for group in config_groups:
group_str = group_template.format(group.name, group.name)
assert group_str in repr(config)
@pytest.mark.ddt(
TestData(
arguments=("config_groups",),
indirect=("config_groups",),
argument_data_set=[
ArgumentData(
id="normal_config",
values=(FAKER.numbers.integer_number(1, 10),),
),
],
),
)
def test_configuration_keys(self, config_groups: Sequence[Group]) -> None:
config = Configuration(config_groups)
group_names = {group.name for group in config_groups}
for item in config.keys():
assert item in group_names
@pytest.mark.ddt(
TestData(
arguments=("config_groups",),
indirect=("config_groups",),
argument_data_set=[
ArgumentData(
id="normal_config",
values=(FAKER.numbers.integer_number(1, 10),),
),
],
),
)
def test_configuration_values(self, config_groups: Sequence[Group]) -> None:
config = Configuration(config_groups)
groups = {group for group in config_groups}
group_ids = {id(group) for group in config_groups}
for item in config.values():
assert item in groups
assert id(item) in group_ids
@pytest.mark.ddt(
TestData(
arguments=("config_groups",),
indirect=("config_groups",),
argument_data_set=[
ArgumentData(
id="normal_config",
values=(FAKER.numbers.integer_number(1, 10),),
),
],
),
)
def test_configuration_items(self, config_groups: Sequence[Group]) -> None:
config = Configuration(config_groups)
group_names = {group.name for group in config_groups}
groups = {group for group in config_groups}
group_ids = {id(group) for group in config_groups}
for name, item in config.items():
assert name in group_names
assert item in groups
assert id(item) in group_ids

View File

@ -12,8 +12,10 @@
# See the License for the specific language governing permissions and
# limitations under the License.
from __future__ import annotations
from skyline_config import __version__
def test_version():
def test_version() -> None:
assert __version__ == "0.1.0"