From a291b1aabc242269f9cb415ea85a58ec30d7853b Mon Sep 17 00:00:00 2001 From: HSN Date: Thu, 20 Feb 2025 15:55:59 +0600 Subject: [PATCH 01/27] chore: package version update --- poetry.lock | 207 +++++++++++++++++++++---------------------- requirements-dev.txt | 205 +++++++++++++++++++++--------------------- 2 files changed, 201 insertions(+), 211 deletions(-) diff --git a/poetry.lock b/poetry.lock index 3acfca3f..76fd0cc8 100644 --- a/poetry.lock +++ b/poetry.lock @@ -176,73 +176,74 @@ files = [ [[package]] name = "coverage" -version = "7.6.10" +version = "7.6.12" description = "Code coverage measurement for Python" optional = false python-versions = ">=3.9" files = [ - {file = "coverage-7.6.10-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:5c912978f7fbf47ef99cec50c4401340436d200d41d714c7a4766f377c5b7b78"}, - {file = "coverage-7.6.10-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:a01ec4af7dfeb96ff0078ad9a48810bb0cc8abcb0115180c6013a6b26237626c"}, - {file = "coverage-7.6.10-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a3b204c11e2b2d883946fe1d97f89403aa1811df28ce0447439178cc7463448a"}, - {file = "coverage-7.6.10-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:32ee6d8491fcfc82652a37109f69dee9a830e9379166cb73c16d8dc5c2915165"}, - {file = "coverage-7.6.10-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:675cefc4c06e3b4c876b85bfb7c59c5e2218167bbd4da5075cbe3b5790a28988"}, - {file = "coverage-7.6.10-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:f4f620668dbc6f5e909a0946a877310fb3d57aea8198bde792aae369ee1c23b5"}, - {file = "coverage-7.6.10-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:4eea95ef275de7abaef630c9b2c002ffbc01918b726a39f5a4353916ec72d2f3"}, - {file = "coverage-7.6.10-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:e2f0280519e42b0a17550072861e0bc8a80a0870de260f9796157d3fca2733c5"}, - {file = "coverage-7.6.10-cp310-cp310-win32.whl", hash = "sha256:bc67deb76bc3717f22e765ab3e07ee9c7a5e26b9019ca19a3b063d9f4b874244"}, - {file = "coverage-7.6.10-cp310-cp310-win_amd64.whl", hash = "sha256:0f460286cb94036455e703c66988851d970fdfd8acc2a1122ab7f4f904e4029e"}, - {file = "coverage-7.6.10-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:ea3c8f04b3e4af80e17bab607c386a830ffc2fb88a5484e1df756478cf70d1d3"}, - {file = "coverage-7.6.10-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:507a20fc863cae1d5720797761b42d2d87a04b3e5aeb682ef3b7332e90598f43"}, - {file = "coverage-7.6.10-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d37a84878285b903c0fe21ac8794c6dab58150e9359f1aaebbeddd6412d53132"}, - {file = "coverage-7.6.10-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:a534738b47b0de1995f85f582d983d94031dffb48ab86c95bdf88dc62212142f"}, - {file = "coverage-7.6.10-cp311-cp311-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0d7a2bf79378d8fb8afaa994f91bfd8215134f8631d27eba3e0e2c13546ce994"}, - {file = "coverage-7.6.10-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:6713ba4b4ebc330f3def51df1d5d38fad60b66720948112f114968feb52d3f99"}, - {file = "coverage-7.6.10-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:ab32947f481f7e8c763fa2c92fd9f44eeb143e7610c4ca9ecd6a36adab4081bd"}, - {file = "coverage-7.6.10-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:7bbd8c8f1b115b892e34ba66a097b915d3871db7ce0e6b9901f462ff3a975377"}, - {file = "coverage-7.6.10-cp311-cp311-win32.whl", hash = "sha256:299e91b274c5c9cdb64cbdf1b3e4a8fe538a7a86acdd08fae52301b28ba297f8"}, - {file = "coverage-7.6.10-cp311-cp311-win_amd64.whl", hash = "sha256:489a01f94aa581dbd961f306e37d75d4ba16104bbfa2b0edb21d29b73be83609"}, - {file = "coverage-7.6.10-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:27c6e64726b307782fa5cbe531e7647aee385a29b2107cd87ba7c0105a5d3853"}, - {file = "coverage-7.6.10-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:c56e097019e72c373bae32d946ecf9858fda841e48d82df7e81c63ac25554078"}, - {file = "coverage-7.6.10-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c7827a5bc7bdb197b9e066cdf650b2887597ad124dd99777332776f7b7c7d0d0"}, - {file = "coverage-7.6.10-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:204a8238afe787323a8b47d8be4df89772d5c1e4651b9ffa808552bdf20e1d50"}, - {file = "coverage-7.6.10-cp312-cp312-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e67926f51821b8e9deb6426ff3164870976fe414d033ad90ea75e7ed0c2e5022"}, - {file = "coverage-7.6.10-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:e78b270eadb5702938c3dbe9367f878249b5ef9a2fcc5360ac7bff694310d17b"}, - {file = "coverage-7.6.10-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:714f942b9c15c3a7a5fe6876ce30af831c2ad4ce902410b7466b662358c852c0"}, - {file = "coverage-7.6.10-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:abb02e2f5a3187b2ac4cd46b8ced85a0858230b577ccb2c62c81482ca7d18852"}, - {file = "coverage-7.6.10-cp312-cp312-win32.whl", hash = "sha256:55b201b97286cf61f5e76063f9e2a1d8d2972fc2fcfd2c1272530172fd28c359"}, - {file = "coverage-7.6.10-cp312-cp312-win_amd64.whl", hash = "sha256:e4ae5ac5e0d1e4edfc9b4b57b4cbecd5bc266a6915c500f358817a8496739247"}, - {file = "coverage-7.6.10-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:05fca8ba6a87aabdd2d30d0b6c838b50510b56cdcfc604d40760dae7153b73d9"}, - {file = "coverage-7.6.10-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:9e80eba8801c386f72e0712a0453431259c45c3249f0009aff537a517b52942b"}, - {file = "coverage-7.6.10-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a372c89c939d57abe09e08c0578c1d212e7a678135d53aa16eec4430adc5e690"}, - {file = "coverage-7.6.10-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ec22b5e7fe7a0fa8509181c4aac1db48f3dd4d3a566131b313d1efc102892c18"}, - {file = "coverage-7.6.10-cp313-cp313-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:26bcf5c4df41cad1b19c84af71c22cbc9ea9a547fc973f1f2cc9a290002c8b3c"}, - {file = "coverage-7.6.10-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:4e4630c26b6084c9b3cb53b15bd488f30ceb50b73c35c5ad7871b869cb7365fd"}, - {file = "coverage-7.6.10-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:2396e8116db77789f819d2bc8a7e200232b7a282c66e0ae2d2cd84581a89757e"}, - {file = "coverage-7.6.10-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:79109c70cc0882e4d2d002fe69a24aa504dec0cc17169b3c7f41a1d341a73694"}, - {file = "coverage-7.6.10-cp313-cp313-win32.whl", hash = "sha256:9e1747bab246d6ff2c4f28b4d186b205adced9f7bd9dc362051cc37c4a0c7bd6"}, - {file = "coverage-7.6.10-cp313-cp313-win_amd64.whl", hash = "sha256:254f1a3b1eef5f7ed23ef265eaa89c65c8c5b6b257327c149db1ca9d4a35f25e"}, - {file = "coverage-7.6.10-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:2ccf240eb719789cedbb9fd1338055de2761088202a9a0b73032857e53f612fe"}, - {file = "coverage-7.6.10-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:0c807ca74d5a5e64427c8805de15b9ca140bba13572d6d74e262f46f50b13273"}, - {file = "coverage-7.6.10-cp313-cp313t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2bcfa46d7709b5a7ffe089075799b902020b62e7ee56ebaed2f4bdac04c508d8"}, - {file = "coverage-7.6.10-cp313-cp313t-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:4e0de1e902669dccbf80b0415fb6b43d27edca2fbd48c74da378923b05316098"}, - {file = "coverage-7.6.10-cp313-cp313t-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3f7b444c42bbc533aaae6b5a2166fd1a797cdb5eb58ee51a92bee1eb94a1e1cb"}, - {file = "coverage-7.6.10-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:b330368cb99ef72fcd2dc3ed260adf67b31499584dc8a20225e85bfe6f6cfed0"}, - {file = "coverage-7.6.10-cp313-cp313t-musllinux_1_2_i686.whl", hash = "sha256:9a7cfb50515f87f7ed30bc882f68812fd98bc2852957df69f3003d22a2aa0abf"}, - {file = "coverage-7.6.10-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:6f93531882a5f68c28090f901b1d135de61b56331bba82028489bc51bdd818d2"}, - {file = "coverage-7.6.10-cp313-cp313t-win32.whl", hash = "sha256:89d76815a26197c858f53c7f6a656686ec392b25991f9e409bcef020cd532312"}, - {file = "coverage-7.6.10-cp313-cp313t-win_amd64.whl", hash = "sha256:54a5f0f43950a36312155dae55c505a76cd7f2b12d26abeebbe7a0b36dbc868d"}, - {file = "coverage-7.6.10-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:656c82b8a0ead8bba147de9a89bda95064874c91a3ed43a00e687f23cc19d53a"}, - {file = "coverage-7.6.10-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:ccc2b70a7ed475c68ceb548bf69cec1e27305c1c2606a5eb7c3afff56a1b3b27"}, - {file = "coverage-7.6.10-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a5e37dc41d57ceba70956fa2fc5b63c26dba863c946ace9705f8eca99daecdc4"}, - {file = "coverage-7.6.10-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:0aa9692b4fdd83a4647eeb7db46410ea1322b5ed94cd1715ef09d1d5922ba87f"}, - {file = "coverage-7.6.10-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:aa744da1820678b475e4ba3dfd994c321c5b13381d1041fe9c608620e6676e25"}, - {file = "coverage-7.6.10-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:c0b1818063dc9e9d838c09e3a473c1422f517889436dd980f5d721899e66f315"}, - {file = "coverage-7.6.10-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:59af35558ba08b758aec4d56182b222976330ef8d2feacbb93964f576a7e7a90"}, - {file = "coverage-7.6.10-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:7ed2f37cfce1ce101e6dffdfd1c99e729dd2ffc291d02d3e2d0af8b53d13840d"}, - {file = "coverage-7.6.10-cp39-cp39-win32.whl", hash = "sha256:4bcc276261505d82f0ad426870c3b12cb177752834a633e737ec5ee79bbdff18"}, - {file = "coverage-7.6.10-cp39-cp39-win_amd64.whl", hash = "sha256:457574f4599d2b00f7f637a0700a6422243b3565509457b2dbd3f50703e11f59"}, - {file = "coverage-7.6.10-pp39.pp310-none-any.whl", hash = "sha256:fd34e7b3405f0cc7ab03d54a334c17a9e802897580d964bd8c2001f4b9fd488f"}, - {file = "coverage-7.6.10.tar.gz", hash = "sha256:7fb105327c8f8f0682e29843e2ff96af9dcbe5bab8eeb4b398c6a33a16d80a23"}, + {file = "coverage-7.6.12-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:704c8c8c6ce6569286ae9622e534b4f5b9759b6f2cd643f1c1a61f666d534fe8"}, + {file = "coverage-7.6.12-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:ad7525bf0241e5502168ae9c643a2f6c219fa0a283001cee4cf23a9b7da75879"}, + {file = "coverage-7.6.12-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:06097c7abfa611c91edb9e6920264e5be1d6ceb374efb4986f38b09eed4cb2fe"}, + {file = "coverage-7.6.12-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:220fa6c0ad7d9caef57f2c8771918324563ef0d8272c94974717c3909664e674"}, + {file = "coverage-7.6.12-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3688b99604a24492bcfe1c106278c45586eb819bf66a654d8a9a1433022fb2eb"}, + {file = "coverage-7.6.12-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:d1a987778b9c71da2fc8948e6f2656da6ef68f59298b7e9786849634c35d2c3c"}, + {file = "coverage-7.6.12-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:cec6b9ce3bd2b7853d4a4563801292bfee40b030c05a3d29555fd2a8ee9bd68c"}, + {file = "coverage-7.6.12-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:ace9048de91293e467b44bce0f0381345078389814ff6e18dbac8fdbf896360e"}, + {file = "coverage-7.6.12-cp310-cp310-win32.whl", hash = "sha256:ea31689f05043d520113e0552f039603c4dd71fa4c287b64cb3606140c66f425"}, + {file = "coverage-7.6.12-cp310-cp310-win_amd64.whl", hash = "sha256:676f92141e3c5492d2a1596d52287d0d963df21bf5e55c8b03075a60e1ddf8aa"}, + {file = "coverage-7.6.12-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:e18aafdfb3e9ec0d261c942d35bd7c28d031c5855dadb491d2723ba54f4c3015"}, + {file = "coverage-7.6.12-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:66fe626fd7aa5982cdebad23e49e78ef7dbb3e3c2a5960a2b53632f1f703ea45"}, + {file = "coverage-7.6.12-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0ef01d70198431719af0b1f5dcbefc557d44a190e749004042927b2a3fed0702"}, + {file = "coverage-7.6.12-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:07e92ae5a289a4bc4c0aae710c0948d3c7892e20fd3588224ebe242039573bf0"}, + {file = "coverage-7.6.12-cp311-cp311-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e695df2c58ce526eeab11a2e915448d3eb76f75dffe338ea613c1201b33bab2f"}, + {file = "coverage-7.6.12-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:d74c08e9aaef995f8c4ef6d202dbd219c318450fe2a76da624f2ebb9c8ec5d9f"}, + {file = "coverage-7.6.12-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:e995b3b76ccedc27fe4f477b349b7d64597e53a43fc2961db9d3fbace085d69d"}, + {file = "coverage-7.6.12-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:b1f097878d74fe51e1ddd1be62d8e3682748875b461232cf4b52ddc6e6db0bba"}, + {file = "coverage-7.6.12-cp311-cp311-win32.whl", hash = "sha256:1f7ffa05da41754e20512202c866d0ebfc440bba3b0ed15133070e20bf5aeb5f"}, + {file = "coverage-7.6.12-cp311-cp311-win_amd64.whl", hash = "sha256:e216c5c45f89ef8971373fd1c5d8d1164b81f7f5f06bbf23c37e7908d19e8558"}, + {file = "coverage-7.6.12-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:b172f8e030e8ef247b3104902cc671e20df80163b60a203653150d2fc204d1ad"}, + {file = "coverage-7.6.12-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:641dfe0ab73deb7069fb972d4d9725bf11c239c309ce694dd50b1473c0f641c3"}, + {file = "coverage-7.6.12-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0e549f54ac5f301e8e04c569dfdb907f7be71b06b88b5063ce9d6953d2d58574"}, + {file = "coverage-7.6.12-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:959244a17184515f8c52dcb65fb662808767c0bd233c1d8a166e7cf74c9ea985"}, + {file = "coverage-7.6.12-cp312-cp312-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bda1c5f347550c359f841d6614fb8ca42ae5cb0b74d39f8a1e204815ebe25750"}, + {file = "coverage-7.6.12-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:1ceeb90c3eda1f2d8c4c578c14167dbd8c674ecd7d38e45647543f19839dd6ea"}, + {file = "coverage-7.6.12-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:0f16f44025c06792e0fb09571ae454bcc7a3ec75eeb3c36b025eccf501b1a4c3"}, + {file = "coverage-7.6.12-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:b076e625396e787448d27a411aefff867db2bffac8ed04e8f7056b07024eed5a"}, + {file = "coverage-7.6.12-cp312-cp312-win32.whl", hash = "sha256:00b2086892cf06c7c2d74983c9595dc511acca00665480b3ddff749ec4fb2a95"}, + {file = "coverage-7.6.12-cp312-cp312-win_amd64.whl", hash = "sha256:7ae6eabf519bc7871ce117fb18bf14e0e343eeb96c377667e3e5dd12095e0288"}, + {file = "coverage-7.6.12-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:488c27b3db0ebee97a830e6b5a3ea930c4a6e2c07f27a5e67e1b3532e76b9ef1"}, + {file = "coverage-7.6.12-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:5d1095bbee1851269f79fd8e0c9b5544e4c00c0c24965e66d8cba2eb5bb535fd"}, + {file = "coverage-7.6.12-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0533adc29adf6a69c1baa88c3d7dbcaadcffa21afbed3ca7a225a440e4744bf9"}, + {file = "coverage-7.6.12-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:53c56358d470fa507a2b6e67a68fd002364d23c83741dbc4c2e0680d80ca227e"}, + {file = "coverage-7.6.12-cp313-cp313-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:64cbb1a3027c79ca6310bf101014614f6e6e18c226474606cf725238cf5bc2d4"}, + {file = "coverage-7.6.12-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:79cac3390bfa9836bb795be377395f28410811c9066bc4eefd8015258a7578c6"}, + {file = "coverage-7.6.12-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:9b148068e881faa26d878ff63e79650e208e95cf1c22bd3f77c3ca7b1d9821a3"}, + {file = "coverage-7.6.12-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:8bec2ac5da793c2685ce5319ca9bcf4eee683b8a1679051f8e6ec04c4f2fd7dc"}, + {file = "coverage-7.6.12-cp313-cp313-win32.whl", hash = "sha256:200e10beb6ddd7c3ded322a4186313d5ca9e63e33d8fab4faa67ef46d3460af3"}, + {file = "coverage-7.6.12-cp313-cp313-win_amd64.whl", hash = "sha256:2b996819ced9f7dbb812c701485d58f261bef08f9b85304d41219b1496b591ef"}, + {file = "coverage-7.6.12-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:299cf973a7abff87a30609879c10df0b3bfc33d021e1adabc29138a48888841e"}, + {file = "coverage-7.6.12-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:4b467a8c56974bf06e543e69ad803c6865249d7a5ccf6980457ed2bc50312703"}, + {file = "coverage-7.6.12-cp313-cp313t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2458f275944db8129f95d91aee32c828a408481ecde3b30af31d552c2ce284a0"}, + {file = "coverage-7.6.12-cp313-cp313t-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:0a9d8be07fb0832636a0f72b80d2a652fe665e80e720301fb22b191c3434d924"}, + {file = "coverage-7.6.12-cp313-cp313t-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:14d47376a4f445e9743f6c83291e60adb1b127607a3618e3185bbc8091f0467b"}, + {file = "coverage-7.6.12-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:b95574d06aa9d2bd6e5cc35a5bbe35696342c96760b69dc4287dbd5abd4ad51d"}, + {file = "coverage-7.6.12-cp313-cp313t-musllinux_1_2_i686.whl", hash = "sha256:ecea0c38c9079570163d663c0433a9af4094a60aafdca491c6a3d248c7432827"}, + {file = "coverage-7.6.12-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:2251fabcfee0a55a8578a9d29cecfee5f2de02f11530e7d5c5a05859aa85aee9"}, + {file = "coverage-7.6.12-cp313-cp313t-win32.whl", hash = "sha256:eb5507795caabd9b2ae3f1adc95f67b1104971c22c624bb354232d65c4fc90b3"}, + {file = "coverage-7.6.12-cp313-cp313t-win_amd64.whl", hash = "sha256:f60a297c3987c6c02ffb29effc70eadcbb412fe76947d394a1091a3615948e2f"}, + {file = "coverage-7.6.12-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:e7575ab65ca8399c8c4f9a7d61bbd2d204c8b8e447aab9d355682205c9dd948d"}, + {file = "coverage-7.6.12-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:8161d9fbc7e9fe2326de89cd0abb9f3599bccc1287db0aba285cb68d204ce929"}, + {file = "coverage-7.6.12-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3a1e465f398c713f1b212400b4e79a09829cd42aebd360362cd89c5bdc44eb87"}, + {file = "coverage-7.6.12-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:f25d8b92a4e31ff1bd873654ec367ae811b3a943583e05432ea29264782dc32c"}, + {file = "coverage-7.6.12-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:1a936309a65cc5ca80fa9f20a442ff9e2d06927ec9a4f54bcba9c14c066323f2"}, + {file = "coverage-7.6.12-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:aa6f302a3a0b5f240ee201297fff0bbfe2fa0d415a94aeb257d8b461032389bd"}, + {file = "coverage-7.6.12-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:f973643ef532d4f9be71dd88cf7588936685fdb576d93a79fe9f65bc337d9d73"}, + {file = "coverage-7.6.12-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:78f5243bb6b1060aed6213d5107744c19f9571ec76d54c99cc15938eb69e0e86"}, + {file = "coverage-7.6.12-cp39-cp39-win32.whl", hash = "sha256:69e62c5034291c845fc4df7f8155e8544178b6c774f97a99e2734b05eb5bed31"}, + {file = "coverage-7.6.12-cp39-cp39-win_amd64.whl", hash = "sha256:b01a840ecc25dce235ae4c1b6a0daefb2a203dba0e6e980637ee9c2f6ee0df57"}, + {file = "coverage-7.6.12-pp39.pp310-none-any.whl", hash = "sha256:7e39e845c4d764208e7b8f6a21c541ade741e2c41afabdfa1caa28687a3c98cf"}, + {file = "coverage-7.6.12-py3-none-any.whl", hash = "sha256:eb8668cfbc279a536c633137deeb9435d2962caec279c3f8cf8b91fff6ff8953"}, + {file = "coverage-7.6.12.tar.gz", hash = "sha256:48cfc4641d95d34766ad41d9573cc0f22a48aa88d22657a1fe01dca0dbae4de2"}, ] [package.extras] @@ -422,49 +423,43 @@ files = [ [[package]] name = "mypy" -version = "1.14.1" +version = "1.15.0" description = "Optional static typing for Python" optional = false -python-versions = ">=3.8" +python-versions = ">=3.9" files = [ - {file = "mypy-1.14.1-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:52686e37cf13d559f668aa398dd7ddf1f92c5d613e4f8cb262be2fb4fedb0fcb"}, - {file = "mypy-1.14.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:1fb545ca340537d4b45d3eecdb3def05e913299ca72c290326be19b3804b39c0"}, - {file = "mypy-1.14.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:90716d8b2d1f4cd503309788e51366f07c56635a3309b0f6a32547eaaa36a64d"}, - {file = "mypy-1.14.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:2ae753f5c9fef278bcf12e1a564351764f2a6da579d4a81347e1d5a15819997b"}, - {file = "mypy-1.14.1-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:e0fe0f5feaafcb04505bcf439e991c6d8f1bf8b15f12b05feeed96e9e7bf1427"}, - {file = "mypy-1.14.1-cp310-cp310-win_amd64.whl", hash = "sha256:7d54bd85b925e501c555a3227f3ec0cfc54ee8b6930bd6141ec872d1c572f81f"}, - {file = "mypy-1.14.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:f995e511de847791c3b11ed90084a7a0aafdc074ab88c5a9711622fe4751138c"}, - {file = "mypy-1.14.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:d64169ec3b8461311f8ce2fd2eb5d33e2d0f2c7b49116259c51d0d96edee48d1"}, - {file = "mypy-1.14.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:ba24549de7b89b6381b91fbc068d798192b1b5201987070319889e93038967a8"}, - {file = "mypy-1.14.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:183cf0a45457d28ff9d758730cd0210419ac27d4d3f285beda038c9083363b1f"}, - {file = "mypy-1.14.1-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:f2a0ecc86378f45347f586e4163d1769dd81c5a223d577fe351f26b179e148b1"}, - {file = "mypy-1.14.1-cp311-cp311-win_amd64.whl", hash = "sha256:ad3301ebebec9e8ee7135d8e3109ca76c23752bac1e717bc84cd3836b4bf3eae"}, - {file = "mypy-1.14.1-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:30ff5ef8519bbc2e18b3b54521ec319513a26f1bba19a7582e7b1f58a6e69f14"}, - {file = "mypy-1.14.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:cb9f255c18052343c70234907e2e532bc7e55a62565d64536dbc7706a20b78b9"}, - {file = "mypy-1.14.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:8b4e3413e0bddea671012b063e27591b953d653209e7a4fa5e48759cda77ca11"}, - {file = "mypy-1.14.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:553c293b1fbdebb6c3c4030589dab9fafb6dfa768995a453d8a5d3b23784af2e"}, - {file = "mypy-1.14.1-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:fad79bfe3b65fe6a1efaed97b445c3d37f7be9fdc348bdb2d7cac75579607c89"}, - {file = "mypy-1.14.1-cp312-cp312-win_amd64.whl", hash = "sha256:8fa2220e54d2946e94ab6dbb3ba0a992795bd68b16dc852db33028df2b00191b"}, - {file = "mypy-1.14.1-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:92c3ed5afb06c3a8e188cb5da4984cab9ec9a77ba956ee419c68a388b4595255"}, - {file = "mypy-1.14.1-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:dbec574648b3e25f43d23577309b16534431db4ddc09fda50841f1e34e64ed34"}, - {file = "mypy-1.14.1-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:8c6d94b16d62eb3e947281aa7347d78236688e21081f11de976376cf010eb31a"}, - {file = "mypy-1.14.1-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:d4b19b03fdf54f3c5b2fa474c56b4c13c9dbfb9a2db4370ede7ec11a2c5927d9"}, - {file = "mypy-1.14.1-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:0c911fde686394753fff899c409fd4e16e9b294c24bfd5e1ea4675deae1ac6fd"}, - {file = "mypy-1.14.1-cp313-cp313-win_amd64.whl", hash = "sha256:8b21525cb51671219f5307be85f7e646a153e5acc656e5cebf64bfa076c50107"}, - {file = "mypy-1.14.1-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:7084fb8f1128c76cd9cf68fe5971b37072598e7c31b2f9f95586b65c741a9d31"}, - {file = "mypy-1.14.1-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:8f845a00b4f420f693f870eaee5f3e2692fa84cc8514496114649cfa8fd5e2c6"}, - {file = "mypy-1.14.1-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:44bf464499f0e3a2d14d58b54674dee25c031703b2ffc35064bd0df2e0fac319"}, - {file = "mypy-1.14.1-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:c99f27732c0b7dc847adb21c9d47ce57eb48fa33a17bc6d7d5c5e9f9e7ae5bac"}, - {file = "mypy-1.14.1-cp38-cp38-musllinux_1_2_x86_64.whl", hash = "sha256:bce23c7377b43602baa0bd22ea3265c49b9ff0b76eb315d6c34721af4cdf1d9b"}, - {file = "mypy-1.14.1-cp38-cp38-win_amd64.whl", hash = "sha256:8edc07eeade7ebc771ff9cf6b211b9a7d93687ff892150cb5692e4f4272b0837"}, - {file = "mypy-1.14.1-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:3888a1816d69f7ab92092f785a462944b3ca16d7c470d564165fe703b0970c35"}, - {file = "mypy-1.14.1-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:46c756a444117c43ee984bd055db99e498bc613a70bbbc120272bd13ca579fbc"}, - {file = "mypy-1.14.1-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:27fc248022907e72abfd8e22ab1f10e903915ff69961174784a3900a8cba9ad9"}, - {file = "mypy-1.14.1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:499d6a72fb7e5de92218db961f1a66d5f11783f9ae549d214617edab5d4dbdbb"}, - {file = "mypy-1.14.1-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:57961db9795eb566dc1d1b4e9139ebc4c6b0cb6e7254ecde69d1552bf7613f60"}, - {file = "mypy-1.14.1-cp39-cp39-win_amd64.whl", hash = "sha256:07ba89fdcc9451f2ebb02853deb6aaaa3d2239a236669a63ab3801bbf923ef5c"}, - {file = "mypy-1.14.1-py3-none-any.whl", hash = "sha256:b66a60cc4073aeb8ae00057f9c1f64d49e90f918fbcef9a977eb121da8b8f1d1"}, - {file = "mypy-1.14.1.tar.gz", hash = "sha256:7ec88144fe9b510e8475ec2f5f251992690fcf89ccb4500b214b4226abcd32d6"}, + {file = "mypy-1.15.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:979e4e1a006511dacf628e36fadfecbcc0160a8af6ca7dad2f5025529e082c13"}, + {file = "mypy-1.15.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:c4bb0e1bd29f7d34efcccd71cf733580191e9a264a2202b0239da95984c5b559"}, + {file = "mypy-1.15.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:be68172e9fd9ad8fb876c6389f16d1c1b5f100ffa779f77b1fb2176fcc9ab95b"}, + {file = "mypy-1.15.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:c7be1e46525adfa0d97681432ee9fcd61a3964c2446795714699a998d193f1a3"}, + {file = "mypy-1.15.0-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:2e2c2e6d3593f6451b18588848e66260ff62ccca522dd231cd4dd59b0160668b"}, + {file = "mypy-1.15.0-cp310-cp310-win_amd64.whl", hash = "sha256:6983aae8b2f653e098edb77f893f7b6aca69f6cffb19b2cc7443f23cce5f4828"}, + {file = "mypy-1.15.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:2922d42e16d6de288022e5ca321cd0618b238cfc5570e0263e5ba0a77dbef56f"}, + {file = "mypy-1.15.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:2ee2d57e01a7c35de00f4634ba1bbf015185b219e4dc5909e281016df43f5ee5"}, + {file = "mypy-1.15.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:973500e0774b85d9689715feeffcc980193086551110fd678ebe1f4342fb7c5e"}, + {file = "mypy-1.15.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:5a95fb17c13e29d2d5195869262f8125dfdb5c134dc8d9a9d0aecf7525b10c2c"}, + {file = "mypy-1.15.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:1905f494bfd7d85a23a88c5d97840888a7bd516545fc5aaedff0267e0bb54e2f"}, + {file = "mypy-1.15.0-cp311-cp311-win_amd64.whl", hash = "sha256:c9817fa23833ff189db061e6d2eff49b2f3b6ed9856b4a0a73046e41932d744f"}, + {file = "mypy-1.15.0-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:aea39e0583d05124836ea645f412e88a5c7d0fd77a6d694b60d9b6b2d9f184fd"}, + {file = "mypy-1.15.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:2f2147ab812b75e5b5499b01ade1f4a81489a147c01585cda36019102538615f"}, + {file = "mypy-1.15.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:ce436f4c6d218a070048ed6a44c0bbb10cd2cc5e272b29e7845f6a2f57ee4464"}, + {file = "mypy-1.15.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:8023ff13985661b50a5928fc7a5ca15f3d1affb41e5f0a9952cb68ef090b31ee"}, + {file = "mypy-1.15.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:1124a18bc11a6a62887e3e137f37f53fbae476dc36c185d549d4f837a2a6a14e"}, + {file = "mypy-1.15.0-cp312-cp312-win_amd64.whl", hash = "sha256:171a9ca9a40cd1843abeca0e405bc1940cd9b305eaeea2dda769ba096932bb22"}, + {file = "mypy-1.15.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:93faf3fdb04768d44bf28693293f3904bbb555d076b781ad2530214ee53e3445"}, + {file = "mypy-1.15.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:811aeccadfb730024c5d3e326b2fbe9249bb7413553f15499a4050f7c30e801d"}, + {file = "mypy-1.15.0-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:98b7b9b9aedb65fe628c62a6dc57f6d5088ef2dfca37903a7d9ee374d03acca5"}, + {file = "mypy-1.15.0-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:c43a7682e24b4f576d93072216bf56eeff70d9140241f9edec0c104d0c515036"}, + {file = "mypy-1.15.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:baefc32840a9f00babd83251560e0ae1573e2f9d1b067719479bfb0e987c6357"}, + {file = "mypy-1.15.0-cp313-cp313-win_amd64.whl", hash = "sha256:b9378e2c00146c44793c98b8d5a61039a048e31f429fb0eb546d93f4b000bedf"}, + {file = "mypy-1.15.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:e601a7fa172c2131bff456bb3ee08a88360760d0d2f8cbd7a75a65497e2df078"}, + {file = "mypy-1.15.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:712e962a6357634fef20412699a3655c610110e01cdaa6180acec7fc9f8513ba"}, + {file = "mypy-1.15.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:f95579473af29ab73a10bada2f9722856792a36ec5af5399b653aa28360290a5"}, + {file = "mypy-1.15.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:8f8722560a14cde92fdb1e31597760dc35f9f5524cce17836c0d22841830fd5b"}, + {file = "mypy-1.15.0-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:1fbb8da62dc352133d7d7ca90ed2fb0e9d42bb1a32724c287d3c76c58cbaa9c2"}, + {file = "mypy-1.15.0-cp39-cp39-win_amd64.whl", hash = "sha256:d10d994b41fb3497719bbf866f227b3489048ea4bbbb5015357db306249f7980"}, + {file = "mypy-1.15.0-py3-none-any.whl", hash = "sha256:5469affef548bd1895d86d3bf10ce2b44e33d86923c29e4d675b3e323437ea3e"}, + {file = "mypy-1.15.0.tar.gz", hash = "sha256:404534629d51d3efea5c800ee7c42b72a6554d6c400e6a79eafe15d11341fd43"}, ] [package.dependencies] @@ -502,13 +497,13 @@ files = [ [[package]] name = "pip" -version = "25.0" +version = "25.0.1" description = "The PyPA recommended tool for installing Python packages." optional = false python-versions = ">=3.8" files = [ - {file = "pip-25.0-py3-none-any.whl", hash = "sha256:b6eb97a803356a52b2dd4bb73ba9e65b2ba16caa6bcb25a7497350a4e5859b65"}, - {file = "pip-25.0.tar.gz", hash = "sha256:8e0a97f7b4c47ae4a494560da84775e9e2f671d415d8d828e052efefb206b30b"}, + {file = "pip-25.0.1-py3-none-any.whl", hash = "sha256:c46efd13b6aa8279f33f2864459c8ce587ea6a1a59ee20de055868d8f7688f7f"}, + {file = "pip-25.0.1.tar.gz", hash = "sha256:88f96547ea48b940a3a385494e181e29fb8637898f88d88737c5049780f196ea"}, ] [[package]] diff --git a/requirements-dev.txt b/requirements-dev.txt index 29b227cf..792faf96 100644 --- a/requirements-dev.txt +++ b/requirements-dev.txt @@ -109,69 +109,70 @@ click==8.1.8 ; python_version >= "3.13" and python_version < "4.0" \ colorama==0.4.6 ; python_version >= "3.13" and python_version < "4.0" \ --hash=sha256:08695f5cb7ed6e0531a20572697297273c47b8cae5a63ffc6d6ed5c201be6e44 \ --hash=sha256:4f1d9991f5acc0ca119f9d443620b77f9d6b33703e51011c16baf57afb285fc6 -coverage[toml]==7.6.10 ; python_version >= "3.13" and python_version < "4.0" \ - --hash=sha256:05fca8ba6a87aabdd2d30d0b6c838b50510b56cdcfc604d40760dae7153b73d9 \ - --hash=sha256:0aa9692b4fdd83a4647eeb7db46410ea1322b5ed94cd1715ef09d1d5922ba87f \ - --hash=sha256:0c807ca74d5a5e64427c8805de15b9ca140bba13572d6d74e262f46f50b13273 \ - --hash=sha256:0d7a2bf79378d8fb8afaa994f91bfd8215134f8631d27eba3e0e2c13546ce994 \ - --hash=sha256:0f460286cb94036455e703c66988851d970fdfd8acc2a1122ab7f4f904e4029e \ - --hash=sha256:204a8238afe787323a8b47d8be4df89772d5c1e4651b9ffa808552bdf20e1d50 \ - --hash=sha256:2396e8116db77789f819d2bc8a7e200232b7a282c66e0ae2d2cd84581a89757e \ - --hash=sha256:254f1a3b1eef5f7ed23ef265eaa89c65c8c5b6b257327c149db1ca9d4a35f25e \ - --hash=sha256:26bcf5c4df41cad1b19c84af71c22cbc9ea9a547fc973f1f2cc9a290002c8b3c \ - --hash=sha256:27c6e64726b307782fa5cbe531e7647aee385a29b2107cd87ba7c0105a5d3853 \ - --hash=sha256:299e91b274c5c9cdb64cbdf1b3e4a8fe538a7a86acdd08fae52301b28ba297f8 \ - --hash=sha256:2bcfa46d7709b5a7ffe089075799b902020b62e7ee56ebaed2f4bdac04c508d8 \ - --hash=sha256:2ccf240eb719789cedbb9fd1338055de2761088202a9a0b73032857e53f612fe \ - --hash=sha256:32ee6d8491fcfc82652a37109f69dee9a830e9379166cb73c16d8dc5c2915165 \ - --hash=sha256:3f7b444c42bbc533aaae6b5a2166fd1a797cdb5eb58ee51a92bee1eb94a1e1cb \ - --hash=sha256:457574f4599d2b00f7f637a0700a6422243b3565509457b2dbd3f50703e11f59 \ - --hash=sha256:489a01f94aa581dbd961f306e37d75d4ba16104bbfa2b0edb21d29b73be83609 \ - --hash=sha256:4bcc276261505d82f0ad426870c3b12cb177752834a633e737ec5ee79bbdff18 \ - --hash=sha256:4e0de1e902669dccbf80b0415fb6b43d27edca2fbd48c74da378923b05316098 \ - --hash=sha256:4e4630c26b6084c9b3cb53b15bd488f30ceb50b73c35c5ad7871b869cb7365fd \ - --hash=sha256:4eea95ef275de7abaef630c9b2c002ffbc01918b726a39f5a4353916ec72d2f3 \ - --hash=sha256:507a20fc863cae1d5720797761b42d2d87a04b3e5aeb682ef3b7332e90598f43 \ - --hash=sha256:54a5f0f43950a36312155dae55c505a76cd7f2b12d26abeebbe7a0b36dbc868d \ - --hash=sha256:55b201b97286cf61f5e76063f9e2a1d8d2972fc2fcfd2c1272530172fd28c359 \ - --hash=sha256:59af35558ba08b758aec4d56182b222976330ef8d2feacbb93964f576a7e7a90 \ - --hash=sha256:5c912978f7fbf47ef99cec50c4401340436d200d41d714c7a4766f377c5b7b78 \ - --hash=sha256:656c82b8a0ead8bba147de9a89bda95064874c91a3ed43a00e687f23cc19d53a \ - --hash=sha256:6713ba4b4ebc330f3def51df1d5d38fad60b66720948112f114968feb52d3f99 \ - --hash=sha256:675cefc4c06e3b4c876b85bfb7c59c5e2218167bbd4da5075cbe3b5790a28988 \ - --hash=sha256:6f93531882a5f68c28090f901b1d135de61b56331bba82028489bc51bdd818d2 \ - --hash=sha256:714f942b9c15c3a7a5fe6876ce30af831c2ad4ce902410b7466b662358c852c0 \ - --hash=sha256:79109c70cc0882e4d2d002fe69a24aa504dec0cc17169b3c7f41a1d341a73694 \ - --hash=sha256:7bbd8c8f1b115b892e34ba66a097b915d3871db7ce0e6b9901f462ff3a975377 \ - --hash=sha256:7ed2f37cfce1ce101e6dffdfd1c99e729dd2ffc291d02d3e2d0af8b53d13840d \ - --hash=sha256:7fb105327c8f8f0682e29843e2ff96af9dcbe5bab8eeb4b398c6a33a16d80a23 \ - --hash=sha256:89d76815a26197c858f53c7f6a656686ec392b25991f9e409bcef020cd532312 \ - --hash=sha256:9a7cfb50515f87f7ed30bc882f68812fd98bc2852957df69f3003d22a2aa0abf \ - --hash=sha256:9e1747bab246d6ff2c4f28b4d186b205adced9f7bd9dc362051cc37c4a0c7bd6 \ - --hash=sha256:9e80eba8801c386f72e0712a0453431259c45c3249f0009aff537a517b52942b \ - --hash=sha256:a01ec4af7dfeb96ff0078ad9a48810bb0cc8abcb0115180c6013a6b26237626c \ - --hash=sha256:a372c89c939d57abe09e08c0578c1d212e7a678135d53aa16eec4430adc5e690 \ - --hash=sha256:a3b204c11e2b2d883946fe1d97f89403aa1811df28ce0447439178cc7463448a \ - --hash=sha256:a534738b47b0de1995f85f582d983d94031dffb48ab86c95bdf88dc62212142f \ - --hash=sha256:a5e37dc41d57ceba70956fa2fc5b63c26dba863c946ace9705f8eca99daecdc4 \ - --hash=sha256:aa744da1820678b475e4ba3dfd994c321c5b13381d1041fe9c608620e6676e25 \ - --hash=sha256:ab32947f481f7e8c763fa2c92fd9f44eeb143e7610c4ca9ecd6a36adab4081bd \ - --hash=sha256:abb02e2f5a3187b2ac4cd46b8ced85a0858230b577ccb2c62c81482ca7d18852 \ - --hash=sha256:b330368cb99ef72fcd2dc3ed260adf67b31499584dc8a20225e85bfe6f6cfed0 \ - --hash=sha256:bc67deb76bc3717f22e765ab3e07ee9c7a5e26b9019ca19a3b063d9f4b874244 \ - --hash=sha256:c0b1818063dc9e9d838c09e3a473c1422f517889436dd980f5d721899e66f315 \ - --hash=sha256:c56e097019e72c373bae32d946ecf9858fda841e48d82df7e81c63ac25554078 \ - --hash=sha256:c7827a5bc7bdb197b9e066cdf650b2887597ad124dd99777332776f7b7c7d0d0 \ - --hash=sha256:ccc2b70a7ed475c68ceb548bf69cec1e27305c1c2606a5eb7c3afff56a1b3b27 \ - --hash=sha256:d37a84878285b903c0fe21ac8794c6dab58150e9359f1aaebbeddd6412d53132 \ - --hash=sha256:e2f0280519e42b0a17550072861e0bc8a80a0870de260f9796157d3fca2733c5 \ - --hash=sha256:e4ae5ac5e0d1e4edfc9b4b57b4cbecd5bc266a6915c500f358817a8496739247 \ - --hash=sha256:e67926f51821b8e9deb6426ff3164870976fe414d033ad90ea75e7ed0c2e5022 \ - --hash=sha256:e78b270eadb5702938c3dbe9367f878249b5ef9a2fcc5360ac7bff694310d17b \ - --hash=sha256:ea3c8f04b3e4af80e17bab607c386a830ffc2fb88a5484e1df756478cf70d1d3 \ - --hash=sha256:ec22b5e7fe7a0fa8509181c4aac1db48f3dd4d3a566131b313d1efc102892c18 \ - --hash=sha256:f4f620668dbc6f5e909a0946a877310fb3d57aea8198bde792aae369ee1c23b5 \ - --hash=sha256:fd34e7b3405f0cc7ab03d54a334c17a9e802897580d964bd8c2001f4b9fd488f +coverage[toml]==7.6.12 ; python_version >= "3.13" and python_version < "4.0" \ + --hash=sha256:00b2086892cf06c7c2d74983c9595dc511acca00665480b3ddff749ec4fb2a95 \ + --hash=sha256:0533adc29adf6a69c1baa88c3d7dbcaadcffa21afbed3ca7a225a440e4744bf9 \ + --hash=sha256:06097c7abfa611c91edb9e6920264e5be1d6ceb374efb4986f38b09eed4cb2fe \ + --hash=sha256:07e92ae5a289a4bc4c0aae710c0948d3c7892e20fd3588224ebe242039573bf0 \ + --hash=sha256:0a9d8be07fb0832636a0f72b80d2a652fe665e80e720301fb22b191c3434d924 \ + --hash=sha256:0e549f54ac5f301e8e04c569dfdb907f7be71b06b88b5063ce9d6953d2d58574 \ + --hash=sha256:0ef01d70198431719af0b1f5dcbefc557d44a190e749004042927b2a3fed0702 \ + --hash=sha256:0f16f44025c06792e0fb09571ae454bcc7a3ec75eeb3c36b025eccf501b1a4c3 \ + --hash=sha256:14d47376a4f445e9743f6c83291e60adb1b127607a3618e3185bbc8091f0467b \ + --hash=sha256:1a936309a65cc5ca80fa9f20a442ff9e2d06927ec9a4f54bcba9c14c066323f2 \ + --hash=sha256:1ceeb90c3eda1f2d8c4c578c14167dbd8c674ecd7d38e45647543f19839dd6ea \ + --hash=sha256:1f7ffa05da41754e20512202c866d0ebfc440bba3b0ed15133070e20bf5aeb5f \ + --hash=sha256:200e10beb6ddd7c3ded322a4186313d5ca9e63e33d8fab4faa67ef46d3460af3 \ + --hash=sha256:220fa6c0ad7d9caef57f2c8771918324563ef0d8272c94974717c3909664e674 \ + --hash=sha256:2251fabcfee0a55a8578a9d29cecfee5f2de02f11530e7d5c5a05859aa85aee9 \ + --hash=sha256:2458f275944db8129f95d91aee32c828a408481ecde3b30af31d552c2ce284a0 \ + --hash=sha256:299cf973a7abff87a30609879c10df0b3bfc33d021e1adabc29138a48888841e \ + --hash=sha256:2b996819ced9f7dbb812c701485d58f261bef08f9b85304d41219b1496b591ef \ + --hash=sha256:3688b99604a24492bcfe1c106278c45586eb819bf66a654d8a9a1433022fb2eb \ + --hash=sha256:3a1e465f398c713f1b212400b4e79a09829cd42aebd360362cd89c5bdc44eb87 \ + --hash=sha256:488c27b3db0ebee97a830e6b5a3ea930c4a6e2c07f27a5e67e1b3532e76b9ef1 \ + --hash=sha256:48cfc4641d95d34766ad41d9573cc0f22a48aa88d22657a1fe01dca0dbae4de2 \ + --hash=sha256:4b467a8c56974bf06e543e69ad803c6865249d7a5ccf6980457ed2bc50312703 \ + --hash=sha256:53c56358d470fa507a2b6e67a68fd002364d23c83741dbc4c2e0680d80ca227e \ + --hash=sha256:5d1095bbee1851269f79fd8e0c9b5544e4c00c0c24965e66d8cba2eb5bb535fd \ + --hash=sha256:641dfe0ab73deb7069fb972d4d9725bf11c239c309ce694dd50b1473c0f641c3 \ + --hash=sha256:64cbb1a3027c79ca6310bf101014614f6e6e18c226474606cf725238cf5bc2d4 \ + --hash=sha256:66fe626fd7aa5982cdebad23e49e78ef7dbb3e3c2a5960a2b53632f1f703ea45 \ + --hash=sha256:676f92141e3c5492d2a1596d52287d0d963df21bf5e55c8b03075a60e1ddf8aa \ + --hash=sha256:69e62c5034291c845fc4df7f8155e8544178b6c774f97a99e2734b05eb5bed31 \ + --hash=sha256:704c8c8c6ce6569286ae9622e534b4f5b9759b6f2cd643f1c1a61f666d534fe8 \ + --hash=sha256:78f5243bb6b1060aed6213d5107744c19f9571ec76d54c99cc15938eb69e0e86 \ + --hash=sha256:79cac3390bfa9836bb795be377395f28410811c9066bc4eefd8015258a7578c6 \ + --hash=sha256:7ae6eabf519bc7871ce117fb18bf14e0e343eeb96c377667e3e5dd12095e0288 \ + --hash=sha256:7e39e845c4d764208e7b8f6a21c541ade741e2c41afabdfa1caa28687a3c98cf \ + --hash=sha256:8161d9fbc7e9fe2326de89cd0abb9f3599bccc1287db0aba285cb68d204ce929 \ + --hash=sha256:8bec2ac5da793c2685ce5319ca9bcf4eee683b8a1679051f8e6ec04c4f2fd7dc \ + --hash=sha256:959244a17184515f8c52dcb65fb662808767c0bd233c1d8a166e7cf74c9ea985 \ + --hash=sha256:9b148068e881faa26d878ff63e79650e208e95cf1c22bd3f77c3ca7b1d9821a3 \ + --hash=sha256:aa6f302a3a0b5f240ee201297fff0bbfe2fa0d415a94aeb257d8b461032389bd \ + --hash=sha256:ace9048de91293e467b44bce0f0381345078389814ff6e18dbac8fdbf896360e \ + --hash=sha256:ad7525bf0241e5502168ae9c643a2f6c219fa0a283001cee4cf23a9b7da75879 \ + --hash=sha256:b01a840ecc25dce235ae4c1b6a0daefb2a203dba0e6e980637ee9c2f6ee0df57 \ + --hash=sha256:b076e625396e787448d27a411aefff867db2bffac8ed04e8f7056b07024eed5a \ + --hash=sha256:b172f8e030e8ef247b3104902cc671e20df80163b60a203653150d2fc204d1ad \ + --hash=sha256:b1f097878d74fe51e1ddd1be62d8e3682748875b461232cf4b52ddc6e6db0bba \ + --hash=sha256:b95574d06aa9d2bd6e5cc35a5bbe35696342c96760b69dc4287dbd5abd4ad51d \ + --hash=sha256:bda1c5f347550c359f841d6614fb8ca42ae5cb0b74d39f8a1e204815ebe25750 \ + --hash=sha256:cec6b9ce3bd2b7853d4a4563801292bfee40b030c05a3d29555fd2a8ee9bd68c \ + --hash=sha256:d1a987778b9c71da2fc8948e6f2656da6ef68f59298b7e9786849634c35d2c3c \ + --hash=sha256:d74c08e9aaef995f8c4ef6d202dbd219c318450fe2a76da624f2ebb9c8ec5d9f \ + --hash=sha256:e18aafdfb3e9ec0d261c942d35bd7c28d031c5855dadb491d2723ba54f4c3015 \ + --hash=sha256:e216c5c45f89ef8971373fd1c5d8d1164b81f7f5f06bbf23c37e7908d19e8558 \ + --hash=sha256:e695df2c58ce526eeab11a2e915448d3eb76f75dffe338ea613c1201b33bab2f \ + --hash=sha256:e7575ab65ca8399c8c4f9a7d61bbd2d204c8b8e447aab9d355682205c9dd948d \ + --hash=sha256:e995b3b76ccedc27fe4f477b349b7d64597e53a43fc2961db9d3fbace085d69d \ + --hash=sha256:ea31689f05043d520113e0552f039603c4dd71fa4c287b64cb3606140c66f425 \ + --hash=sha256:eb5507795caabd9b2ae3f1adc95f67b1104971c22c624bb354232d65c4fc90b3 \ + --hash=sha256:eb8668cfbc279a536c633137deeb9435d2962caec279c3f8cf8b91fff6ff8953 \ + --hash=sha256:ecea0c38c9079570163d663c0433a9af4094a60aafdca491c6a3d248c7432827 \ + --hash=sha256:f25d8b92a4e31ff1bd873654ec367ae811b3a943583e05432ea29264782dc32c \ + --hash=sha256:f60a297c3987c6c02ffb29effc70eadcbb412fe76947d394a1091a3615948e2f \ + --hash=sha256:f973643ef532d4f9be71dd88cf7588936685fdb576d93a79fe9f65bc337d9d73 defusedxml==0.7.1 ; python_version >= "3.13" and python_version < "4.0" \ --hash=sha256:1bb3032db185915b62d7c6209c5a8792be6a32ab2fedacc84e01b52c51aa3e69 \ --hash=sha256:a352e7e428770286cc899e2542b6cdaedb2b4953ff269a210103ec58f6198a61 @@ -258,51 +259,45 @@ markupsafe==3.0.2 ; python_version >= "3.13" and python_version < "4.0" \ mypy-extensions==1.0.0 ; python_version >= "3.13" and python_version < "4.0" \ --hash=sha256:4392f6c0eb8a5668a69e23d168ffa70f0be9ccfd32b5cc2d26a34ae5b844552d \ --hash=sha256:75dbf8955dc00442a438fc4d0666508a9a97b6bd41aa2f0ffe9d2f2725af0782 -mypy==1.14.1 ; python_version >= "3.13" and python_version < "4.0" \ - --hash=sha256:07ba89fdcc9451f2ebb02853deb6aaaa3d2239a236669a63ab3801bbf923ef5c \ - --hash=sha256:0c911fde686394753fff899c409fd4e16e9b294c24bfd5e1ea4675deae1ac6fd \ - --hash=sha256:183cf0a45457d28ff9d758730cd0210419ac27d4d3f285beda038c9083363b1f \ - --hash=sha256:1fb545ca340537d4b45d3eecdb3def05e913299ca72c290326be19b3804b39c0 \ - --hash=sha256:27fc248022907e72abfd8e22ab1f10e903915ff69961174784a3900a8cba9ad9 \ - --hash=sha256:2ae753f5c9fef278bcf12e1a564351764f2a6da579d4a81347e1d5a15819997b \ - --hash=sha256:30ff5ef8519bbc2e18b3b54521ec319513a26f1bba19a7582e7b1f58a6e69f14 \ - --hash=sha256:3888a1816d69f7ab92092f785a462944b3ca16d7c470d564165fe703b0970c35 \ - --hash=sha256:44bf464499f0e3a2d14d58b54674dee25c031703b2ffc35064bd0df2e0fac319 \ - --hash=sha256:46c756a444117c43ee984bd055db99e498bc613a70bbbc120272bd13ca579fbc \ - --hash=sha256:499d6a72fb7e5de92218db961f1a66d5f11783f9ae549d214617edab5d4dbdbb \ - --hash=sha256:52686e37cf13d559f668aa398dd7ddf1f92c5d613e4f8cb262be2fb4fedb0fcb \ - --hash=sha256:553c293b1fbdebb6c3c4030589dab9fafb6dfa768995a453d8a5d3b23784af2e \ - --hash=sha256:57961db9795eb566dc1d1b4e9139ebc4c6b0cb6e7254ecde69d1552bf7613f60 \ - --hash=sha256:7084fb8f1128c76cd9cf68fe5971b37072598e7c31b2f9f95586b65c741a9d31 \ - --hash=sha256:7d54bd85b925e501c555a3227f3ec0cfc54ee8b6930bd6141ec872d1c572f81f \ - --hash=sha256:7ec88144fe9b510e8475ec2f5f251992690fcf89ccb4500b214b4226abcd32d6 \ - --hash=sha256:8b21525cb51671219f5307be85f7e646a153e5acc656e5cebf64bfa076c50107 \ - --hash=sha256:8b4e3413e0bddea671012b063e27591b953d653209e7a4fa5e48759cda77ca11 \ - --hash=sha256:8c6d94b16d62eb3e947281aa7347d78236688e21081f11de976376cf010eb31a \ - --hash=sha256:8edc07eeade7ebc771ff9cf6b211b9a7d93687ff892150cb5692e4f4272b0837 \ - --hash=sha256:8f845a00b4f420f693f870eaee5f3e2692fa84cc8514496114649cfa8fd5e2c6 \ - --hash=sha256:8fa2220e54d2946e94ab6dbb3ba0a992795bd68b16dc852db33028df2b00191b \ - --hash=sha256:90716d8b2d1f4cd503309788e51366f07c56635a3309b0f6a32547eaaa36a64d \ - --hash=sha256:92c3ed5afb06c3a8e188cb5da4984cab9ec9a77ba956ee419c68a388b4595255 \ - --hash=sha256:ad3301ebebec9e8ee7135d8e3109ca76c23752bac1e717bc84cd3836b4bf3eae \ - --hash=sha256:b66a60cc4073aeb8ae00057f9c1f64d49e90f918fbcef9a977eb121da8b8f1d1 \ - --hash=sha256:ba24549de7b89b6381b91fbc068d798192b1b5201987070319889e93038967a8 \ - --hash=sha256:bce23c7377b43602baa0bd22ea3265c49b9ff0b76eb315d6c34721af4cdf1d9b \ - --hash=sha256:c99f27732c0b7dc847adb21c9d47ce57eb48fa33a17bc6d7d5c5e9f9e7ae5bac \ - --hash=sha256:cb9f255c18052343c70234907e2e532bc7e55a62565d64536dbc7706a20b78b9 \ - --hash=sha256:d4b19b03fdf54f3c5b2fa474c56b4c13c9dbfb9a2db4370ede7ec11a2c5927d9 \ - --hash=sha256:d64169ec3b8461311f8ce2fd2eb5d33e2d0f2c7b49116259c51d0d96edee48d1 \ - --hash=sha256:dbec574648b3e25f43d23577309b16534431db4ddc09fda50841f1e34e64ed34 \ - --hash=sha256:e0fe0f5feaafcb04505bcf439e991c6d8f1bf8b15f12b05feeed96e9e7bf1427 \ - --hash=sha256:f2a0ecc86378f45347f586e4163d1769dd81c5a223d577fe351f26b179e148b1 \ - --hash=sha256:f995e511de847791c3b11ed90084a7a0aafdc074ab88c5a9711622fe4751138c \ - --hash=sha256:fad79bfe3b65fe6a1efaed97b445c3d37f7be9fdc348bdb2d7cac75579607c89 +mypy==1.15.0 ; python_version >= "3.13" and python_version < "4.0" \ + --hash=sha256:1124a18bc11a6a62887e3e137f37f53fbae476dc36c185d549d4f837a2a6a14e \ + --hash=sha256:171a9ca9a40cd1843abeca0e405bc1940cd9b305eaeea2dda769ba096932bb22 \ + --hash=sha256:1905f494bfd7d85a23a88c5d97840888a7bd516545fc5aaedff0267e0bb54e2f \ + --hash=sha256:1fbb8da62dc352133d7d7ca90ed2fb0e9d42bb1a32724c287d3c76c58cbaa9c2 \ + --hash=sha256:2922d42e16d6de288022e5ca321cd0618b238cfc5570e0263e5ba0a77dbef56f \ + --hash=sha256:2e2c2e6d3593f6451b18588848e66260ff62ccca522dd231cd4dd59b0160668b \ + --hash=sha256:2ee2d57e01a7c35de00f4634ba1bbf015185b219e4dc5909e281016df43f5ee5 \ + --hash=sha256:2f2147ab812b75e5b5499b01ade1f4a81489a147c01585cda36019102538615f \ + --hash=sha256:404534629d51d3efea5c800ee7c42b72a6554d6c400e6a79eafe15d11341fd43 \ + --hash=sha256:5469affef548bd1895d86d3bf10ce2b44e33d86923c29e4d675b3e323437ea3e \ + --hash=sha256:5a95fb17c13e29d2d5195869262f8125dfdb5c134dc8d9a9d0aecf7525b10c2c \ + --hash=sha256:6983aae8b2f653e098edb77f893f7b6aca69f6cffb19b2cc7443f23cce5f4828 \ + --hash=sha256:712e962a6357634fef20412699a3655c610110e01cdaa6180acec7fc9f8513ba \ + --hash=sha256:8023ff13985661b50a5928fc7a5ca15f3d1affb41e5f0a9952cb68ef090b31ee \ + --hash=sha256:811aeccadfb730024c5d3e326b2fbe9249bb7413553f15499a4050f7c30e801d \ + --hash=sha256:8f8722560a14cde92fdb1e31597760dc35f9f5524cce17836c0d22841830fd5b \ + --hash=sha256:93faf3fdb04768d44bf28693293f3904bbb555d076b781ad2530214ee53e3445 \ + --hash=sha256:973500e0774b85d9689715feeffcc980193086551110fd678ebe1f4342fb7c5e \ + --hash=sha256:979e4e1a006511dacf628e36fadfecbcc0160a8af6ca7dad2f5025529e082c13 \ + --hash=sha256:98b7b9b9aedb65fe628c62a6dc57f6d5088ef2dfca37903a7d9ee374d03acca5 \ + --hash=sha256:aea39e0583d05124836ea645f412e88a5c7d0fd77a6d694b60d9b6b2d9f184fd \ + --hash=sha256:b9378e2c00146c44793c98b8d5a61039a048e31f429fb0eb546d93f4b000bedf \ + --hash=sha256:baefc32840a9f00babd83251560e0ae1573e2f9d1b067719479bfb0e987c6357 \ + --hash=sha256:be68172e9fd9ad8fb876c6389f16d1c1b5f100ffa779f77b1fb2176fcc9ab95b \ + --hash=sha256:c43a7682e24b4f576d93072216bf56eeff70d9140241f9edec0c104d0c515036 \ + --hash=sha256:c4bb0e1bd29f7d34efcccd71cf733580191e9a264a2202b0239da95984c5b559 \ + --hash=sha256:c7be1e46525adfa0d97681432ee9fcd61a3964c2446795714699a998d193f1a3 \ + --hash=sha256:c9817fa23833ff189db061e6d2eff49b2f3b6ed9856b4a0a73046e41932d744f \ + --hash=sha256:ce436f4c6d218a070048ed6a44c0bbb10cd2cc5e272b29e7845f6a2f57ee4464 \ + --hash=sha256:d10d994b41fb3497719bbf866f227b3489048ea4bbbb5015357db306249f7980 \ + --hash=sha256:e601a7fa172c2131bff456bb3ee08a88360760d0d2f8cbd7a75a65497e2df078 \ + --hash=sha256:f95579473af29ab73a10bada2f9722856792a36ec5af5399b653aa28360290a5 packaging==24.2 ; python_version >= "3.13" and python_version < "4.0" \ --hash=sha256:09abb1bccd265c01f4a3aa3f7a7db064b36514d2cba19a2f694fe6150451a759 \ --hash=sha256:c228a6dc5e932d346bc5739379109d49e8853dd8223571c7c5b55260edc0b97f -pip==25.0 ; python_version >= "3.13" and python_version < "4.0" \ - --hash=sha256:8e0a97f7b4c47ae4a494560da84775e9e2f671d415d8d828e052efefb206b30b \ - --hash=sha256:b6eb97a803356a52b2dd4bb73ba9e65b2ba16caa6bcb25a7497350a4e5859b65 +pip==25.0.1 ; python_version >= "3.13" and python_version < "4.0" \ + --hash=sha256:88f96547ea48b940a3a385494e181e29fb8637898f88d88737c5049780f196ea \ + --hash=sha256:c46efd13b6aa8279f33f2864459c8ce587ea6a1a59ee20de055868d8f7688f7f pluggy==1.5.0 ; python_version >= "3.13" and python_version < "4.0" \ --hash=sha256:2cffa88e94fdc978c4c574f15f9e59b7f4201d439195c3715ca9e2486f1d0cf1 \ --hash=sha256:44e1ad92c8ca002de6377e165f3e0f1be63266ab4d554740532335b9d75ea669 From 1676a7fb1c9a2f5e00dc4350fc9a243ded29f293 Mon Sep 17 00:00:00 2001 From: HSN Date: Fri, 21 Feb 2025 11:13:32 +0600 Subject: [PATCH 02/27] feat: test code for in template datatype conversion --- chk/infrastructure/templating.py | 4 +-- .../validate/assertion_services_test.py | 36 +++++++++++++++++++ 2 files changed, 38 insertions(+), 2 deletions(-) diff --git a/chk/infrastructure/templating.py b/chk/infrastructure/templating.py index 797a0cf6..d7ad24ba 100644 --- a/chk/infrastructure/templating.py +++ b/chk/infrastructure/templating.py @@ -20,7 +20,7 @@ def make(template: str) -> Template: error(e_msg) raise ValueError(e_msg) - n_env = NativeEnvironment( + env = NativeEnvironment( variable_start_string="<%", variable_end_string="%>", block_start_string="<@", @@ -29,7 +29,7 @@ def make(template: str) -> Template: comment_end_string="#>", ) - return n_env.from_string(template) + return env.from_string(template) def is_template_str(tpl: str) -> bool: diff --git a/tests/modules/validate/assertion_services_test.py b/tests/modules/validate/assertion_services_test.py index ba5ec480..adaa1c18 100644 --- a/tests/modules/validate/assertion_services_test.py +++ b/tests/modules/validate/assertion_services_test.py @@ -202,3 +202,39 @@ def test_copy(): assert ar.assert_type == ae.assert_type assert ar is not ae assert "a" in ar.extra_fields + + +class TestAssertionEntryCasting: + """TestAssertionEntryCasting""" + + @staticmethod + def test_casting_int_pass(): + """test_casting_int_pass""" + + assert_list = [ + AssertionEntry( + assert_type="Equal", + actual="<% '10' | int %>", + expected=10, + ), + ] + + run_rpt = AssertionEntryListRunner.test_run(assert_list, {}) + + assert run_rpt.count_fail == 0 + + @staticmethod + def test_casting_float_pass(): + """test_casting_float_pass""" + + assert_list = [ + AssertionEntry( + assert_type="Equal", + actual="<% '10.0032' | float %>", + expected=10.0032, + ), + ] + + run_rpt = AssertionEntryListRunner.test_run(assert_list, {}) + + assert run_rpt.count_fail == 0 From c8cab08554d8e37159ff04dd2be73a7b5da154f9 Mon Sep 17 00:00:00 2001 From: HSN Date: Sat, 22 Feb 2025 16:46:11 +0600 Subject: [PATCH 03/27] refactor: remove cast_actual_to feature --- chk/modules/validate/__init__.py | 2 -- chk/modules/validate/assertion_services.py | 19 ------------------- chk/modules/validate/assertion_validation.py | 19 +------------------ chk/modules/validate/entities.py | 2 -- 4 files changed, 1 insertion(+), 41 deletions(-) diff --git a/chk/modules/validate/__init__.py b/chk/modules/validate/__init__.py index 1cf6a2a3..ffc3c8c7 100644 --- a/chk/modules/validate/__init__.py +++ b/chk/modules/validate/__init__.py @@ -180,7 +180,6 @@ def make_assertion_entry_list(assert_lst: list[dict]) -> list[AssertionEntry]: each_assert["expected"] if "expected" in each_assert else NotImplemented ) - _cast_actual_to = each_assert.get("cast_actual_to", "") _msg_pass = each_assert.get("msg_pass", "") _msg_fail = each_assert.get("msg_fail", "") @@ -195,7 +194,6 @@ def make_assertion_entry_list(assert_lst: list[dict]) -> list[AssertionEntry]: assert_type=_assert_type, actual=_actual, expected=_expected, - cast_actual_to=_cast_actual_to, extra_fields=_extra_fld, msg_pass=_msg_pass, msg_fail=_msg_fail, diff --git a/chk/modules/validate/assertion_services.py b/chk/modules/validate/assertion_services.py index 95a24520..c1f75532 100644 --- a/chk/modules/validate/assertion_services.py +++ b/chk/modules/validate/assertion_services.py @@ -81,25 +81,6 @@ def _replace_assertion_values( str_tpl = JinjaTemplate.make(assert_item.actual) assert_item.actual = str_tpl.render(variable_d) - # convert actual value type - if assert_item.cast_actual_to != "" and isinstance(assert_item.actual, str): - assert_item.actual_b4_cast = assert_item.actual - - if assert_item.cast_actual_to == "int_or_float": - assert_item.actual = Cast.to_int_or_float(assert_item.actual) - elif assert_item.cast_actual_to == "int": - assert_item.actual = Cast.to_int(assert_item.actual) - elif assert_item.cast_actual_to == "float": - assert_item.actual = Cast.to_float(assert_item.actual) - elif assert_item.cast_actual_to == "bool": - assert_item.actual = Cast.to_bool(assert_item.actual) - elif assert_item.cast_actual_to == "none": - assert_item.actual = Cast.to_none(assert_item.actual) - elif assert_item.cast_actual_to in ["map", "list", "str"]: - assert_item.actual = Cast.to_hashable(assert_item.actual) - elif assert_item.cast_actual_to == "auto": - assert_item.actual = Cast.to_auto(assert_item.actual) - # replace expected value for template if isinstance(assert_item.expected, str) and is_template_str( assert_item.expected diff --git a/chk/modules/validate/assertion_validation.py b/chk/modules/validate/assertion_validation.py index 6f8dec15..3cfdbfe4 100644 --- a/chk/modules/validate/assertion_validation.py +++ b/chk/modules/validate/assertion_validation.py @@ -5,7 +5,7 @@ import copy import enum -AssertionEntityProperty = ("type", "actual", "expected", "cast_actual_to") +AssertionEntityProperty = ("type", "actual", "expected") class AssertionEntityType(enum.StrEnum): @@ -73,23 +73,6 @@ class AssertionEntityType(enum.StrEnum): "empty": True, "nullable": True, }, - "cast_actual_to": { - "required": False, - "empty": False, - "nullable": False, - "type": "string", - "allowed": [ - "int_or_float", - "int", - "float", - "bool", - "none", - "map", - "list", - "str", - "auto", - ], - }, "msg_pass": { "required": False, "empty": False, diff --git a/chk/modules/validate/entities.py b/chk/modules/validate/entities.py index 94e1e1b9..09bd523a 100644 --- a/chk/modules/validate/entities.py +++ b/chk/modules/validate/entities.py @@ -20,7 +20,6 @@ class AssertionEntry(BaseModel): expected: Any msg_pass: str = Field(default_factory=str) msg_fail: str = Field(default_factory=str) - cast_actual_to: str = Field(default_factory=str) actual_given: Any = Field(default=NotImplemented) actual_b4_cast: Any = Field(default=NotImplemented) extra_fields: dict = Field(default_factory=dict) @@ -31,7 +30,6 @@ def __iter__(self) -> Generator: yield "expected", "" if self.expected == NotImplemented else self.expected yield "msg_pass", self.msg_pass yield "msg_fail", self.msg_fail - yield "cast_actual_to", self.cast_actual_to yield ( "actual_given", ("" if self.actual_given == NotImplemented else self.actual_given), From eecb2e8e974da376369ee3c54783bcd500ce082d Mon Sep 17 00:00:00 2001 From: HSN Date: Sat, 22 Feb 2025 16:46:26 +0600 Subject: [PATCH 04/27] refactor: update tests to remove cast_actual_to --- .../validate/assertion_services_test.py | 2 - tests/modules/workflow/wf_module_test.py | 2 +- .../spec_docs/validate/btc-usd-validate.chk | 2 +- .../spec_docs/validate/validate-asserts.chk | 58 +++++++++---------- .../get-req-vars/coinstats-usd-validate.chk | 4 +- .../get-req-vars/coinstats-usd-workflow.chk | 2 +- .../register-flow/register-valid.yml | 2 +- .../pass_data/coinstats-usd-validate.chk | 4 +- .../simple-error-1/coinstats-usd-validate.chk | 2 +- .../simple/coinstats-usd-validate.chk | 2 +- 10 files changed, 39 insertions(+), 41 deletions(-) diff --git a/tests/modules/validate/assertion_services_test.py b/tests/modules/validate/assertion_services_test.py index adaa1c18..73460dc8 100644 --- a/tests/modules/validate/assertion_services_test.py +++ b/tests/modules/validate/assertion_services_test.py @@ -79,7 +79,6 @@ def setup_assertion_entry_list_many_items_pass_assert(): { "type": "Equal", "actual": "<% _data.year %>", - "cast_actual_to": "int", "expected": 2023, }, ], @@ -194,7 +193,6 @@ def test_copy(): assert_type="Empty", actual="10", expected=10, - cast_actual_to="int", extra_fields={"a": 1}, ) diff --git a/tests/modules/workflow/wf_module_test.py b/tests/modules/workflow/wf_module_test.py index 150a58bb..cde624ea 100644 --- a/tests/modules/workflow/wf_module_test.py +++ b/tests/modules/workflow/wf_module_test.py @@ -22,7 +22,7 @@ def test_execute_pass_vars( execute(file_ctx, execution_ctx) captured = capsys.readouterr() - assert "======" in captured.out + assert "------" in captured.out @staticmethod def test_execute_pass_args( diff --git a/tests/resources/storage/spec_docs/validate/btc-usd-validate.chk b/tests/resources/storage/spec_docs/validate/btc-usd-validate.chk index 3a42c608..69a0e698 100644 --- a/tests/resources/storage/spec_docs/validate/btc-usd-validate.chk +++ b/tests/resources/storage/spec_docs/validate/btc-usd-validate.chk @@ -4,7 +4,7 @@ version: default:validate:0.7.2 asserts: - { type: Equal, actual: <% _data.code %>, expected: 200, msg_pass: 'Response was successful with code `{type_actual}({value_actual})`' } - { type: Map, actual: <% _data.headers %>, msg_pass: 'Header is a list', msg_fail: 'Header is not a list' } - - { type: Str, actual: <% _data.code %>, msg_pass: 'Code `{type_actual}({value_actual})` is a string', msg_fail: 'Code `{type_actual}({value_actual})` is not a string', cast_actual_to: int } + - { type: Str, actual: <% _data.code %>, msg_pass: 'Code `{type_actual}({value_actual})` is a string', msg_fail: 'Code `{type_actual}({value_actual})` is not a string' } - { type: StrHave, actual: <% _data.info %>, other: "200 OK" } - { type: Map, actual: <% _data.body %> } - { type: List, actual: <% _data.body.explorers %> } diff --git a/tests/resources/storage/spec_docs/validate/validate-asserts.chk b/tests/resources/storage/spec_docs/validate/validate-asserts.chk index 05b3fd26..53e99567 100644 --- a/tests/resources/storage/spec_docs/validate/validate-asserts.chk +++ b/tests/resources/storage/spec_docs/validate/validate-asserts.chk @@ -19,10 +19,10 @@ data: asserts: - { type: Equal, actual: <% response.int %>, expected: 200 } - { type: Equal, actual: <% response.float %>, expected: 200.23 } - - { type: Equal, actual: "[ 1, 2, 3 ]", expected: [ 1, 2, 3 ], cast_actual_to: list } - - { type: Equal, actual: "{'a': 1, 'c': 3, 'b': 2}", expected: { 'a': 1, 'c': 3, 'b': 2 }, cast_actual_to: map } - - { type: Equal, actual: "False", expected: False, cast_actual_to: bool } - - { type: Equal, actual: "False", expected: False, cast_actual_to: auto } + - { type: Equal, actual: "[ 1, 2, 3 ]", expected: [ 1, 2, 3 ] } + - { type: Equal, actual: "{'a': 1, 'c': 3, 'b': 2}", expected: { 'a': 1, 'c': 3, 'b': 2 } } + - { type: Equal, actual: "False", expected: False } + - { type: Equal, actual: "False", expected: False } - { type: NotEqual, actual: "False", expected: False } @@ -57,10 +57,10 @@ asserts: - { type: Boolean, actual: 2 } - { type: Boolean, actual: True } - - { type: Boolean, actual: "true", cast_actual_to: bool } + - { type: Boolean, actual: "true" } - { type: Boolean, actual: True, expected: False } - { type: Boolean, actual: True, expected: 2 } - - { type: Boolean, actual: "true", expected: False, cast_actual_to: bool } + - { type: Boolean, actual: "true", expected: False } - { type: Integer, actual: 10 } - { type: Integer, actual: -10 } @@ -70,28 +70,28 @@ asserts: - { type: IntegerBetween, actual: 5, min: 11, max: 13 } - { type: IntegerBetween, actual: 15, min: 11, max: 13 } - { type: IntegerBetween, actual: "15", min: 11, max: 13 } - - { type: IntegerBetween, actual: "12", min: 11, max: 13, cast_actual_to: int } + - { type: IntegerBetween, actual: "12", min: 11, max: 13 } - { type: IntegerGreater, actual: 12, other: 11 } - { type: IntegerGreater, actual: 5, other: 11 } - { type: IntegerGreater, actual: "15", other: 11 } - - { type: IntegerGreater, actual: "12", other: 11, cast_actual_to: int } + - { type: IntegerGreater, actual: "12", other: 11 } - { type: IntegerGreaterOrEqual, actual: 12, other: 12 } - { type: IntegerGreaterOrEqual, actual: 5, other: 11 } - { type: IntegerGreaterOrEqual, actual: "15", other: 15 } - - { type: IntegerGreaterOrEqual, actual: "12", other: 15, cast_actual_to: int } - - { type: IntegerGreaterOrEqual, actual: "16", other: 15, cast_actual_to: int } + - { type: IntegerGreaterOrEqual, actual: "12", other: 15 } + - { type: IntegerGreaterOrEqual, actual: "16", other: 15 } - { type: IntegerLess, actual: 12, other: 11 } - { type: IntegerLess, actual: 5, other: 11 } - - { type: IntegerLess, actual: "12", other: 13, cast_actual_to: int } + - { type: IntegerLess, actual: "12", other: 13 } - { type: IntegerLessOrEqual, actual: 12, other: 12 } - { type: IntegerLessOrEqual, actual: 5, other: 11 } - { type: IntegerLessOrEqual, actual: "15", other: 15 } - - { type: IntegerLessOrEqual, actual: "12", other: 15, cast_actual_to: int } - - { type: IntegerLessOrEqual, actual: "16", other: 15, cast_actual_to: int } + - { type: IntegerLessOrEqual, actual: "12", other: 15 } + - { type: IntegerLessOrEqual, actual: "16", other: 15 } - { type: Float, actual: 10.0 } - { type: Float, actual: -10.00000000001 } @@ -101,30 +101,30 @@ asserts: - { type: FloatBetween, actual: 5.0, min: 11, max: 13 } - { type: FloatBetween, actual: 15.89, min: 11, max: 13 } - { type: FloatBetween, actual: "15.32", min: 11, max: 13 } - - { type: FloatBetween, actual: "12.24", min: 11, max: 13, cast_actual_to: float } + - { type: FloatBetween, actual: "12.24", min: 11, max: 13 } - { type: FloatGreater, actual: 12.0, other: 12 } - { type: FloatGreater, actual: 5.0, other: 13 } - { type: FloatGreater, actual: 15.89, other: 13 } - { type: FloatGreater, actual: "15.32", other: 13 } - - { type: FloatGreater, actual: "13.24", other: 13, cast_actual_to: float } + - { type: FloatGreater, actual: "13.24", other: 13 } - { type: FloatGreaterOrEqual, actual: 12.0, other: 12 } - { type: FloatGreaterOrEqual, actual: 5.0, other: 11 } - { type: FloatGreaterOrEqual, actual: "15", other: 15 } - - { type: FloatGreaterOrEqual, actual: "12.23", other: 15, cast_actual_to: float } - - { type: FloatGreaterOrEqual, actual: "16.56", other: 15, cast_actual_to: float } + - { type: FloatGreaterOrEqual, actual: "12.23", other: 15 } + - { type: FloatGreaterOrEqual, actual: "16.56", other: 15 } - { type: FloatLess, actual: 12.9, other: 11.0 } - { type: FloatLess, actual: 5.0, other: 11.0 } - { type: FloatLess, actual: "12.3", other: 13.3 } - - { type: FloatLess, actual: "12.3", other: 13.3, cast_actual_to: float } + - { type: FloatLess, actual: "12.3", other: 13.3 } - { type: FloatLessOrEqual, actual: 12.0, other: 12 } - { type: FloatLessOrEqual, actual: 5.0, other: 11 } - { type: FloatLessOrEqual, actual: "15", other: 15 } - - { type: FloatLessOrEqual, actual: "12.23", other: 15.7, cast_actual_to: float } - - { type: FloatLessOrEqual, actual: "16.56", other: 15, cast_actual_to: float } + - { type: FloatLessOrEqual, actual: "12.23", other: 15.7 } + - { type: FloatLessOrEqual, actual: "16.56", other: 15 } - { type: Str, actual: <% response.string1%> } - { type: Str, actual: <% response.string2 %> } @@ -177,34 +177,34 @@ asserts: - { type: DateBeforeOrEqual, actual: "1972-07", expected: "1972-07", format: "%Y-%m" } - { type: List, actual: 'some' } - - { type: List, actual: "[1, 2, 3]", cast_actual_to: list } + - { type: List, actual: "[1, 2, 3]" } - { type: List, actual: [ 1, 2, 3 ] } - { type: List, actual: [ 1, "2", 3.0 ] } - - { type: ListContains, actual: "[1, 2, 3]", expected: 2, cast_actual_to: list } + - { type: ListContains, actual: "[1, 2, 3]", expected: 2 } - { type: ListContains, actual: [ 1, 2, 3 ], expected: 3 } - { type: ListContains, actual: [ 1, "2", 3.0 ], expected: 4 } - - { type: ListDoNotContains, actual: "[1, 2, 3]", expected: 4, cast_actual_to: list } + - { type: ListDoNotContains, actual: "[1, 2, 3]", expected: 4 } - { type: ListDoNotContains, actual: [ 1, 2, 3 ], expected: 4 } - { type: ListDoNotContains, actual: [ 1, "2", 3.0 ], expected: 2 } - { type: ListDoNotContains, actual: [ 1, "2", 3.0 ], expected: '2' } - - { type: ListHasIndex, actual: "[1, 2, 3]", index: 2, cast_actual_to: list } + - { type: ListHasIndex, actual: "[1, 2, 3]", index: 2 } - { type: ListHasIndex, actual: [ 1, 2, 3 ], index: 3 } - { type: ListHasIndex, actual: [ 1, "2", 3.0 ], index: 4 } - - { type: ListDoNotHasIndex, actual: "[1, 2, 3]", index: 2, cast_actual_to: list } + - { type: ListDoNotHasIndex, actual: "[1, 2, 3]", index: 2 } - { type: ListDoNotHasIndex, actual: [ 1, 2, 3 ], index: 3 } - { type: ListDoNotHasIndex, actual: [ 1, "2", 3.0 ], index: 4 } - - { type: Map, actual: <% response.map %>, cast_actual_to: map } - - { type: Map, actual: "{ 'a': 1, 'b': 2 }", cast_actual_to: map } + - { type: Map, actual: <% response.map %> } + - { type: Map, actual: "{ 'a': 1, 'b': 2 }" } - { type: Map, actual: { 'a': 1, 'b': 2 } } - { type: Map, actual: [ 'a', 1, 'b', 2 ] } - - { type: MapKeyCount, actual: <% response.map %>, expected: 2, cast_actual_to: map } - - { type: MapKeyCount, actual: { 'a': 1, 'b': 2 }, expected: 3, cast_actual_to: map } + - { type: MapKeyCount, actual: <% response.map %>, expected: 2 } + - { type: MapKeyCount, actual: { 'a': 1, 'b': 2 }, expected: 3 } - { type: MapHasKeys, actual: <% response.map %>, expected: [ "address", "name" ] } - { type: MapHasKeys, actual: { 'a': 1, 'b': 2 }, expected: [ "b" ] } diff --git a/tests/resources/storage/spec_docs/workflow_cases/get-req-vars/coinstats-usd-validate.chk b/tests/resources/storage/spec_docs/workflow_cases/get-req-vars/coinstats-usd-validate.chk index adcfbc95..30ef0f49 100644 --- a/tests/resources/storage/spec_docs/workflow_cases/get-req-vars/coinstats-usd-validate.chk +++ b/tests/resources/storage/spec_docs/workflow_cases/get-req-vars/coinstats-usd-validate.chk @@ -5,9 +5,9 @@ variables: vdata: ~ asserts: - - { type: Equal, actual: <% vdata.code %>, expected: 200, msg_pass: 'Response was successful with code `{type_actual}({value_actual})`', cast_actual_to: int } + - { type: Equal, actual: <% vdata.code %>, expected: 200, msg_pass: 'Response was successful with code `{type_actual}({value_actual})`' } - { type: Map, actual: <% vdata.headers %>, msg_pass: 'Header is a list', msg_fail: 'Header is not a list' } - - { type: Str, actual: <% vdata.code %>, msg_pass: 'Code `{type_actual}({value_actual})` is a string', msg_fail: 'Code `{type_actual}({value_actual})` is not a string', cast_actual_to: int } + - { type: Str, actual: <% vdata.code %>, msg_pass: 'Code `{type_actual}({value_actual})` is a string', msg_fail: 'Code `{type_actual}({value_actual})` is not a string' } - { type: StrHave, actual: <% vdata.info %>, other: "200 OK" } - { type: Map, actual: <% vdata.body %> } - { type: List, actual: <% vdata.body.explorers %> } diff --git a/tests/resources/storage/spec_docs/workflow_cases/get-req-vars/coinstats-usd-workflow.chk b/tests/resources/storage/spec_docs/workflow_cases/get-req-vars/coinstats-usd-workflow.chk index c091d7a3..54460f0f 100644 --- a/tests/resources/storage/spec_docs/workflow_cases/get-req-vars/coinstats-usd-workflow.chk +++ b/tests/resources/storage/spec_docs/workflow_cases/get-req-vars/coinstats-usd-workflow.chk @@ -22,4 +22,4 @@ tasks: expose: - <% _steps %> - - <% _steps.1.vdata.body %> +# - <% _steps.1.vdata.body %> diff --git a/tests/resources/storage/spec_docs/workflow_cases/lozoacademy/register-flow/register-valid.yml b/tests/resources/storage/spec_docs/workflow_cases/lozoacademy/register-flow/register-valid.yml index 0480d72d..df24025c 100644 --- a/tests/resources/storage/spec_docs/workflow_cases/lozoacademy/register-flow/register-valid.yml +++ b/tests/resources/storage/spec_docs/workflow_cases/lozoacademy/register-flow/register-valid.yml @@ -6,7 +6,7 @@ variables: asserts: - { type: Str, actual: <% _data.body.jwt %>, msg_pass: '`jwt` is string.' } - - { type: Integer, actual: <% _data.body.user.id %>, msg_pass: '`user.id` is an int', msg_fail: '`user.id` is not an int', cast_actual_to: int } + - { type: Integer, actual: <% _data.body.user.id %>, msg_pass: '`user.id` is an int', msg_fail: '`user.id` is not an int' } - { type: Equal, actual: <% _data.body.user.username %>, expected: <% userName %> , msg_pass: '`user.username` matches', msg_fail: '`user.username` do not matches'} - { type: Map, actual: <% _data.body.user %>, msg_pass: '`user` is a map', msg_fail: '`user` is not a map' } - { type: StrHave, actual: <% _data.body.user.email %>, other: "@gmail.com" } diff --git a/tests/resources/storage/spec_docs/workflow_cases/pass_data/coinstats-usd-validate.chk b/tests/resources/storage/spec_docs/workflow_cases/pass_data/coinstats-usd-validate.chk index cbcb47e4..58028a90 100644 --- a/tests/resources/storage/spec_docs/workflow_cases/pass_data/coinstats-usd-validate.chk +++ b/tests/resources/storage/spec_docs/workflow_cases/pass_data/coinstats-usd-validate.chk @@ -2,9 +2,9 @@ version: default:validate:0.7.2 asserts: - - { type: Equal, actual: <% _data.code %>, expected: 200, msg_pass: 'Response was successful with code `{type_actual}({value_actual})`', cast_actual_to: int } + - { type: Equal, actual: <% _data.code %>, expected: 200, msg_pass: 'Response was successful with code `{type_actual}({value_actual})`'} - { type: Map, actual: <% _data.headers %>, msg_pass: 'Header is a list', msg_fail: 'Header is not a list' } - - { type: Str, actual: <% _data.code %>, msg_pass: 'Code `{type_actual}({value_actual})` is a string', msg_fail: 'Code `{type_actual}({value_actual})` is not a string', cast_actual_to: int } + - { type: Str, actual: <% _data.code %>, msg_pass: 'Code `{type_actual}({value_actual})` is a string', msg_fail: 'Code `{type_actual}({value_actual})` is not a string'} - { type: StrHave, actual: <% _data.info %>, other: "200 OK" } - { type: Map, actual: <% _data.body %> } - { type: List, actual: <% _data.body.explorers %> } diff --git a/tests/resources/storage/spec_docs/workflow_cases/simple-error-1/coinstats-usd-validate.chk b/tests/resources/storage/spec_docs/workflow_cases/simple-error-1/coinstats-usd-validate.chk index fa7c7b47..2530838b 100644 --- a/tests/resources/storage/spec_docs/workflow_cases/simple-error-1/coinstats-usd-validate.chk +++ b/tests/resources/storage/spec_docs/workflow_cases/simple-error-1/coinstats-usd-validate.chk @@ -4,7 +4,7 @@ version: default:validate:0.7.2 asserts: - { type: Equal, actual: <% _data.code %>, expected: 200, msg_pass: 'Response was successful with code `{type_actual}({value_actual})`' } - { type: Map, actual: <% _data.headers %>, msg_pass: 'Header is a list', msg_fail: 'Header is not a list' } - - { type: Str, actual: <% _data.code %>, msg_pass: 'Code `{type_actual}({value_actual})` is a string', msg_fail: 'Code `{type_actual}({value_actual})` is not a string', cast_actual_to: int } + - { type: Str, actual: <% _data.code %>, msg_pass: 'Code `{type_actual}({value_actual})` is a string', msg_fail: 'Code `{type_actual}({value_actual})` is not a string'} - { type: StrHave, actual: <% _data.info %>, other: "200 OK" } - { type: Map, actual: <% _data.body %> } - { type: List, actual: <% _data.body.explorers %> } diff --git a/tests/resources/storage/spec_docs/workflow_cases/simple/coinstats-usd-validate.chk b/tests/resources/storage/spec_docs/workflow_cases/simple/coinstats-usd-validate.chk index 0fc8fb31..e39cb09d 100644 --- a/tests/resources/storage/spec_docs/workflow_cases/simple/coinstats-usd-validate.chk +++ b/tests/resources/storage/spec_docs/workflow_cases/simple/coinstats-usd-validate.chk @@ -4,7 +4,7 @@ version: default:validate:0.7.2 asserts: - { type: Equal, actual: <% _data.code %>, expected: 200, msg_pass: 'Response was successful with code `{type_actual}({value_actual})`' } - { type: Map, actual: <% _data.headers %>, msg_pass: 'Header is a list', msg_fail: 'Header is not a list' } - - { type: Str, actual: <% _data.code %>, msg_pass: 'Code `{type_actual}({value_actual})` is a string', msg_fail: 'Code `{type_actual}({value_actual})` is not a string', cast_actual_to: int } + - { type: Str, actual: <% _data.code %>, msg_pass: 'Code `{type_actual}({value_actual})` is a string', msg_fail: 'Code `{type_actual}({value_actual})` is not a string'} - { type: StrHave, actual: <% _data.info %>, other: "200 OK" } - { type: Map, actual: <% _data.body %> } - { type: List, actual: <% _data.body.explorers %> } From 2c75dc6c1495babccf123ddf68d579cdf08f3a21 Mon Sep 17 00:00:00 2001 From: HSN Date: Sat, 22 Feb 2025 17:13:29 +0600 Subject: [PATCH 05/27] refactor: update tests --- .../spec_docs/validate/validate-asserts.chk | 47 ++++++++----------- 1 file changed, 20 insertions(+), 27 deletions(-) diff --git a/tests/resources/storage/spec_docs/validate/validate-asserts.chk b/tests/resources/storage/spec_docs/validate/validate-asserts.chk index 53e99567..05fc8097 100644 --- a/tests/resources/storage/spec_docs/validate/validate-asserts.chk +++ b/tests/resources/storage/spec_docs/validate/validate-asserts.chk @@ -19,10 +19,6 @@ data: asserts: - { type: Equal, actual: <% response.int %>, expected: 200 } - { type: Equal, actual: <% response.float %>, expected: 200.23 } - - { type: Equal, actual: "[ 1, 2, 3 ]", expected: [ 1, 2, 3 ] } - - { type: Equal, actual: "{'a': 1, 'c': 3, 'b': 2}", expected: { 'a': 1, 'c': 3, 'b': 2 } } - - { type: Equal, actual: "False", expected: False } - - { type: Equal, actual: "False", expected: False } - { type: NotEqual, actual: "False", expected: False } @@ -69,29 +65,27 @@ asserts: - { type: IntegerBetween, actual: 12, min: 11, max: 13 } - { type: IntegerBetween, actual: 5, min: 11, max: 13 } - { type: IntegerBetween, actual: 15, min: 11, max: 13 } - - { type: IntegerBetween, actual: "15", min: 11, max: 13 } - - { type: IntegerBetween, actual: "12", min: 11, max: 13 } + - { type: IntegerBetween, actual: <% "15" | int %>, min: 11, max: 13 } + - { type: IntegerBetween, actual: <% "12" | int %>, min: 11, max: 13 } - { type: IntegerGreater, actual: 12, other: 11 } - { type: IntegerGreater, actual: 5, other: 11 } - - { type: IntegerGreater, actual: "15", other: 11 } - - { type: IntegerGreater, actual: "12", other: 11 } + - { type: IntegerGreater, actual: <% "15" | int %>, other: 11 } + - { type: IntegerGreater, actual: <% "12" | int %>, other: 11 } - { type: IntegerGreaterOrEqual, actual: 12, other: 12 } - { type: IntegerGreaterOrEqual, actual: 5, other: 11 } - - { type: IntegerGreaterOrEqual, actual: "15", other: 15 } - - { type: IntegerGreaterOrEqual, actual: "12", other: 15 } - - { type: IntegerGreaterOrEqual, actual: "16", other: 15 } + - { type: IntegerGreaterOrEqual, actual: <% "15" | int %>, other: 15 } + - { type: IntegerGreaterOrEqual, actual: <% "12" | int %>, other: 15 } - { type: IntegerLess, actual: 12, other: 11 } - { type: IntegerLess, actual: 5, other: 11 } - - { type: IntegerLess, actual: "12", other: 13 } + - { type: IntegerLess, actual: <% "12" | int %>, other: 13 } - { type: IntegerLessOrEqual, actual: 12, other: 12 } - { type: IntegerLessOrEqual, actual: 5, other: 11 } - - { type: IntegerLessOrEqual, actual: "15", other: 15 } - - { type: IntegerLessOrEqual, actual: "12", other: 15 } - - { type: IntegerLessOrEqual, actual: "16", other: 15 } + - { type: IntegerLessOrEqual, actual: <% "15" | int %>, other: 15 } + - { type: IntegerLessOrEqual, actual: <% "12" | int %>, other: 15 } - { type: Float, actual: 10.0 } - { type: Float, actual: -10.00000000001 } @@ -100,31 +94,30 @@ asserts: - { type: FloatBetween, actual: 12.34, min: 11, max: 13 } - { type: FloatBetween, actual: 5.0, min: 11, max: 13 } - { type: FloatBetween, actual: 15.89, min: 11, max: 13 } - - { type: FloatBetween, actual: "15.32", min: 11, max: 13 } - - { type: FloatBetween, actual: "12.24", min: 11, max: 13 } + - { type: FloatBetween, actual: <% "15.32" | float %>, min: 11, max: 13 } + - { type: FloatBetween, actual: <% "12.24" | float %>, min: 11, max: 13 } - { type: FloatGreater, actual: 12.0, other: 12 } - { type: FloatGreater, actual: 5.0, other: 13 } - { type: FloatGreater, actual: 15.89, other: 13 } - - { type: FloatGreater, actual: "15.32", other: 13 } - - { type: FloatGreater, actual: "13.24", other: 13 } + - { type: FloatGreater, actual: <% "15.32" | float %>, other: 13 } + - { type: FloatGreater, actual: <% "13.24" | float %>, other: 13 } - { type: FloatGreaterOrEqual, actual: 12.0, other: 12 } - { type: FloatGreaterOrEqual, actual: 5.0, other: 11 } - - { type: FloatGreaterOrEqual, actual: "15", other: 15 } - - { type: FloatGreaterOrEqual, actual: "12.23", other: 15 } - - { type: FloatGreaterOrEqual, actual: "16.56", other: 15 } + - { type: FloatGreaterOrEqual, actual: <% "15" | float %>, other: 15 } + - { type: FloatGreaterOrEqual, actual: <% "12.23" | float %>, other: 15 } + - { type: FloatGreaterOrEqual, actual: <% "16.56" | float %>, other: 15 } - { type: FloatLess, actual: 12.9, other: 11.0 } - { type: FloatLess, actual: 5.0, other: 11.0 } - - { type: FloatLess, actual: "12.3", other: 13.3 } - - { type: FloatLess, actual: "12.3", other: 13.3 } + - { type: FloatLess, actual: <% "12.23" | float %>, other: 13.3 } - { type: FloatLessOrEqual, actual: 12.0, other: 12 } - { type: FloatLessOrEqual, actual: 5.0, other: 11 } - - { type: FloatLessOrEqual, actual: "15", other: 15 } - - { type: FloatLessOrEqual, actual: "12.23", other: 15.7 } - - { type: FloatLessOrEqual, actual: "16.56", other: 15 } + - { type: FloatLessOrEqual, actual: <% "15" | float %>, other: 15 } + - { type: FloatLessOrEqual, actual: <% "12.23" | float %>, other: 15.7 } + - { type: FloatLessOrEqual, actual: <% "16.56" | float %>, other: 15 } - { type: Str, actual: <% response.string1%> } - { type: Str, actual: <% response.string2 %> } From 71f0b356442580f382cf395e3ea515398895da94 Mon Sep 17 00:00:00 2001 From: HSN Date: Tue, 25 Feb 2025 09:56:25 +0600 Subject: [PATCH 06/27] feat: new jinja fromjson filter added --- chk/infrastructure/templating.py | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/chk/infrastructure/templating.py b/chk/infrastructure/templating.py index d7ad24ba..46828015 100644 --- a/chk/infrastructure/templating.py +++ b/chk/infrastructure/templating.py @@ -2,6 +2,10 @@ Templating module """ +import json +import typing + +from jinja2 import TemplateError from jinja2.environment import Template from jinja2.nativetypes import NativeEnvironment @@ -29,6 +33,8 @@ def make(template: str) -> Template: comment_end_string="#>", ) + env.filters["fromjson"] = filter_fromjson + return env.from_string(template) @@ -37,3 +43,15 @@ def is_template_str(tpl: str) -> bool: _dm_sets = [("<%", "%>"), ("<@", "@>"), ("<#", "#>")] return any([_dm_set[0] in tpl and _dm_set[1] in tpl for _dm_set in _dm_sets]) + +###################################### +# Jinja Filters +###################################### + +def filter_fromjson(value: typing.Any) -> str: + """Convert a JSON string to a Python dictionary.""" + + try: + return json.loads(value) + except json.JSONDecodeError as e: + raise TemplateError(f"Invalid JSON string: {e}") from e From 91d4fbe711f238f4eb407a9f3118d780a381669c Mon Sep 17 00:00:00 2001 From: HSN Date: Sun, 2 Mar 2025 12:41:46 +0600 Subject: [PATCH 07/27] chore: setuptool version update --- poetry.lock | 6 +++--- requirements-dev.txt | 6 +++--- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/poetry.lock b/poetry.lock index 76fd0cc8..c3c693b7 100644 --- a/poetry.lock +++ b/poetry.lock @@ -848,13 +848,13 @@ files = [ [[package]] name = "setuptools" -version = "75.8.0" +version = "75.8.2" description = "Easily download, build, install, upgrade, and uninstall Python packages" optional = false python-versions = ">=3.9" files = [ - {file = "setuptools-75.8.0-py3-none-any.whl", hash = "sha256:e3982f444617239225d675215d51f6ba05f845d4eec313da4418fdbb56fb27e3"}, - {file = "setuptools-75.8.0.tar.gz", hash = "sha256:c5afc8f407c626b8313a86e10311dd3f661c6cd9c09d4bf8c15c0e11f9f2b0e6"}, + {file = "setuptools-75.8.2-py3-none-any.whl", hash = "sha256:558e47c15f1811c1fa7adbd0096669bf76c1d3f433f58324df69f3f5ecac4e8f"}, + {file = "setuptools-75.8.2.tar.gz", hash = "sha256:4880473a969e5f23f2a2be3646b2dfd84af9028716d398e46192f84bc36900d2"}, ] [package.extras] diff --git a/requirements-dev.txt b/requirements-dev.txt index 792faf96..b96bd0a7 100644 --- a/requirements-dev.txt +++ b/requirements-dev.txt @@ -496,9 +496,9 @@ ruff==0.8.6 ; python_version >= "3.13" and python_version < "4.0" \ --hash=sha256:e169ea1b9eae61c99b257dc83b9ee6c76f89042752cb2d83486a7d6e48e8f764 \ --hash=sha256:e88b8f6d901477c41559ba540beeb5a671e14cd29ebd5683903572f4b40a9807 \ --hash=sha256:f1d70bef3d16fdc897ee290d7d20da3cbe4e26349f62e8a0274e7a3f4ce7a905 -setuptools==75.8.0 ; python_version >= "3.13" and python_version < "4.0" \ - --hash=sha256:c5afc8f407c626b8313a86e10311dd3f661c6cd9c09d4bf8c15c0e11f9f2b0e6 \ - --hash=sha256:e3982f444617239225d675215d51f6ba05f845d4eec313da4418fdbb56fb27e3 +setuptools==75.8.2 ; python_version >= "3.13" and python_version < "4.0" \ + --hash=sha256:4880473a969e5f23f2a2be3646b2dfd84af9028716d398e46192f84bc36900d2 \ + --hash=sha256:558e47c15f1811c1fa7adbd0096669bf76c1d3f433f58324df69f3f5ecac4e8f shiv==1.0.8 ; python_version >= "3.13" and python_version < "4.0" \ --hash=sha256:2a68d69e98ce81cb5b8fdafbfc1e27efa93e6d89ca14bfae33482e4176f561d6 \ --hash=sha256:a60e4b05a2d2f8b820d567b1d89ee59af731759771c32c282d03c4ceae6aba24 From 7552ee61fcfebaa23316737d49c691163840d37a Mon Sep 17 00:00:00 2001 From: HSN Date: Wed, 5 Mar 2025 16:51:25 +0600 Subject: [PATCH 08/27] feat: add env builder to JinjaTemplate --- chk/infrastructure/templating.py | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/chk/infrastructure/templating.py b/chk/infrastructure/templating.py index 46828015..db01462f 100644 --- a/chk/infrastructure/templating.py +++ b/chk/infrastructure/templating.py @@ -15,6 +15,22 @@ class JinjaTemplate: """JinjaTemplate is wrapper class for JinjaNativeTemplate""" + @staticmethod + def build_env() -> NativeEnvironment: + """Build a native env""" + + env = NativeEnvironment( + variable_start_string="<%", + variable_end_string="%>", + block_start_string="<@", + block_end_string="@>", + comment_start_string="<#", + comment_end_string="#>", + ) + + env.filters["fromjson"] = filter_fromjson + return env + @staticmethod def make(template: str) -> Template: """Create a NativeEnvironment with default settings""" From 4206f895cc734c3435b2964528b474b574423716 Mon Sep 17 00:00:00 2001 From: HSN Date: Wed, 5 Mar 2025 16:51:50 +0600 Subject: [PATCH 09/27] feat: add render feature to JinjaTemplate --- chk/infrastructure/templating.py | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/chk/infrastructure/templating.py b/chk/infrastructure/templating.py index db01462f..4e1987a9 100644 --- a/chk/infrastructure/templating.py +++ b/chk/infrastructure/templating.py @@ -7,6 +7,7 @@ from jinja2 import TemplateError from jinja2.environment import Template +from jinja2.meta import find_undeclared_variables from jinja2.nativetypes import NativeEnvironment from chk.infrastructure.logging import error @@ -53,6 +54,23 @@ def make(template: str) -> Template: return env.from_string(template) + @staticmethod + def render(env: NativeEnvironment, template: str, data: dict) -> typing.Any: + """Create a NativeEnvironment with default settings""" + + if not template or not isinstance(template, str): + e_msg = f"Template error: {type(template)} {template}" + error(e_msg) + raise ValueError(e_msg) + + # handle undefined vars + undeclared_vars = find_undeclared_variables(env.parse(template)) + + if all([_var in data for _var in undeclared_vars]): + return env.from_string(template).render(data) + else: + return template + def is_template_str(tpl: str) -> bool: """Check given string is templated string or not""" From 1bc5bd88d0a949afd4bf5edf2a1f5b6d8b00d0b2 Mon Sep 17 00:00:00 2001 From: HSN Date: Wed, 5 Mar 2025 16:53:14 +0600 Subject: [PATCH 10/27] refactor: improve template compile feature --- chk/infrastructure/symbol_table.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/chk/infrastructure/symbol_table.py b/chk/infrastructure/symbol_table.py index a86b97f0..68b3a884 100644 --- a/chk/infrastructure/symbol_table.py +++ b/chk/infrastructure/symbol_table.py @@ -94,11 +94,11 @@ def replace_value(doc: dict | list, var_s: dict) -> dict | list: :param var_s: :return: """ + env = JinjaTemplate.build_env() for key, val in list(doc.items() if isinstance(doc, dict) else enumerate(doc)): if isinstance(val, str): - str_tpl = JinjaTemplate.make(val) - doc[key] = str_tpl.render(var_s) + doc[key] = JinjaTemplate.render(env, val, var_s) elif isinstance(val, (dict, list)): doc[key] = replace_value(doc[key], var_s) return doc From fcfc377f6f7adea719ac548067b3f4c0e9a6fc22 Mon Sep 17 00:00:00 2001 From: HSN Date: Wed, 5 Mar 2025 16:53:43 +0600 Subject: [PATCH 11/27] feat: recursively resolve composite variables --- chk/infrastructure/symbol_table.py | 6 ++++-- tests/infrastructure/symbol_table_test.py | 7 +++++-- 2 files changed, 9 insertions(+), 4 deletions(-) diff --git a/chk/infrastructure/symbol_table.py b/chk/infrastructure/symbol_table.py index 68b3a884..31e44498 100644 --- a/chk/infrastructure/symbol_table.py +++ b/chk/infrastructure/symbol_table.py @@ -174,8 +174,10 @@ def handle_composite( replaced_values: dict = replace_callback( composite_values, variable_doc.data ) - for key, val in replaced_values.items(): - variable_doc[key] = val + + cls.handle_absolute(variable_doc, replaced_values) + cls.handle_composite(variable_doc, replaced_values) + @classmethod def handle_execute_context( diff --git a/tests/infrastructure/symbol_table_test.py b/tests/infrastructure/symbol_table_test.py index 7bdde27f..9ed43fc7 100644 --- a/tests/infrastructure/symbol_table_test.py +++ b/tests/infrastructure/symbol_table_test.py @@ -87,7 +87,9 @@ def test_handle_composite_pass(): }, VariableConfigNode.VARIABLES: { "var_1": "bar", + "var_6": "<% var_5 | trim %> cent", "var_2": 2, + "var_7": "<% var_6 %> <% var_3 | upper %>", "var_3": "ajax_<%var_1%>", "var_5": " <% var_2 %>", }, @@ -104,13 +106,14 @@ def test_handle_composite_pass(): variable_doc, file_ctx.document[VariableConfigNode.VARIABLES] ) - assert len(variable_doc.data) == 4 + assert len(variable_doc.data) == 6 assert variable_doc.data == { "var_1": "bar", "var_2": 2, "var_3": "ajax_bar", "var_5": " 2", - } + "var_6": "2 cent", + "var_7": "2 cent AJAX_BAR", } @staticmethod def test_handle_execute_context_pass(): From 6f095929c4326267037aa559b625742e2a19b230 Mon Sep 17 00:00:00 2001 From: HSN Date: Wed, 5 Mar 2025 16:54:32 +0600 Subject: [PATCH 12/27] chore: pytest version update --- poetry.lock | 6 +++--- requirements-dev.txt | 6 +++--- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/poetry.lock b/poetry.lock index c3c693b7..a823016e 100644 --- a/poetry.lock +++ b/poetry.lock @@ -669,13 +669,13 @@ windows-terminal = ["colorama (>=0.4.6)"] [[package]] name = "pytest" -version = "8.3.4" +version = "8.3.5" description = "pytest: simple powerful testing with Python" optional = false python-versions = ">=3.8" files = [ - {file = "pytest-8.3.4-py3-none-any.whl", hash = "sha256:50e16d954148559c9a74109af1eaf0c945ba2d8f30f0a3d3335edde19788b6f6"}, - {file = "pytest-8.3.4.tar.gz", hash = "sha256:965370d062bce11e73868e0335abac31b4d3de0e82f4007408d242b4f8610761"}, + {file = "pytest-8.3.5-py3-none-any.whl", hash = "sha256:c69214aa47deac29fad6c2a4f590b9c4a9fdb16a403176fe154b79c0b4d4d820"}, + {file = "pytest-8.3.5.tar.gz", hash = "sha256:f4efe70cc14e511565ac476b57c279e12a855b11f48f212af1080ef2263d3845"}, ] [package.dependencies] diff --git a/requirements-dev.txt b/requirements-dev.txt index b96bd0a7..86465d6b 100644 --- a/requirements-dev.txt +++ b/requirements-dev.txt @@ -411,9 +411,9 @@ pygments==2.19.1 ; python_version >= "3.13" and python_version < "4.0" \ pytest-cov==6.0.0 ; python_version >= "3.13" and python_version < "4.0" \ --hash=sha256:eee6f1b9e61008bd34975a4d5bab25801eb31898b032dd55addc93e96fcaaa35 \ --hash=sha256:fde0b595ca248bb8e2d76f020b465f3b107c9632e6a1d1705f17834c89dcadc0 -pytest==8.3.4 ; python_version >= "3.13" and python_version < "4.0" \ - --hash=sha256:50e16d954148559c9a74109af1eaf0c945ba2d8f30f0a3d3335edde19788b6f6 \ - --hash=sha256:965370d062bce11e73868e0335abac31b4d3de0e82f4007408d242b4f8610761 +pytest==8.3.5 ; python_version >= "3.13" and python_version < "4.0" \ + --hash=sha256:c69214aa47deac29fad6c2a4f590b9c4a9fdb16a403176fe154b79c0b4d4d820 \ + --hash=sha256:f4efe70cc14e511565ac476b57c279e12a855b11f48f212af1080ef2263d3845 python-dotenv==1.0.1 ; python_version >= "3.13" and python_version < "4.0" \ --hash=sha256:e324ee90a023d808f1959c46bcbc04446a10ced277783dc6ee09987c37ec10ca \ --hash=sha256:f7b63ef50f1b690dddf550d03497b66d609393b40b564ed0d674909a68ebf16a From 7a178900188980e7b2203326075eba83834c9df5 Mon Sep 17 00:00:00 2001 From: HSN Date: Thu, 6 Mar 2025 10:43:36 +0600 Subject: [PATCH 13/27] refactor: check if "exceptions" were passed before processing --- chk/modules/workflow/services.py | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/chk/modules/workflow/services.py b/chk/modules/workflow/services.py index 069c0c72..f2e95424 100644 --- a/chk/modules/workflow/services.py +++ b/chk/modules/workflow/services.py @@ -113,9 +113,13 @@ def _prepare_dump_data(self) -> dict: response_task_dump["validate_asserts_count_fail"] = ( item.others["count_fail"] if "count_fail" in item.others else "" ) - response_task_dump["validate_asserts_err_messages"] = [ - f" >>> {msg}" for msg in item.others["exceptions"] - ] + + response_task_dump["validate_asserts_err_messages"] = [] + + if "exceptions" in item.others: + response_task_dump["validate_asserts_err_messages"] = [ + f" >>> {msg}" for msg in item.others["exceptions"] + ] r_dump["tasks"].append(response_task_dump) return r_dump From 738c0bf7ae7a58128ce2cc82b410bb33bc206427 Mon Sep 17 00:00:00 2001 From: HSN Date: Thu, 6 Mar 2025 15:51:33 +0600 Subject: [PATCH 14/27] feat: add feature for local context variable handling --- chk/infrastructure/symbol_table.py | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/chk/infrastructure/symbol_table.py b/chk/infrastructure/symbol_table.py index 31e44498..cf2b9b15 100644 --- a/chk/infrastructure/symbol_table.py +++ b/chk/infrastructure/symbol_table.py @@ -135,6 +135,24 @@ def handle( if variables: cls.handle_composite(variable_doc, variables) + @classmethod + def handle_variable_doc( + cls, + variables: Variables, + variable_doc: dict, + ) -> None: + """Handles variable handling + + Args: + variable_doc: VariableDocument to add values to + variables: VersionedDocument of document data + """ + + cls.handle_absolute(variables, variable_doc) + + if variables: + cls.handle_composite(variables, variable_doc) + @classmethod def handle_absolute(cls, variable_doc: Variables, document: dict) -> None: """Handles absolute variables and values from document From f647a29985fa68bbb59c77f33479742903ff4280 Mon Sep 17 00:00:00 2001 From: HSN Date: Thu, 6 Mar 2025 15:53:53 +0600 Subject: [PATCH 15/27] refactor: task variable features closes #369 --- chk/modules/workflow/__init__.py | 22 ++++++++++++++++--- .../get-req-vars/coinstats-usd-workflow.chk | 4 ++-- 2 files changed, 21 insertions(+), 5 deletions(-) diff --git a/chk/modules/workflow/__init__.py b/chk/modules/workflow/__init__.py index 3774a8a5..63f8b374 100644 --- a/chk/modules/workflow/__init__.py +++ b/chk/modules/workflow/__init__.py @@ -10,6 +10,7 @@ from collections import abc from collections.abc import Callable +import icecream from pydantic import BaseModel, ConfigDict, Field from chk.infrastructure.document import ( @@ -113,6 +114,17 @@ def set_step_template(cls, variables: Variables) -> None: # @TODO implement data set functionality with validation for variables variables[WorkflowConfigNode.NODE.value] = [] + @classmethod + def process_task_variables_template(cls, task: dict, variables: Variables): + """process task.variables template""" + + if "variables" in task: + doc = task["variables"] + loc_vars = Variables(variables.data) + + VariableTableManager.handle_variable_doc(loc_vars, doc) + task["variables"] = {key: value for key, value in loc_vars.items() if key in doc.keys()} + @classmethod def process_task_template( cls, document: WorkflowDocument, variables: Variables @@ -135,11 +147,15 @@ def process_task_template( raise RuntimeError("`tasks.*.item` should be map.") # replace values in tasks - task_d_: dict = replace_value(task, variables.data) - debug(task_d_) + task_repl = {key: value for key, value in task.items() if key in {"name"}} + task = task | replace_value(task_repl, variables.data) + + cls.process_task_variables_template(task, variables) + icecream.ic(task) + exit() task_o_ = ChkwareTaskSupport.make_task( - task_d_, **dict(base_file_path=base_fpath) + task, **dict(base_file_path=base_fpath) ) exctx_args = {"variables": json.dumps(task_o_.variables)} diff --git a/tests/resources/storage/spec_docs/workflow_cases/get-req-vars/coinstats-usd-workflow.chk b/tests/resources/storage/spec_docs/workflow_cases/get-req-vars/coinstats-usd-workflow.chk index 54460f0f..7b73c702 100644 --- a/tests/resources/storage/spec_docs/workflow_cases/get-req-vars/coinstats-usd-workflow.chk +++ b/tests/resources/storage/spec_docs/workflow_cases/get-req-vars/coinstats-usd-workflow.chk @@ -10,13 +10,13 @@ variables: tasks: - name: Fetch some content from URL uses: fetch - file: "./<% group %>-usd-request.chk" + file: "./coinstats-usd-request.chk" variables: convertCurrency: <% currency %> - name: Validate the content is okay uses: validate - file: "./<% group %>-usd-validate.chk" + file: "./coinstats-usd-validate.chk" variables: vdata: <% _steps.0._response %> From 94ad7c55375620fb050c6b34278683b3e6be73c8 Mon Sep 17 00:00:00 2001 From: HSN Date: Thu, 6 Mar 2025 16:05:38 +0600 Subject: [PATCH 16/27] refactor: remove debug stmts --- chk/modules/workflow/__init__.py | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/chk/modules/workflow/__init__.py b/chk/modules/workflow/__init__.py index 63f8b374..38f714f3 100644 --- a/chk/modules/workflow/__init__.py +++ b/chk/modules/workflow/__init__.py @@ -151,19 +151,17 @@ def process_task_template( task = task | replace_value(task_repl, variables.data) cls.process_task_variables_template(task, variables) - icecream.ic(task) - exit() task_o_ = ChkwareTaskSupport.make_task( task, **dict(base_file_path=base_fpath) ) - exctx_args = {"variables": json.dumps(task_o_.variables)} + execute_args = {"variables": json.dumps(task_o_.variables)} if isinstance(task_o_, ChkwareValidateTask): - exctx_args["arguments"] = task_o_.arguments.model_dump_json() + execute_args["arguments"] = task_o_.arguments.model_dump_json() - execution_ctx = ExecuteContext({"dump": True, "format": True}, exctx_args) + execution_ctx = ExecuteContext({"dump": True, "format": True}, execute_args) debug(execution_ctx) task_fn = None From 934dc22c2d0a58eb07386dd87008effc73fd5180 Mon Sep 17 00:00:00 2001 From: HSN Date: Thu, 6 Mar 2025 16:09:34 +0600 Subject: [PATCH 17/27] fix: expectation in wf tests --- tests/modules/workflow/wf_module_test.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/modules/workflow/wf_module_test.py b/tests/modules/workflow/wf_module_test.py index cde624ea..106843ba 100644 --- a/tests/modules/workflow/wf_module_test.py +++ b/tests/modules/workflow/wf_module_test.py @@ -37,7 +37,7 @@ def test_execute_pass_args( execute(file_ctx, execution_ctx) captured = capsys.readouterr() - assert "======" in captured.out + assert "------" in captured.out class TestWorkflowCall: """TestWorkflowCall""" From 9bdf346dca8d0fda73eb3ee85c8f5b2c6b148252 Mon Sep 17 00:00:00 2001 From: HSN Date: Sun, 9 Mar 2025 23:03:46 +0600 Subject: [PATCH 18/27] refactor: add argument.data processing capability --- chk/modules/workflow/__init__.py | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/chk/modules/workflow/__init__.py b/chk/modules/workflow/__init__.py index 38f714f3..8778f565 100644 --- a/chk/modules/workflow/__init__.py +++ b/chk/modules/workflow/__init__.py @@ -10,7 +10,6 @@ from collections import abc from collections.abc import Callable -import icecream from pydantic import BaseModel, ConfigDict, Field from chk.infrastructure.document import ( @@ -118,12 +117,22 @@ def set_step_template(cls, variables: Variables) -> None: def process_task_variables_template(cls, task: dict, variables: Variables): """process task.variables template""" + # handle task variables if "variables" in task: doc = task["variables"] loc_vars = Variables(variables.data) VariableTableManager.handle_variable_doc(loc_vars, doc) - task["variables"] = {key: value for key, value in loc_vars.items() if key in doc.keys()} + task["variables"] = {key: value for key, value in loc_vars.data.items() if key in doc.keys()} + + # handle task arguments + if "arguments" in task and bool(task["arguments"]): + if "data" in task["arguments"] and bool(task["arguments"]["data"]): + doc = task["arguments"] + loc_vars = Variables(variables.data) + + VariableTableManager.handle_variable_doc(loc_vars, doc) + task["arguments"] = {key: value for key, value in loc_vars.data.items() if key in doc.keys()} @classmethod def process_task_template( From 13b6f13cf13f63c9a2c55db909d8c3498bd70b25 Mon Sep 17 00:00:00 2001 From: HSN Date: Sun, 9 Mar 2025 23:07:14 +0600 Subject: [PATCH 19/27] refactor: general refactor on formatting --- chk/infrastructure/symbol_table.py | 1 - chk/infrastructure/templating.py | 2 ++ chk/modules/validate/assertion_services.py | 1 - chk/modules/workflow/__init__.py | 10 ++++++++-- 4 files changed, 10 insertions(+), 4 deletions(-) diff --git a/chk/infrastructure/symbol_table.py b/chk/infrastructure/symbol_table.py index cf2b9b15..704c4d25 100644 --- a/chk/infrastructure/symbol_table.py +++ b/chk/infrastructure/symbol_table.py @@ -196,7 +196,6 @@ def handle_composite( cls.handle_absolute(variable_doc, replaced_values) cls.handle_composite(variable_doc, replaced_values) - @classmethod def handle_execute_context( cls, variable_doc: Variables, exec_ctx: ExecuteContext diff --git a/chk/infrastructure/templating.py b/chk/infrastructure/templating.py index 4e1987a9..2418167d 100644 --- a/chk/infrastructure/templating.py +++ b/chk/infrastructure/templating.py @@ -78,10 +78,12 @@ def is_template_str(tpl: str) -> bool: _dm_sets = [("<%", "%>"), ("<@", "@>"), ("<#", "#>")] return any([_dm_set[0] in tpl and _dm_set[1] in tpl for _dm_set in _dm_sets]) + ###################################### # Jinja Filters ###################################### + def filter_fromjson(value: typing.Any) -> str: """Convert a JSON string to a Python dictionary.""" diff --git a/chk/modules/validate/assertion_services.py b/chk/modules/validate/assertion_services.py index c1f75532..027d6553 100644 --- a/chk/modules/validate/assertion_services.py +++ b/chk/modules/validate/assertion_services.py @@ -6,7 +6,6 @@ from datetime import datetime import chk.modules.validate.assertion_function as asrt_f -from chk.infrastructure.helper import Cast from chk.infrastructure.logging import debug from chk.infrastructure.templating import JinjaTemplate, is_template_str from chk.modules.validate.assertion_message import get_assert_msg_for diff --git a/chk/modules/workflow/__init__.py b/chk/modules/workflow/__init__.py index 8778f565..110e2288 100644 --- a/chk/modules/workflow/__init__.py +++ b/chk/modules/workflow/__init__.py @@ -123,7 +123,9 @@ def process_task_variables_template(cls, task: dict, variables: Variables): loc_vars = Variables(variables.data) VariableTableManager.handle_variable_doc(loc_vars, doc) - task["variables"] = {key: value for key, value in loc_vars.data.items() if key in doc.keys()} + task["variables"] = { + key: value for key, value in loc_vars.data.items() if key in doc.keys() + } # handle task arguments if "arguments" in task and bool(task["arguments"]): @@ -132,7 +134,11 @@ def process_task_variables_template(cls, task: dict, variables: Variables): loc_vars = Variables(variables.data) VariableTableManager.handle_variable_doc(loc_vars, doc) - task["arguments"] = {key: value for key, value in loc_vars.data.items() if key in doc.keys()} + task["arguments"] = { + key: value + for key, value in loc_vars.data.items() + if key in doc.keys() + } @classmethod def process_task_template( From 619eed75ecbc79e280ea1e920ea5018f7d669628 Mon Sep 17 00:00:00 2001 From: HSN Date: Tue, 11 Mar 2025 11:29:40 +0600 Subject: [PATCH 20/27] feat: Improve version information closes #372 --- chk/console/main.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/chk/console/main.py b/chk/console/main.py index ad062920..a14ecc7f 100644 --- a/chk/console/main.py +++ b/chk/console/main.py @@ -20,6 +20,7 @@ # root command @click.group() +@click.version_option() @click.option( "--debug/--no-debug", is_flag=True, default=True, help="Enable debug logging" ) @@ -35,10 +36,11 @@ def chk(ctx: click.Context, debug: bool) -> None: ░░█████████ █████ █████ █████ ░░████ ░░████░████ ░░████████ █████ ░░██████ ░░░░░░░░░ ░░░░░ ░░░░░ ░░░░░ ░░░░ ░░░░ ░░░░ ░░░░░░░░ ░░░░░ ░░░░░░ + \b Low-code API quality testing, and automation toolbox. - Version 0.5.0 """ + ctx.ensure_object(dict) ctx.obj["debug"] = debug From 85cef265a7a22bdec1b094e4211716a66179f881 Mon Sep 17 00:00:00 2001 From: HSN Date: Tue, 11 Mar 2025 11:34:25 +0600 Subject: [PATCH 21/27] chore: package version update --- poetry.lock | 12 ++++++------ requirements-dev.txt | 12 ++++++------ requirements.txt | 6 +++--- 3 files changed, 15 insertions(+), 15 deletions(-) diff --git a/poetry.lock b/poetry.lock index a823016e..7fc152a3 100644 --- a/poetry.lock +++ b/poetry.lock @@ -318,13 +318,13 @@ files = [ [[package]] name = "jinja2" -version = "3.1.5" +version = "3.1.6" description = "A very fast and expressive template engine." optional = false python-versions = ">=3.7" files = [ - {file = "jinja2-3.1.5-py3-none-any.whl", hash = "sha256:aba0f4dc9ed8013c424088f68a5c226f7d6097ed89b246d7749c2ec4175c6adb"}, - {file = "jinja2-3.1.5.tar.gz", hash = "sha256:8fefff8dc3034e27bb80d67c671eb8a9bc424c0ef4c0826edbff304cceff43bb"}, + {file = "jinja2-3.1.6-py3-none-any.whl", hash = "sha256:85ece4451f492d0c13c5dd7c13a64681a86afae63a5f347908daf103ce6d2f67"}, + {file = "jinja2-3.1.6.tar.gz", hash = "sha256:0137fb05990d35f1275a587e9aee6d56da821fc83491a0fb838183be43f66d6d"}, ] [package.dependencies] @@ -848,13 +848,13 @@ files = [ [[package]] name = "setuptools" -version = "75.8.2" +version = "76.0.0" description = "Easily download, build, install, upgrade, and uninstall Python packages" optional = false python-versions = ">=3.9" files = [ - {file = "setuptools-75.8.2-py3-none-any.whl", hash = "sha256:558e47c15f1811c1fa7adbd0096669bf76c1d3f433f58324df69f3f5ecac4e8f"}, - {file = "setuptools-75.8.2.tar.gz", hash = "sha256:4880473a969e5f23f2a2be3646b2dfd84af9028716d398e46192f84bc36900d2"}, + {file = "setuptools-76.0.0-py3-none-any.whl", hash = "sha256:199466a166ff664970d0ee145839f5582cb9bca7a0a3a2e795b6a9cb2308e9c6"}, + {file = "setuptools-76.0.0.tar.gz", hash = "sha256:43b4ee60e10b0d0ee98ad11918e114c70701bc6051662a9a675a0496c1a158f4"}, ] [package.extras] diff --git a/requirements-dev.txt b/requirements-dev.txt index 86465d6b..3608019d 100644 --- a/requirements-dev.txt +++ b/requirements-dev.txt @@ -188,9 +188,9 @@ idna==3.10 ; python_version >= "3.13" and python_version < "4.0" \ iniconfig==2.0.0 ; python_version >= "3.13" and python_version < "4.0" \ --hash=sha256:2d91e135bf72d31a410b17c16da610a82cb55f6b0477d1a902134b24a455b8b3 \ --hash=sha256:b6a85871a79d2e3b22d2d1b94ac2824226a63c6b741c88f7ae975f18b6778374 -jinja2==3.1.5 ; python_version >= "3.13" and python_version < "4.0" \ - --hash=sha256:8fefff8dc3034e27bb80d67c671eb8a9bc424c0ef4c0826edbff304cceff43bb \ - --hash=sha256:aba0f4dc9ed8013c424088f68a5c226f7d6097ed89b246d7749c2ec4175c6adb +jinja2==3.1.6 ; python_version >= "3.13" and python_version < "4.0" \ + --hash=sha256:0137fb05990d35f1275a587e9aee6d56da821fc83491a0fb838183be43f66d6d \ + --hash=sha256:85ece4451f492d0c13c5dd7c13a64681a86afae63a5f347908daf103ce6d2f67 loguru==0.7.3 ; python_version >= "3.13" and python_version < "4.0" \ --hash=sha256:19480589e77d47b8d85b2c827ad95d49bf31b0dcde16593892eb51dd18706eb6 \ --hash=sha256:31a33c10c8e1e10422bfd431aeb5d351c7cf7fa671e3c4df004162264b28220c @@ -496,9 +496,9 @@ ruff==0.8.6 ; python_version >= "3.13" and python_version < "4.0" \ --hash=sha256:e169ea1b9eae61c99b257dc83b9ee6c76f89042752cb2d83486a7d6e48e8f764 \ --hash=sha256:e88b8f6d901477c41559ba540beeb5a671e14cd29ebd5683903572f4b40a9807 \ --hash=sha256:f1d70bef3d16fdc897ee290d7d20da3cbe4e26349f62e8a0274e7a3f4ce7a905 -setuptools==75.8.2 ; python_version >= "3.13" and python_version < "4.0" \ - --hash=sha256:4880473a969e5f23f2a2be3646b2dfd84af9028716d398e46192f84bc36900d2 \ - --hash=sha256:558e47c15f1811c1fa7adbd0096669bf76c1d3f433f58324df69f3f5ecac4e8f +setuptools==76.0.0 ; python_version >= "3.13" and python_version < "4.0" \ + --hash=sha256:199466a166ff664970d0ee145839f5582cb9bca7a0a3a2e795b6a9cb2308e9c6 \ + --hash=sha256:43b4ee60e10b0d0ee98ad11918e114c70701bc6051662a9a675a0496c1a158f4 shiv==1.0.8 ; python_version >= "3.13" and python_version < "4.0" \ --hash=sha256:2a68d69e98ce81cb5b8fdafbfc1e27efa93e6d89ca14bfae33482e4176f561d6 \ --hash=sha256:a60e4b05a2d2f8b820d567b1d89ee59af731759771c32c282d03c4ceae6aba24 diff --git a/requirements.txt b/requirements.txt index 4d5ba71c..49e13357 100644 --- a/requirements.txt +++ b/requirements.txt @@ -112,9 +112,9 @@ defusedxml==0.7.1 ; python_version >= "3.13" and python_version < "4.0" \ idna==3.10 ; python_version >= "3.13" and python_version < "4.0" \ --hash=sha256:12f65c9b470abda6dc35cf8e63cc574b1c52b11df2c86030af0ac09b01b13ea9 \ --hash=sha256:946d195a0d259cbba61165e88e65941f16e9b36ea6ddb97f00452bae8b1287d3 -jinja2==3.1.5 ; python_version >= "3.13" and python_version < "4.0" \ - --hash=sha256:8fefff8dc3034e27bb80d67c671eb8a9bc424c0ef4c0826edbff304cceff43bb \ - --hash=sha256:aba0f4dc9ed8013c424088f68a5c226f7d6097ed89b246d7749c2ec4175c6adb +jinja2==3.1.6 ; python_version >= "3.13" and python_version < "4.0" \ + --hash=sha256:0137fb05990d35f1275a587e9aee6d56da821fc83491a0fb838183be43f66d6d \ + --hash=sha256:85ece4451f492d0c13c5dd7c13a64681a86afae63a5f347908daf103ce6d2f67 loguru==0.7.3 ; python_version >= "3.13" and python_version < "4.0" \ --hash=sha256:19480589e77d47b8d85b2c827ad95d49bf31b0dcde16593892eb51dd18706eb6 \ --hash=sha256:31a33c10c8e1e10422bfd431aeb5d351c7cf7fa671e3c4df004162264b28220c From b47a0f1be82f5e1a6ada39908fd94a971b702541 Mon Sep 17 00:00:00 2001 From: HSN Date: Sat, 15 Mar 2025 14:54:23 +0600 Subject: [PATCH 22/27] refactor: fix formatting with ruff --- chk/__init__.py | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/chk/__init__.py b/chk/__init__.py index 8cf545bb..a91d28d5 100644 --- a/chk/__init__.py +++ b/chk/__init__.py @@ -1,3 +1 @@ -""" -chk command-line app -""" +"""chk command-line app""" From d80e0309fe01a4bce3d45661fc2cb4e78a03a868 Mon Sep 17 00:00:00 2001 From: HSN Date: Sat, 15 Mar 2025 14:55:26 +0600 Subject: [PATCH 23/27] refactor: update ruff config --- ruff.toml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/ruff.toml b/ruff.toml index f7e726f9..681d4f17 100644 --- a/ruff.toml +++ b/ruff.toml @@ -39,8 +39,8 @@ target-version = "py313" # Enable Pyflakes (`F`) and a subset of the pycodestyle (`E`) codes by default. # Unlike Flake8, Ruff doesn't enable pycodestyle warnings (`W`) or # McCabe complexity (`C901`) by default. -select = ["E4", "E7", "E9", "F"] -ignore = [] +select = ["E", "W", "F", "C", "D", "B", "T"] +ignore = ["N816", "C901"] # Allow fix for all enabled rules (when `--fix`) is provided. fixable = ["ALL"] From ad10c24bec009ab1186bff98553b3004334a767f Mon Sep 17 00:00:00 2001 From: HSN Date: Sat, 15 Mar 2025 14:56:13 +0600 Subject: [PATCH 24/27] chore: install pre-commit --- poetry.lock | 119 ++++++++++++++++++++++++++++++++++++++++++- pyproject.toml | 1 + requirements-dev.txt | 24 +++++++++ 3 files changed, 143 insertions(+), 1 deletion(-) diff --git a/poetry.lock b/poetry.lock index 7fc152a3..50c8a626 100644 --- a/poetry.lock +++ b/poetry.lock @@ -48,6 +48,17 @@ files = [ {file = "certifi-2025.1.31.tar.gz", hash = "sha256:3d5da6925056f6f18f119200434a4780a94263f10d1c21d032a6f6b2baa20651"}, ] +[[package]] +name = "cfgv" +version = "3.4.0" +description = "Validate configuration and produce human readable error messages." +optional = false +python-versions = ">=3.8" +files = [ + {file = "cfgv-3.4.0-py2.py3-none-any.whl", hash = "sha256:b7265b1f29fd3316bfcd2b330d63d024f2bfd8bcb8b0272f8e19a504856c48f9"}, + {file = "cfgv-3.4.0.tar.gz", hash = "sha256:e52591d4c5f5dead8e0f673fb16db7949d2cfb3f7da4582893288f0ded8fe560"}, +] + [[package]] name = "charset-normalizer" version = "3.4.1" @@ -260,6 +271,17 @@ files = [ {file = "defusedxml-0.7.1.tar.gz", hash = "sha256:1bb3032db185915b62d7c6209c5a8792be6a32ab2fedacc84e01b52c51aa3e69"}, ] +[[package]] +name = "distlib" +version = "0.3.9" +description = "Distribution utilities" +optional = false +python-versions = "*" +files = [ + {file = "distlib-0.3.9-py2.py3-none-any.whl", hash = "sha256:47f8c22fd27c27e25a65601af709b38e4f0a45ea4fc2e710f65755fa8caaaf87"}, + {file = "distlib-0.3.9.tar.gz", hash = "sha256:a60f20dea646b8a33f3e7772f74dc0b2d0772d2837ee1342a00645c81edf9403"}, +] + [[package]] name = "executing" version = "2.2.0" @@ -274,6 +296,22 @@ files = [ [package.extras] tests = ["asttokens (>=2.1.0)", "coverage", "coverage-enable-subprocess", "ipython", "littleutils", "pytest", "rich"] +[[package]] +name = "filelock" +version = "3.18.0" +description = "A platform independent file lock." +optional = false +python-versions = ">=3.9" +files = [ + {file = "filelock-3.18.0-py3-none-any.whl", hash = "sha256:c401f4f8377c4464e6db25fff06205fd89bdd83b65eb0488ed1b160f780e21de"}, + {file = "filelock-3.18.0.tar.gz", hash = "sha256:adbc88eabb99d2fec8c9c1b229b171f18afa655400173ddc653d5d01501fb9f2"}, +] + +[package.extras] +docs = ["furo (>=2024.8.6)", "sphinx (>=8.1.3)", "sphinx-autodoc-typehints (>=3)"] +testing = ["covdefaults (>=2.3)", "coverage (>=7.6.10)", "diff-cover (>=9.2.1)", "pytest (>=8.3.4)", "pytest-asyncio (>=0.25.2)", "pytest-cov (>=6)", "pytest-mock (>=3.14)", "pytest-timeout (>=2.3.1)", "virtualenv (>=20.28.1)"] +typing = ["typing-extensions (>=4.12.2)"] + [[package]] name = "icecream" version = "2.1.4" @@ -291,6 +329,20 @@ colorama = ">=0.3.9" executing = ">=2.1.0" pygments = ">=2.2.0" +[[package]] +name = "identify" +version = "2.6.9" +description = "File identification library for Python" +optional = false +python-versions = ">=3.9" +files = [ + {file = "identify-2.6.9-py2.py3-none-any.whl", hash = "sha256:c98b4322da415a8e5a70ff6e51fbc2d2932c015532d77e9f8537b4ba7813b150"}, + {file = "identify-2.6.9.tar.gz", hash = "sha256:d40dfe3142a1421d8518e3d3985ef5ac42890683e32306ad614a29490abeb6bf"}, +] + +[package.extras] +license = ["ukkonen"] + [[package]] name = "idna" version = "3.10" @@ -484,6 +536,17 @@ files = [ {file = "mypy_extensions-1.0.0.tar.gz", hash = "sha256:75dbf8955dc00442a438fc4d0666508a9a97b6bd41aa2f0ffe9d2f2725af0782"}, ] +[[package]] +name = "nodeenv" +version = "1.9.1" +description = "Node.js virtual environment builder" +optional = false +python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*,!=3.5.*,!=3.6.*,>=2.7" +files = [ + {file = "nodeenv-1.9.1-py2.py3-none-any.whl", hash = "sha256:ba11c9782d29c27c70ffbdda2d7415098754709be8a7056d79a737cd901155c9"}, + {file = "nodeenv-1.9.1.tar.gz", hash = "sha256:6ec12890a2dab7946721edbfbcd91f3319c6ccc9aec47be7c7e6b7011ee6645f"}, +] + [[package]] name = "packaging" version = "24.2" @@ -506,6 +569,22 @@ files = [ {file = "pip-25.0.1.tar.gz", hash = "sha256:88f96547ea48b940a3a385494e181e29fb8637898f88d88737c5049780f196ea"}, ] +[[package]] +name = "platformdirs" +version = "4.3.6" +description = "A small Python package for determining appropriate platform-specific dirs, e.g. a `user data dir`." +optional = false +python-versions = ">=3.8" +files = [ + {file = "platformdirs-4.3.6-py3-none-any.whl", hash = "sha256:73e575e1408ab8103900836b97580d5307456908a03e92031bab39e4554cc3fb"}, + {file = "platformdirs-4.3.6.tar.gz", hash = "sha256:357fb2acbc885b0419afd3ce3ed34564c13c9b95c89360cd9563f73aa5e2b907"}, +] + +[package.extras] +docs = ["furo (>=2024.8.6)", "proselint (>=0.14)", "sphinx (>=8.0.2)", "sphinx-autodoc-typehints (>=2.4)"] +test = ["appdirs (==1.4.4)", "covdefaults (>=2.3)", "pytest (>=8.3.2)", "pytest-cov (>=5)", "pytest-mock (>=3.14)"] +type = ["mypy (>=1.11.2)"] + [[package]] name = "pluggy" version = "1.5.0" @@ -521,6 +600,24 @@ files = [ dev = ["pre-commit", "tox"] testing = ["pytest", "pytest-benchmark"] +[[package]] +name = "pre-commit" +version = "4.1.0" +description = "A framework for managing and maintaining multi-language pre-commit hooks." +optional = false +python-versions = ">=3.9" +files = [ + {file = "pre_commit-4.1.0-py2.py3-none-any.whl", hash = "sha256:d29e7cb346295bcc1cc75fc3e92e343495e3ea0196c9ec6ba53f49f10ab6ae7b"}, + {file = "pre_commit-4.1.0.tar.gz", hash = "sha256:ae3f018575a588e30dfddfab9a05448bfbd6b73d78709617b5a2b853549716d4"}, +] + +[package.dependencies] +cfgv = ">=2.0.0" +identify = ">=1.0.0" +nodeenv = ">=0.11.1" +pyyaml = ">=5.1" +virtualenv = ">=20.10.0" + [[package]] name = "pydantic" version = "2.10.6" @@ -913,6 +1010,26 @@ h2 = ["h2 (>=4,<5)"] socks = ["pysocks (>=1.5.6,!=1.5.7,<2.0)"] zstd = ["zstandard (>=0.18.0)"] +[[package]] +name = "virtualenv" +version = "20.29.3" +description = "Virtual Python Environment builder" +optional = false +python-versions = ">=3.8" +files = [ + {file = "virtualenv-20.29.3-py3-none-any.whl", hash = "sha256:3e3d00f5807e83b234dfb6122bf37cfadf4be216c53a49ac059d02414f819170"}, + {file = "virtualenv-20.29.3.tar.gz", hash = "sha256:95e39403fcf3940ac45bc717597dba16110b74506131845d9b687d5e73d947ac"}, +] + +[package.dependencies] +distlib = ">=0.3.7,<1" +filelock = ">=3.12.2,<4" +platformdirs = ">=3.9.1,<5" + +[package.extras] +docs = ["furo (>=2023.7.26)", "proselint (>=0.13)", "sphinx (>=7.1.2,!=7.3)", "sphinx-argparse (>=0.4)", "sphinxcontrib-towncrier (>=0.2.1a0)", "towncrier (>=23.6)"] +test = ["covdefaults (>=2.3)", "coverage (>=7.2.7)", "coverage-enable-subprocess (>=1)", "flaky (>=3.7)", "packaging (>=23.1)", "pytest (>=7.4)", "pytest-env (>=0.8.2)", "pytest-freezer (>=0.4.8)", "pytest-mock (>=3.11.1)", "pytest-randomly (>=3.12)", "pytest-timeout (>=2.1)", "setuptools (>=68)", "time-machine (>=2.10)"] + [[package]] name = "win32-setctime" version = "1.2.0" @@ -941,4 +1058,4 @@ files = [ [metadata] lock-version = "2.0" python-versions = "^3.13" -content-hash = "aef733793ba3254a8846da90033fc1be061d59477f5e370b9a3d60565687b45a" +content-hash = "18a25d86da2e7d2dcd15c921efd6bcf698baacfb24c53a6d0c44f79b77eade8e" diff --git a/pyproject.toml b/pyproject.toml index 56e15657..3bd0e532 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -59,6 +59,7 @@ requests-mock = "^1.12.1" pytest-cov = "^6.0.0" ruff = "^0.8.4" shiv = "^1.0.8" +pre-commit = "^4.1.0" [tool.poetry.scripts] chk = "chk.console.main:chk" diff --git a/requirements-dev.txt b/requirements-dev.txt index 3608019d..0a0b43b2 100644 --- a/requirements-dev.txt +++ b/requirements-dev.txt @@ -10,6 +10,9 @@ cerberus==1.3.7 ; python_version >= "3.13" and python_version < "4.0" \ certifi==2025.1.31 ; python_version >= "3.13" and python_version < "4.0" \ --hash=sha256:3d5da6925056f6f18f119200434a4780a94263f10d1c21d032a6f6b2baa20651 \ --hash=sha256:ca78db4565a652026a4db2bcdf68f2fb589ea80d0be70e03929ed730746b84fe +cfgv==3.4.0 ; python_version >= "3.13" and python_version < "4.0" \ + --hash=sha256:b7265b1f29fd3316bfcd2b330d63d024f2bfd8bcb8b0272f8e19a504856c48f9 \ + --hash=sha256:e52591d4c5f5dead8e0f673fb16db7949d2cfb3f7da4582893288f0ded8fe560 charset-normalizer==3.4.1 ; python_version >= "3.13" and python_version < "4.0" \ --hash=sha256:0167ddc8ab6508fe81860a57dd472b2ef4060e8d378f0cc555707126830f2537 \ --hash=sha256:01732659ba9b5b873fc117534143e4feefecf3b2078b0a6a2e925271bb6f4cfa \ @@ -176,12 +179,21 @@ coverage[toml]==7.6.12 ; python_version >= "3.13" and python_version < "4.0" \ defusedxml==0.7.1 ; python_version >= "3.13" and python_version < "4.0" \ --hash=sha256:1bb3032db185915b62d7c6209c5a8792be6a32ab2fedacc84e01b52c51aa3e69 \ --hash=sha256:a352e7e428770286cc899e2542b6cdaedb2b4953ff269a210103ec58f6198a61 +distlib==0.3.9 ; python_version >= "3.13" and python_version < "4.0" \ + --hash=sha256:47f8c22fd27c27e25a65601af709b38e4f0a45ea4fc2e710f65755fa8caaaf87 \ + --hash=sha256:a60f20dea646b8a33f3e7772f74dc0b2d0772d2837ee1342a00645c81edf9403 executing==2.2.0 ; python_version >= "3.13" and python_version < "4.0" \ --hash=sha256:11387150cad388d62750327a53d3339fad4888b39a6fe233c3afbb54ecffd3aa \ --hash=sha256:5d108c028108fe2551d1a7b2e8b713341e2cb4fc0aa7dcf966fa4327a5226755 +filelock==3.18.0 ; python_version >= "3.13" and python_version < "4.0" \ + --hash=sha256:adbc88eabb99d2fec8c9c1b229b171f18afa655400173ddc653d5d01501fb9f2 \ + --hash=sha256:c401f4f8377c4464e6db25fff06205fd89bdd83b65eb0488ed1b160f780e21de icecream==2.1.4 ; python_version >= "3.13" and python_version < "4.0" \ --hash=sha256:58755e58397d5350a76f25976dee7b607f5febb3c6e1cddfe6b1951896e91573 \ --hash=sha256:7bb715f69102cae871b3a361c3b656536db02cfcadac9664c673581cac4df4fd +identify==2.6.9 ; python_version >= "3.13" and python_version < "4.0" \ + --hash=sha256:c98b4322da415a8e5a70ff6e51fbc2d2932c015532d77e9f8537b4ba7813b150 \ + --hash=sha256:d40dfe3142a1421d8518e3d3985ef5ac42890683e32306ad614a29490abeb6bf idna==3.10 ; python_version >= "3.13" and python_version < "4.0" \ --hash=sha256:12f65c9b470abda6dc35cf8e63cc574b1c52b11df2c86030af0ac09b01b13ea9 \ --hash=sha256:946d195a0d259cbba61165e88e65941f16e9b36ea6ddb97f00452bae8b1287d3 @@ -292,15 +304,24 @@ mypy==1.15.0 ; python_version >= "3.13" and python_version < "4.0" \ --hash=sha256:d10d994b41fb3497719bbf866f227b3489048ea4bbbb5015357db306249f7980 \ --hash=sha256:e601a7fa172c2131bff456bb3ee08a88360760d0d2f8cbd7a75a65497e2df078 \ --hash=sha256:f95579473af29ab73a10bada2f9722856792a36ec5af5399b653aa28360290a5 +nodeenv==1.9.1 ; python_version >= "3.13" and python_version < "4.0" \ + --hash=sha256:6ec12890a2dab7946721edbfbcd91f3319c6ccc9aec47be7c7e6b7011ee6645f \ + --hash=sha256:ba11c9782d29c27c70ffbdda2d7415098754709be8a7056d79a737cd901155c9 packaging==24.2 ; python_version >= "3.13" and python_version < "4.0" \ --hash=sha256:09abb1bccd265c01f4a3aa3f7a7db064b36514d2cba19a2f694fe6150451a759 \ --hash=sha256:c228a6dc5e932d346bc5739379109d49e8853dd8223571c7c5b55260edc0b97f pip==25.0.1 ; python_version >= "3.13" and python_version < "4.0" \ --hash=sha256:88f96547ea48b940a3a385494e181e29fb8637898f88d88737c5049780f196ea \ --hash=sha256:c46efd13b6aa8279f33f2864459c8ce587ea6a1a59ee20de055868d8f7688f7f +platformdirs==4.3.6 ; python_version >= "3.13" and python_version < "4.0" \ + --hash=sha256:357fb2acbc885b0419afd3ce3ed34564c13c9b95c89360cd9563f73aa5e2b907 \ + --hash=sha256:73e575e1408ab8103900836b97580d5307456908a03e92031bab39e4554cc3fb pluggy==1.5.0 ; python_version >= "3.13" and python_version < "4.0" \ --hash=sha256:2cffa88e94fdc978c4c574f15f9e59b7f4201d439195c3715ca9e2486f1d0cf1 \ --hash=sha256:44e1ad92c8ca002de6377e165f3e0f1be63266ab4d554740532335b9d75ea669 +pre-commit==4.1.0 ; python_version >= "3.13" and python_version < "4.0" \ + --hash=sha256:ae3f018575a588e30dfddfab9a05448bfbd6b73d78709617b5a2b853549716d4 \ + --hash=sha256:d29e7cb346295bcc1cc75fc3e92e343495e3ea0196c9ec6ba53f49f10ab6ae7b pydantic-core==2.27.2 ; python_version >= "3.13" and python_version < "4.0" \ --hash=sha256:00bad2484fa6bda1e216e7345a798bd37c68fb2d97558edd584942aa41b7d278 \ --hash=sha256:0296abcb83a797db256b773f45773da397da75a08f5fcaef41f2044adec05f50 \ @@ -508,6 +529,9 @@ typing-extensions==4.12.2 ; python_version >= "3.13" and python_version < "4.0" urllib3==2.3.0 ; python_version >= "3.13" and python_version < "4.0" \ --hash=sha256:1cee9ad369867bfdbbb48b7dd50374c0967a0bb7710050facf0dd6911440e3df \ --hash=sha256:f8c5449b3cf0861679ce7e0503c7b44b5ec981bec0d1d3795a07f1ba96f0204d +virtualenv==20.29.3 ; python_version >= "3.13" and python_version < "4.0" \ + --hash=sha256:3e3d00f5807e83b234dfb6122bf37cfadf4be216c53a49ac059d02414f819170 \ + --hash=sha256:95e39403fcf3940ac45bc717597dba16110b74506131845d9b687d5e73d947ac win32-setctime==1.2.0 ; python_version >= "3.13" and python_version < "4.0" and sys_platform == "win32" \ --hash=sha256:95d644c4e708aba81dc3704a116d8cbc974d70b3bdb8be1d150e36be6e9d1390 \ --hash=sha256:ae1fdf948f5640aae05c511ade119313fb6a30d7eabe25fef9764dca5873c4c0 From d3102ba1745dfffa2f9e9bb388e05fb2e044c392 Mon Sep 17 00:00:00 2001 From: HSN Date: Sat, 15 Mar 2025 14:56:40 +0600 Subject: [PATCH 25/27] feat: add a pre-commit config --- .pre-commit-config.yaml | 12 ++++++++++++ 1 file changed, 12 insertions(+) create mode 100644 .pre-commit-config.yaml diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml new file mode 100644 index 00000000..21b11536 --- /dev/null +++ b/.pre-commit-config.yaml @@ -0,0 +1,12 @@ +repos: + - repo: https://github.com/astral-sh/ruff-pre-commit + # Ruff version. + rev: v0.11.0 + hooks: + # Run the linter. + - id: ruff + args: [ --fix ] + files: ^chk/.*\.py$ + # Run the formatter. + - id: ruff-format + files: ^chk/.*\.py$ From 6412a5f20a5b77666e805218afeb21ab06335e59 Mon Sep 17 00:00:00 2001 From: HSN Date: Sun, 16 Mar 2025 21:10:45 +0600 Subject: [PATCH 26/27] refactor: remove document formatting and incr line-len --- ruff.toml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/ruff.toml b/ruff.toml index 681d4f17..82b3d9d5 100644 --- a/ruff.toml +++ b/ruff.toml @@ -29,7 +29,7 @@ exclude = [ ] # Same as Black. -line-length = 88 +line-length = 120 indent-width = 4 # Assume Python 3.13 @@ -39,7 +39,7 @@ target-version = "py313" # Enable Pyflakes (`F`) and a subset of the pycodestyle (`E`) codes by default. # Unlike Flake8, Ruff doesn't enable pycodestyle warnings (`W`) or # McCabe complexity (`C901`) by default. -select = ["E", "W", "F", "C", "D", "B", "T"] +select = ["E", "W", "F", "C", "B", "T"] ignore = ["N816", "C901"] # Allow fix for all enabled rules (when `--fix`) is provided. From 7843bab543a3cde60dd5a663690eace7fa0de8b7 Mon Sep 17 00:00:00 2001 From: HSN Date: Sun, 16 Mar 2025 21:11:03 +0600 Subject: [PATCH 27/27] refactor: code formatting refactor by ruff --- chk/console/main.py | 24 ++---- chk/infrastructure/document.py | 12 +-- chk/infrastructure/helper.py | 12 +-- chk/infrastructure/symbol_table.py | 15 +--- chk/infrastructure/templating.py | 4 +- chk/infrastructure/version.py | 6 +- chk/infrastructure/view.py | 4 +- chk/modules/fetch/__init__.py | 8 +- chk/modules/fetch/entities.py | 21 +---- chk/modules/fetch/services.py | 32 ++------ chk/modules/validate/__init__.py | 42 +++------- chk/modules/validate/assertion_function.py | 20 ++--- chk/modules/validate/assertion_message.py | 32 ++++++-- chk/modules/validate/assertion_services.py | 24 ++---- chk/modules/validate/assertion_validation.py | 80 +++++--------------- chk/modules/validate/services.py | 8 +- chk/modules/workflow/__init__.py | 32 ++------ chk/modules/workflow/entities.py | 6 +- chk/modules/workflow/services.py | 22 ++---- 19 files changed, 116 insertions(+), 288 deletions(-) diff --git a/chk/console/main.py b/chk/console/main.py index a14ecc7f..fad7f3c3 100644 --- a/chk/console/main.py +++ b/chk/console/main.py @@ -21,9 +21,7 @@ # root command @click.group() @click.version_option() -@click.option( - "--debug/--no-debug", is_flag=True, default=True, help="Enable debug logging" -) +@click.option("--debug/--no-debug", is_flag=True, default=True, help="Enable debug logging") @click.pass_context def chk(ctx: click.Context, debug: bool) -> None: """\b @@ -50,9 +48,7 @@ def chk(ctx: click.Context, debug: bool) -> None: # run fetch sub-command @chk.command() @click.argument("file", type=click.Path(exists=True)) -@click.option( - "-nf", "--no-format", is_flag=True, help="No formatting to show the output" -) +@click.option("-nf", "--no-format", is_flag=True, help="No formatting to show the output") @click.option("-V", "--variables", type=str, help="Pass variable(s) as JSON object") @click.pass_context def fetch(cctx: click.Context, file: str, no_format: bool, variables: str) -> None: @@ -85,9 +81,7 @@ def fetch(cctx: click.Context, file: str, no_format: bool, variables: str) -> No # run validate sub-command @chk.command() @click.argument("file", type=click.Path(exists=True)) -@click.option( - "-nf", "--no-format", is_flag=True, help="No formatting to show the output" -) +@click.option("-nf", "--no-format", is_flag=True, help="No formatting to show the output") @click.option("-V", "--variables", type=str, help="Pass variable(s) as JSON object") @click.option("-D", "--data", type=str, help="Pass data as JSON") @click.option("-Di", "--data-in", is_flag=True, help="Pass data as JSON [from pipe]") @@ -111,13 +105,9 @@ def validate( with with_catch_log(): _data = ( - load_variables_as_dict( - get_stdin(), except_msg="-Di, --data-in: Pass data as JSON [from pipe]" - ) + load_variables_as_dict(get_stdin(), except_msg="-Di, --data-in: Pass data as JSON [from pipe]") if data_in - else load_variables_as_dict( - data, except_msg="-D, --data: Pass data as JSON" - ) + else load_variables_as_dict(data, except_msg="-D, --data: Pass data as JSON") ) execution_ctx = ExecuteContext( @@ -141,9 +131,7 @@ def validate( # run validate sub-command @chk.command() @click.argument("file", type=click.Path(exists=True)) -@click.option( - "-nf", "--no-format", is_flag=True, help="No formatting to show the output" -) +@click.option("-nf", "--no-format", is_flag=True, help="No formatting to show the output") @click.option("-V", "--variables", type=str, help="Pass variable(s) as JSON object") @click.pass_context def workflow(cctx: click.Context, file: str, no_format: bool, variables: str) -> None: diff --git a/chk/infrastructure/document.py b/chk/infrastructure/document.py index 2f592564..1efd4642 100644 --- a/chk/infrastructure/document.py +++ b/chk/infrastructure/document.py @@ -33,9 +33,7 @@ class VersionedDocumentSupport: """DocumentVersionSupport""" @staticmethod - def validate_with_schema( - schema: dict, doc: VersionedDocument | VersionedDocumentV2 - ) -> bool: + def validate_with_schema(schema: dict, doc: VersionedDocument | VersionedDocumentV2) -> bool: """Validate a document with given schema Args: @@ -54,12 +52,8 @@ def validate_with_schema( try: if not validator.validate(file_ctx.document, schema): - raise RuntimeError( - f"File exception: Validation failed: {str(validator.errors)}" - ) + raise RuntimeError(f"File exception: Validation failed: {str(validator.errors)}") except cerberus.validator.DocumentError as doc_err: - raise RuntimeError( - f"Document exception: `version` string not found: {str(doc_err)}" - ) from doc_err + raise RuntimeError(f"Document exception: `version` string not found: {str(doc_err)}") from doc_err return True diff --git a/chk/infrastructure/helper.py b/chk/infrastructure/helper.py index 562eea74..6f6c30f8 100644 --- a/chk/infrastructure/helper.py +++ b/chk/infrastructure/helper.py @@ -27,9 +27,7 @@ def data_set(data: dict | list, keymap: str, value: Any) -> Any: if isinstance(data, dict): if current_item.isnumeric(): - raise IndexError( - f"Trying to set numeric key `{current_item}` on dict `{data}`" - ) + raise IndexError(f"Trying to set numeric key `{current_item}` on dict `{data}`") if len(keymap_list) == 0: data[current_item] = value @@ -42,9 +40,7 @@ def data_set(data: dict | list, keymap: str, value: Any) -> Any: if isinstance(data, list): if not current_item.isnumeric(): - raise IndexError( - f"Trying to set non-numeric index `{current_item}` on list `{data}`" - ) + raise IndexError(f"Trying to set non-numeric index `{current_item}` on list `{data}`") current_item_i = int(current_item) if len(data) < current_item_i: @@ -170,9 +166,7 @@ def try_dict(to_dict: Any, say_exception: bool = False) -> dict | Any: return to_dict -def formatter( - message: object, cb: Callable = str, dump: bool = True, is_err: bool = False -) -> str: +def formatter(message: object, cb: Callable = str, dump: bool = True, is_err: bool = False) -> str: """Format message with given callback Args: diff --git a/chk/infrastructure/symbol_table.py b/chk/infrastructure/symbol_table.py index 704c4d25..485f0444 100644 --- a/chk/infrastructure/symbol_table.py +++ b/chk/infrastructure/symbol_table.py @@ -189,17 +189,13 @@ def handle_composite( composite_values[key] = val if composite_values: - replaced_values: dict = replace_callback( - composite_values, variable_doc.data - ) + replaced_values: dict = replace_callback(composite_values, variable_doc.data) cls.handle_absolute(variable_doc, replaced_values) cls.handle_composite(variable_doc, replaced_values) @classmethod - def handle_execute_context( - cls, variable_doc: Variables, exec_ctx: ExecuteContext - ) -> None: + def handle_execute_context(cls, variable_doc: Variables, exec_ctx: ExecuteContext) -> None: """Handle variables passed from external context Args: @@ -276,12 +272,9 @@ def get_exposed_replaced_data(document: VersionedDocumentV2, store: dict) -> dic if expose_doc := ExposeManager.get_expose_doc(file_ctx.document): exposed_doc_t = copy.copy(expose_doc) - exposed_doc_t = [ - str(key).replace("%>", "").replace("<%", "").strip() - for key in exposed_doc_t - ] + exposed_doc_t = [str(key).replace("%>", "").replace("<%", "").strip() for key in exposed_doc_t] expose_val = ExposeManager.replace_values(expose_doc, store) - return dict(zip(exposed_doc_t, expose_val)) + return dict(zip(exposed_doc_t, expose_val, strict=False)) return {} diff --git a/chk/infrastructure/templating.py b/chk/infrastructure/templating.py index 2418167d..88f6154f 100644 --- a/chk/infrastructure/templating.py +++ b/chk/infrastructure/templating.py @@ -66,7 +66,7 @@ def render(env: NativeEnvironment, template: str, data: dict) -> typing.Any: # handle undefined vars undeclared_vars = find_undeclared_variables(env.parse(template)) - if all([_var in data for _var in undeclared_vars]): + if all(_var in data for _var in undeclared_vars): return env.from_string(template).render(data) else: return template @@ -76,7 +76,7 @@ def is_template_str(tpl: str) -> bool: """Check given string is templated string or not""" _dm_sets = [("<%", "%>"), ("<@", "@>"), ("<#", "#>")] - return any([_dm_set[0] in tpl and _dm_set[1] in tpl for _dm_set in _dm_sets]) + return any(_dm_set[0] in tpl and _dm_set[1] in tpl for _dm_set in _dm_sets) ###################################### diff --git a/chk/infrastructure/version.py b/chk/infrastructure/version.py index 87ada61c..525b2b83 100644 --- a/chk/infrastructure/version.py +++ b/chk/infrastructure/version.py @@ -68,11 +68,7 @@ def parse(self) -> None: ver_l[-1], ) - if ( - len(self.provider) == 0 - or len(self.doc_type) == 0 - or len(self.doc_type_ver) == 0 - ): + if len(self.provider) == 0 or len(self.doc_type) == 0 or len(self.doc_type_ver) == 0: raise ValueError("Invalid version string") def validate(self) -> bool: diff --git a/chk/infrastructure/view.py b/chk/infrastructure/view.py index 7db4d6b2..e469d73b 100644 --- a/chk/infrastructure/view.py +++ b/chk/infrastructure/view.py @@ -64,9 +64,7 @@ def display( formatter(wfp.dump_json(), dump=exec_ctx.options["dump"]) -def die_with_error( - err: Exception, Presenter: type[PresentationBuilder], is_fmt: bool -) -> None: +def die_with_error(err: Exception, Presenter: type[PresentationBuilder], is_fmt: bool) -> None: """die_with_error""" prs = Presenter(data=None) diff --git a/chk/modules/fetch/__init__.py b/chk/modules/fetch/__init__.py index 49666c99..918a9de1 100644 --- a/chk/modules/fetch/__init__.py +++ b/chk/modules/fetch/__init__.py @@ -30,9 +30,7 @@ def call(file_ctx: FileContext, exec_ctx: ExecuteContext) -> ExecResponse: http_doc = HttpDocumentSupport.from_file_context(file_ctx) debug(http_doc.model_dump_json()) - VersionedDocumentSupport.validate_with_schema( - HttpDocumentSupport.build_schema(), http_doc - ) + VersionedDocumentSupport.validate_with_schema(HttpDocumentSupport.build_schema(), http_doc) except Exception as ex: error_trace(exception=sys.exc_info()).error(ex) return ExecResponse( @@ -96,9 +94,7 @@ def call(file_ctx: FileContext, exec_ctx: ExecuteContext) -> ExecResponse: @with_catch_log -def execute( - ctx: FileContext, exec_ctx: ExecuteContext, cb: abc.Callable = lambda *args: ... -) -> None: +def execute(ctx: FileContext, exec_ctx: ExecuteContext, cb: abc.Callable = lambda *args: ...) -> None: """Call with a http document Args: diff --git a/chk/modules/fetch/entities.py b/chk/modules/fetch/entities.py index fa847e60..4f639b18 100644 --- a/chk/modules/fetch/entities.py +++ b/chk/modules/fetch/entities.py @@ -177,9 +177,7 @@ def __bool__(self) -> bool: @computed_field # type: ignore @property def info(self) -> str: - return ( - f"{Http_V10 if self.version == 10 else Http_V11} {self.code} {self.reason}" - ) + return f"{Http_V10 if self.version == 10 else Http_V11} {self.code} {self.reason}" @computed_field # type: ignore @property @@ -248,7 +246,7 @@ def from_response(response: requests.Response) -> ApiResponseModel: ApiResponseModel: _description_ """ - arm = ApiResponseModel( + return ApiResponseModel( code=response.status_code, version=11 if response.raw.version == 0 else response.raw.version, reason=response.reason, @@ -256,18 +254,11 @@ def from_response(response: requests.Response) -> ApiResponseModel: body=response.text, ) - if arm: - arm.body_content_type - - return arm - @staticmethod def from_dict(**kwargs: dict) -> ApiResponseModel: """Construct from dict""" - if not all( - [item in kwargs.keys() for item in ["code", "info", "headers", "body"]] - ): + if not all(item in kwargs.keys() for item in ["code", "info", "headers", "body"]): raise KeyError("Expected keys to make ApiResponseModel not found") if not isinstance(kwargs["code"], int): @@ -311,11 +302,7 @@ def as_fmt_str(self) -> str: presentation += "\r\n".join(f"{k}: {v}" for k, v in self.headers.items()) presentation += "\r\n\r\n" - presentation += ( - json.dumps(self.body_as_dict()) - if self.body_content_type == CTYPE_JSON - else self.body - ) + presentation += json.dumps(self.body_as_dict()) if self.body_content_type == CTYPE_JSON else self.body return presentation diff --git a/chk/modules/fetch/services.py b/chk/modules/fetch/services.py index 3739354c..dd6214ff 100644 --- a/chk/modules/fetch/services.py +++ b/chk/modules/fetch/services.py @@ -43,7 +43,7 @@ def allowed_method(value: str) -> bool: ValueError: When unsupported method found """ - if value not in set(method for method in HttpMethod): + if value not in set(HttpMethod): raise ValueError("Unsupported method") return True @@ -105,9 +105,7 @@ def add_authorization(request_data: dict, request_arg: dict) -> None: # handle bearer auth if (tag_be := request_data.get(RequestConfigNode.AUTH_BE)) is not None: - request_arg["auth"] = BearerAuthentication( - tag_be.get(RequestConfigNode.AUTH_BE_TOK) - ) + request_arg["auth"] = BearerAuthentication(tag_be.get(RequestConfigNode.AUTH_BE_TOK)) @staticmethod def add_body(request_data: dict, request_arg: dict) -> None: @@ -141,10 +139,7 @@ def add_body(request_data: dict, request_arg: dict) -> None: if "headers" not in request_arg: request_arg["headers"] = {} - if ( - "content-type" not in request_arg["headers"] - and "Content-Type" not in request_arg["headers"] - ): + if "content-type" not in request_arg["headers"] and "Content-Type" not in request_arg["headers"]: request_arg["headers"]["content-type"] = CTYPE_XML request_arg["data"] = body @@ -152,10 +147,7 @@ def add_body(request_data: dict, request_arg: dict) -> None: if "headers" not in request_arg: request_arg["headers"] = {} - if ( - "content-type" not in request_arg["headers"] - and "Content-Type" not in request_arg["headers"] - ): + if "content-type" not in request_arg["headers"] and "Content-Type" not in request_arg["headers"]: request_arg["headers"]["content-type"] = "text/plain" request_arg["data"] = str(body) @@ -252,11 +244,7 @@ def dump_error_fmt(self, err: object = None) -> str: if not err: err = self.data.exception - return ( - f"Fetch error\n------\n{repr(err)}" - if err - else "Fetch error\n------\nUnspecified error" - ) + return f"Fetch error\n------\n{repr(err)}" if err else "Fetch error\n------\nUnspecified error" def dump_json(self) -> str: """dump json""" @@ -265,10 +253,7 @@ def dump_json(self) -> str: for key, expose_item in self.data.exposed.items(): if key == RequestConfigNode.LOCAL and all( - [ - item in expose_item.keys() - for item in ["code", "info", "headers", "body"] - ] + item in expose_item.keys() for item in ("code", "info", "headers", "body") ): resp = ApiResponseModel.from_dict(**expose_item) displayables.append(resp.model_dump()) @@ -284,10 +269,7 @@ def dump_fmt(self) -> str: for key, expose_item in self.data.exposed.items(): if key == RequestConfigNode.LOCAL and all( - [ - item in expose_item.keys() - for item in ["code", "info", "headers", "body"] - ] + item in expose_item.keys() for item in ("code", "info", "headers", "body") ): resp = ApiResponseModel.from_dict(**expose_item) displayables.append(resp.as_fmt_str()) diff --git a/chk/modules/validate/__init__.py b/chk/modules/validate/__init__.py index ffc3c8c7..8bbb7fb3 100644 --- a/chk/modules/validate/__init__.py +++ b/chk/modules/validate/__init__.py @@ -131,23 +131,15 @@ def set_data_template( """sets data or template""" data = data_get(exec_ctx.arguments, "data", {}) - variables[ValidationConfigNode.VAR_NODE.value] = ( - data if data else validate_doc.data - ) + variables[ValidationConfigNode.VAR_NODE.value] = data if data else validate_doc.data @staticmethod def process_data_template(variables: Variables) -> None: """process data or template before assertion""" data = variables[ValidationConfigNode.VAR_NODE.value] - tmp_variables = { - key: val - for key, val in variables.data.items() - if key != ValidationConfigNode.VAR_NODE.value - } + tmp_variables = {key: val for key, val in variables.data.items() if key != ValidationConfigNode.VAR_NODE.value} - variables[ValidationConfigNode.VAR_NODE.value] = replace_value( - data, tmp_variables - ) + variables[ValidationConfigNode.VAR_NODE.value] = replace_value(data, tmp_variables) @staticmethod def make_assertion_entry_list(assert_lst: list[dict]) -> list[AssertionEntry]: @@ -160,14 +152,10 @@ def make_assertion_entry_list(assert_lst: list[dict]) -> list[AssertionEntry]: try: validator = cerberus.Validator(get_schema_map(_assert_type)) except KeyError as ex: - raise KeyError( - f"`{_assert_type}` key not found. in {repr(each_assert)}" - ) from ex + raise KeyError(f"`{_assert_type}` key not found. in {repr(each_assert)}") from ex if not validator.validate(each_assert): - raise RuntimeError( - f"key: Unsupported structure for `{each_assert}`. {validator.errors}" - ) + raise RuntimeError(f"key: Unsupported structure for `{each_assert}`. {validator.errors}") if _assert_type not in MAP_TYPE_TO_FN: raise RuntimeError(f"type: `{_assert_type}` not supported.") @@ -176,9 +164,7 @@ def make_assertion_entry_list(assert_lst: list[dict]) -> list[AssertionEntry]: raise RuntimeError("key: `actual` not found in one of the asserts.") _actual = each_assert["actual"] - _expected = ( - each_assert["expected"] if "expected" in each_assert else NotImplemented - ) + _expected = each_assert["expected"] if "expected" in each_assert else NotImplemented _msg_pass = each_assert.get("msg_pass", "") _msg_fail = each_assert.get("msg_fail", "") @@ -187,9 +173,7 @@ def make_assertion_entry_list(assert_lst: list[dict]) -> list[AssertionEntry]: _extra_fld = {} if len(only) > 0: - _extra_fld = { - key: val for key, val in each_assert.items() if key in only - } + _extra_fld = {key: val for key, val in each_assert.items() if key in only} ae = AssertionEntry( assert_type=_assert_type, actual=_actual, @@ -216,9 +200,7 @@ def call(file_ctx: FileContext, exec_ctx: ExecuteContext) -> ExecResponse: validate_doc = ValidationDocument.from_file_context(file_ctx) debug(validate_doc.model_dump_json()) - VersionedDocumentSupport.validate_with_schema( - ValidationDocumentSupport.build_schema(), validate_doc - ) + VersionedDocumentSupport.validate_with_schema(ValidationDocumentSupport.build_schema(), validate_doc) except Exception as ex: error_trace(exception=sys.exc_info()).error(ex) return ExecResponse( @@ -239,9 +221,7 @@ def call(file_ctx: FileContext, exec_ctx: ExecuteContext) -> ExecResponse: debug(variable_doc.data) try: - assert_list = ValidationDocumentSupport.make_assertion_entry_list( - validate_doc.asserts - ) + assert_list = ValidationDocumentSupport.make_assertion_entry_list(validate_doc.asserts) run_rpt = AssertionEntryListRunner.test_run(assert_list, variable_doc.data) except Exception as ex: @@ -292,9 +272,7 @@ def call(file_ctx: FileContext, exec_ctx: ExecuteContext) -> ExecResponse: @with_catch_log -def execute( - ctx: FileContext, exec_ctx: ExecuteContext, cb: abc.Callable = lambda *args: ... -) -> None: +def execute(ctx: FileContext, exec_ctx: ExecuteContext, cb: abc.Callable = lambda *args: ...) -> None: """Run a validation document Args: diff --git a/chk/modules/validate/assertion_function.py b/chk/modules/validate/assertion_function.py index d103d03d..7c15db29 100644 --- a/chk/modules/validate/assertion_function.py +++ b/chk/modules/validate/assertion_function.py @@ -141,9 +141,7 @@ def boolean(actual: object, expected: object, **_: object) -> _AResult: if not isinstance(actual, bool): return ValueError("actual_not_bool") - if not isinstance(expected, types.NotImplementedType) and not isinstance( - expected, bool - ): + if not isinstance(expected, types.NotImplementedType) and not isinstance(expected, bool): return ValueError("expected_not_bool") if isinstance(expected, bool): @@ -176,9 +174,7 @@ def integer_greater(actual: object, extra_fields: dict, **_: object) -> _AResult return int(extra_fields["other"]) < actual -def integer_greater_or_equal( - actual: object, extra_fields: dict, **_: object -) -> _AResult: +def integer_greater_or_equal(actual: object, extra_fields: dict, **_: object) -> _AResult: """Assert integer is greater than or equal to other""" if not isinstance(actual, int): @@ -365,9 +361,7 @@ def date_after(actual: str, expected: str, extra_fields: dict, **_: object) -> _ return ValueError("date_conversion_issue") -def date_after_or_equal( - actual: str, expected: str, extra_fields: dict, **_: object -) -> _AResult: +def date_after_or_equal(actual: str, expected: str, extra_fields: dict, **_: object) -> _AResult: """Assert actual date is after or equal to expected date""" if not isinstance(actual, str): @@ -385,9 +379,7 @@ def date_after_or_equal( return ValueError("date_conversion_issue") -def date_before( - actual: str, expected: str, extra_fields: dict, **_: object -) -> _AResult: +def date_before(actual: str, expected: str, extra_fields: dict, **_: object) -> _AResult: """Assert actual date is after expected date""" if not isinstance(actual, str): @@ -405,9 +397,7 @@ def date_before( return ValueError("date_conversion_issue") -def date_before_or_equal( - actual: str, expected: str, extra_fields: dict, **_: object -) -> _AResult: +def date_before_or_equal(actual: str, expected: str, extra_fields: dict, **_: object) -> _AResult: """Assert actual date is after expected date""" if not isinstance(actual, str): diff --git a/chk/modules/validate/assertion_message.py b/chk/modules/validate/assertion_message.py index 8abdad3d..6068b538 100644 --- a/chk/modules/validate/assertion_message.py +++ b/chk/modules/validate/assertion_message.py @@ -33,7 +33,9 @@ "fail": "actual `{type_actual}({value_actual})` is not a boolean value", "actual_not_bool": "actual `{type_actual}({value_actual})` is not a boolean value", "expected_not_bool": "expected `{type_expected}({value_expected})` is not a boolean value", - "expected_mismatch": "actual `{type_actual}({value_actual})` and expected `{type_expected}({value_expected})` mismatch", + "expected_mismatch": ( + "actual `{type_actual}({value_actual})` and expected `{type_expected}({value_expected})` mismatch" + ), }, "integer": { "pass": "actual `{type_actual}({value_actual})` is a integer value", @@ -143,28 +145,48 @@ "fail": "actual `{type_actual}({value_actual})` is not after `{type_expected}({value_expected})`", "actual_not_str": "actual `{type_actual}({value_actual})` is not a string formatted date.", "expected_not_str": "expected `{type_expected}({value_expected})` is not a string formatted date.", - "date_conversion_issue": "date conversion error. actual `{type_actual}({value_actual})`, expected `{type_expected}({value_expected})`, format `{extra_fields[format]}`.", + "date_conversion_issue": ( + "date conversion error." + " actual `{type_actual}({value_actual})`" + ", expected `{type_expected}({value_expected})`" + ", format `{extra_fields[format]}`." + ), }, "date_after_or_equal": { "pass": "actual `{type_actual}({value_actual})` is after or equal `{type_expected}({value_expected})`", "fail": "actual `{type_actual}({value_actual})` is not after or equal `{type_expected}({value_expected})`", "actual_not_str": "actual `{type_actual}({value_actual})` is not a string formatted date.", "expected_not_str": "expected `{type_expected}({value_expected})` is not a string formatted date.", - "date_conversion_issue": "date conversion error. actual `{type_actual}({value_actual})`, expected `{type_expected}({value_expected})`, format `{extra_fields[format]}`.", + "date_conversion_issue": ( + "date conversion error." + " actual `{type_actual}({value_actual})`" + ", expected `{type_expected}({value_expected})`" + ", format `{extra_fields[format]}`." + ), }, "date_before": { "pass": "actual `{type_actual}({value_actual})` is before `{type_expected}({value_expected})`", "fail": "actual `{type_actual}({value_actual})` is not before `{type_expected}({value_expected})`", "actual_not_str": "actual `{type_actual}({value_actual})` is not a string formatted date.", "expected_not_str": "expected `{type_expected}({value_expected})` is not a string formatted date.", - "date_conversion_issue": "date conversion error. actual `{type_actual}({value_actual})`, expected `{type_expected}({value_expected})`, format `{extra_fields[format]}`.", + "date_conversion_issue": ( + "date conversion error." + " actual `{type_actual}({value_actual})`" + ", expected `{type_expected}({value_expected})`" + ", format `{extra_fields[format]}`." + ), }, "date_before_or_equal": { "pass": "actual `{type_actual}({value_actual})` is before or equal `{type_expected}({value_expected})`", "fail": "actual `{type_actual}({value_actual})` is not before or equal `{type_expected}({value_expected})`", "actual_not_str": "actual `{type_actual}({value_actual})` is not a string formatted date.", "expected_not_str": "expected `{type_expected}({value_expected})` is not a string formatted date.", - "date_conversion_issue": "date conversion error. actual `{type_actual}({value_actual})`, expected `{type_expected}({value_expected})`, format `{extra_fields[format]}`.", + "date_conversion_issue": ( + "date conversion error." + " actual `{type_actual}({value_actual})`" + ", expected `{type_expected}({value_expected})`" + ", format `{extra_fields[format]}`." + ), }, "list_": { "pass": "actual `{type_actual}({value_actual})` is a list", diff --git a/chk/modules/validate/assertion_services.py b/chk/modules/validate/assertion_services.py index 027d6553..3f4c9fe2 100644 --- a/chk/modules/validate/assertion_services.py +++ b/chk/modules/validate/assertion_services.py @@ -62,9 +62,7 @@ class AssertionEntryListRunner: """AssertionAntiquary is service class that run assertion""" @staticmethod - def _replace_assertion_values( - assert_item: AssertionEntry, variable_d: dict - ) -> AssertionEntry: + def _replace_assertion_values(assert_item: AssertionEntry, variable_d: dict) -> AssertionEntry: """Replace value for actual and expected data Args: @@ -81,9 +79,7 @@ def _replace_assertion_values( assert_item.actual = str_tpl.render(variable_d) # replace expected value for template - if isinstance(assert_item.expected, str) and is_template_str( - assert_item.expected - ): + if isinstance(assert_item.expected, str) and is_template_str(assert_item.expected): str_tpl = JinjaTemplate.make(assert_item.expected) assert_item.expected = str_tpl.render(variable_d) @@ -98,21 +94,15 @@ def _prepare_message() -> str: asrt_fn_name = MAP_TYPE_TO_FN[assert_item.assert_type].__name__ if isinstance(asrt_resp, ValueError): - return get_assert_msg_for(f"{asrt_fn_name}.{str(asrt_resp)}").format( - **detail.get_message_values() - ) + return get_assert_msg_for(f"{asrt_fn_name}.{str(asrt_resp)}").format(**detail.get_message_values()) if asrt_resp: message = ( - get_assert_msg_for(f"{asrt_fn_name}.pass") - if assert_item.msg_pass == "" - else assert_item.msg_pass + get_assert_msg_for(f"{asrt_fn_name}.pass") if assert_item.msg_pass == "" else assert_item.msg_pass ) else: message = ( - get_assert_msg_for(f"{asrt_fn_name}.fail") - if assert_item.msg_fail == "" - else assert_item.msg_fail + get_assert_msg_for(f"{asrt_fn_name}.fail") if assert_item.msg_fail == "" else assert_item.msg_fail ) return message.format(**detail.get_message_values()) @@ -158,9 +148,7 @@ def test_run(assert_list: list[AssertionEntry], variables: dict) -> RunReport: run_report = RunReport(count_all=len(assert_list)) for assert_item in assert_list: - assert_item = AssertionEntryListRunner._replace_assertion_values( - assert_item, variables - ) + assert_item = AssertionEntryListRunner._replace_assertion_values(assert_item, variables) debug(assert_item) resp: RunDetail = AssertionEntryListRunner._prepare_test_run_result( diff --git a/chk/modules/validate/assertion_validation.py b/chk/modules/validate/assertion_validation.py index 3cfdbfe4..18dc6504 100644 --- a/chk/modules/validate/assertion_validation.py +++ b/chk/modules/validate/assertion_validation.py @@ -697,79 +697,39 @@ def get_schema_map(item: AssertionEntityType | None = None) -> dict: AssertionEntityType.NotEmpty: _get_schema_for_not_empty(_generic_schema), AssertionEntityType.Boolean: _get_schema_for_boolean(_generic_schema), AssertionEntityType.Integer: _get_schema_for_integer(_generic_schema), - AssertionEntityType.IntegerBetween: _get_schema_for_integer_between( - _generic_schema - ), - AssertionEntityType.IntegerGreater: _get_schema_for_integer_greater( - _generic_schema - ), - AssertionEntityType.IntegerGreaterOrEqual: _get_schema_for_integer_greater_or_equal( - _generic_schema - ), + AssertionEntityType.IntegerBetween: _get_schema_for_integer_between(_generic_schema), + AssertionEntityType.IntegerGreater: _get_schema_for_integer_greater(_generic_schema), + AssertionEntityType.IntegerGreaterOrEqual: _get_schema_for_integer_greater_or_equal(_generic_schema), AssertionEntityType.IntegerLess: _get_schema_for_integer_less(_generic_schema), - AssertionEntityType.IntegerLessOrEqual: _get_schema_for_integer_less_or_equal( - _generic_schema - ), + AssertionEntityType.IntegerLessOrEqual: _get_schema_for_integer_less_or_equal(_generic_schema), AssertionEntityType.Float: _get_schema_for_float(_generic_schema), - AssertionEntityType.FloatBetween: _get_schema_for_float_between( - _generic_schema - ), - AssertionEntityType.FloatGreater: _get_schema_for_float_greater( - _generic_schema - ), - AssertionEntityType.FloatGreaterOrEqual: _get_schema_for_float_greater_or_equal( - _generic_schema - ), + AssertionEntityType.FloatBetween: _get_schema_for_float_between(_generic_schema), + AssertionEntityType.FloatGreater: _get_schema_for_float_greater(_generic_schema), + AssertionEntityType.FloatGreaterOrEqual: _get_schema_for_float_greater_or_equal(_generic_schema), AssertionEntityType.FloatLess: _get_schema_for_float_less(_generic_schema), - AssertionEntityType.FloatLessOrEqual: _get_schema_for_float_less_or_equal( - _generic_schema - ), + AssertionEntityType.FloatLessOrEqual: _get_schema_for_float_less_or_equal(_generic_schema), AssertionEntityType.Str: _get_schema_for_str(_generic_schema), AssertionEntityType.StrHave: _get_schema_for_str_have(_generic_schema), - AssertionEntityType.StrDoNotHave: _get_schema_for_str_do_not_have( - _generic_schema - ), - AssertionEntityType.StrStartsWith: _get_schema_for_str_starts_with( - _generic_schema - ), - AssertionEntityType.StrDoNotStartsWith: _get_schema_for_str_do_not_starts_with( - _generic_schema - ), + AssertionEntityType.StrDoNotHave: _get_schema_for_str_do_not_have(_generic_schema), + AssertionEntityType.StrStartsWith: _get_schema_for_str_starts_with(_generic_schema), + AssertionEntityType.StrDoNotStartsWith: _get_schema_for_str_do_not_starts_with(_generic_schema), AssertionEntityType.StrEndsWith: _get_schema_for_str_ends_with(_generic_schema), - AssertionEntityType.StrDoNotEndsWith: _get_schema_for_str_do_not_ends_with( - _generic_schema - ), + AssertionEntityType.StrDoNotEndsWith: _get_schema_for_str_do_not_ends_with(_generic_schema), AssertionEntityType.Date: _get_schema_for_date(_generic_schema), AssertionEntityType.DateAfter: _get_schema_for_date_after(_generic_schema), - AssertionEntityType.DateAfterOrEqual: _get_schema_for_date_after_or_equal( - _generic_schema - ), + AssertionEntityType.DateAfterOrEqual: _get_schema_for_date_after_or_equal(_generic_schema), AssertionEntityType.DateBefore: _get_schema_for_date_before(_generic_schema), - AssertionEntityType.DateBeforeOrEqual: _get_schema_for_date_before_or_equal( - _generic_schema - ), + AssertionEntityType.DateBeforeOrEqual: _get_schema_for_date_before_or_equal(_generic_schema), AssertionEntityType.List: _get_schema_for_list(_generic_schema), - AssertionEntityType.ListContains: _get_schema_for_list_contains( - _generic_schema - ), - AssertionEntityType.ListDoNotContains: _get_schema_for_list_do_not_contains( - _generic_schema - ), - AssertionEntityType.ListHasIndex: _get_schema_for_list_has_index( - _generic_schema - ), - AssertionEntityType.ListDoNotHasIndex: _get_schema_for_list_do_not_has_index( - _generic_schema - ), + AssertionEntityType.ListContains: _get_schema_for_list_contains(_generic_schema), + AssertionEntityType.ListDoNotContains: _get_schema_for_list_do_not_contains(_generic_schema), + AssertionEntityType.ListHasIndex: _get_schema_for_list_has_index(_generic_schema), + AssertionEntityType.ListDoNotHasIndex: _get_schema_for_list_do_not_has_index(_generic_schema), AssertionEntityType.Map: _get_schema_for_map(_generic_schema), AssertionEntityType.MapKeyCount: _get_schema_for_map_key_count(_generic_schema), AssertionEntityType.MapHasKeys: _get_schema_for_map_has_keys(_generic_schema), - AssertionEntityType.MapDoNotHasKeys: _get_schema_for_map_do_not_has_keys( - _generic_schema - ), - AssertionEntityType.MapExactKeys: _get_schema_for_map_exact_keys( - _generic_schema - ), + AssertionEntityType.MapDoNotHasKeys: _get_schema_for_map_do_not_has_keys(_generic_schema), + AssertionEntityType.MapExactKeys: _get_schema_for_map_exact_keys(_generic_schema), AssertionEntityType.Count: _get_schema_for_count(_generic_schema), } diff --git a/chk/modules/validate/services.py b/chk/modules/validate/services.py index b2898b12..1b7f14ac 100644 --- a/chk/modules/validate/services.py +++ b/chk/modules/validate/services.py @@ -25,11 +25,7 @@ def dump_error_fmt(self, err: object = None) -> str: if not err: err = self.data.exception - return ( - f"Validate error\n------\n{repr(err)}" - if err - else "Validate error\n------\nUnspecified error" - ) + return f"Validate error\n------\n{repr(err)}" if err else "Validate error\n------\nUnspecified error" def dump_fmt(self) -> str: """dump formatted string""" @@ -49,7 +45,7 @@ def dump_json(self) -> str: display_items: list[dict] = [] - for key, item in self.data.exposed.items(): + for _key, item in self.data.exposed.items(): display_items.append(dict(item)) return json.dumps(display_items) diff --git a/chk/modules/workflow/__init__.py b/chk/modules/workflow/__init__.py index 110e2288..94e5c71d 100644 --- a/chk/modules/workflow/__init__.py +++ b/chk/modules/workflow/__init__.py @@ -67,11 +67,7 @@ def from_file_context(ctx: FileContext) -> WorkflowDocument: if id_str := data_get(ctx.document, "id"): id_str = slugify(str(id_str).strip()) else: - id_str = ( - slugify(name_str) - if name_str and len(name_str) > 0 - else pathlib.Path(ctx.filepath).stem - ) + id_str = slugify(name_str) if name_str and len(name_str) > 0 else pathlib.Path(ctx.filepath).stem if not name_str: name_str = id_str @@ -123,9 +119,7 @@ def process_task_variables_template(cls, task: dict, variables: Variables): loc_vars = Variables(variables.data) VariableTableManager.handle_variable_doc(loc_vars, doc) - task["variables"] = { - key: value for key, value in loc_vars.data.items() if key in doc.keys() - } + task["variables"] = {key: value for key, value in loc_vars.data.items() if key in doc.keys()} # handle task arguments if "arguments" in task and bool(task["arguments"]): @@ -134,16 +128,10 @@ def process_task_variables_template(cls, task: dict, variables: Variables): loc_vars = Variables(variables.data) VariableTableManager.handle_variable_doc(loc_vars, doc) - task["arguments"] = { - key: value - for key, value in loc_vars.data.items() - if key in doc.keys() - } + task["arguments"] = {key: value for key, value in loc_vars.data.items() if key in doc.keys()} @classmethod - def process_task_template( - cls, document: WorkflowDocument, variables: Variables - ) -> list: + def process_task_template(cls, document: WorkflowDocument, variables: Variables) -> list: """Process task block of document""" base_fpath: str = FileContext(*document.context).filepath @@ -167,9 +155,7 @@ def process_task_template( cls.process_task_variables_template(task, variables) - task_o_ = ChkwareTaskSupport.make_task( - task, **dict(base_file_path=base_fpath) - ) + task_o_ = ChkwareTaskSupport.make_task(task, **{"base_file_path": base_fpath}) execute_args = {"variables": json.dumps(task_o_.variables)} @@ -209,9 +195,7 @@ def process_task_template( return exec_report @classmethod - def execute_task( - cls, task_fn: Callable, task_params: TaskExecParam, variables: Variables - ) -> ExecResponse: + def execute_task(cls, task_fn: Callable, task_params: TaskExecParam, variables: Variables) -> ExecResponse: """execute_task""" _task_res: ExecResponse = task_fn(**task_params.as_dict()) @@ -279,9 +263,7 @@ def call(file_ctx: FileContext, exec_ctx: ExecuteContext) -> ExecResponse: @with_catch_log -def execute( - ctx: FileContext, exec_ctx: ExecuteContext, cb: abc.Callable = lambda *args: ... -) -> None: +def execute(ctx: FileContext, exec_ctx: ExecuteContext, cb: abc.Callable = lambda *args: ...) -> None: """Run a workflow document Args: diff --git a/chk/modules/workflow/entities.py b/chk/modules/workflow/entities.py index 07a80e59..1e9b3289 100644 --- a/chk/modules/workflow/entities.py +++ b/chk/modules/workflow/entities.py @@ -50,11 +50,7 @@ class ChkwareTask(BaseModel): def __init__(self, basepath: str, /, **kwargs: dict) -> None: """Constructor""" - if ( - "file" in kwargs - and isinstance(kwargs["file"], str) - and len(kwargs["file"]) != 0 - ): + if "file" in kwargs and isinstance(kwargs["file"], str) and len(kwargs["file"]) != 0: kwargs["file"] = generate_abs_path(basepath, kwargs["file"]) super().__init__(**kwargs) diff --git a/chk/modules/workflow/services.py b/chk/modules/workflow/services.py index f2e95424..e0fc332b 100644 --- a/chk/modules/workflow/services.py +++ b/chk/modules/workflow/services.py @@ -62,11 +62,7 @@ def dump_error_fmt(self, err: object = None) -> str: if not err: err = self.data.exception - return ( - f"Workflow error\n------\n{repr(err)}" - if err - else "Workflow error\n------\nUnspecified error" - ) + return f"Workflow error\n------\n{repr(err)}" if err else "Workflow error\n------\nUnspecified error" def _prepare_dump_data(self) -> dict: """prepare dump data""" @@ -81,9 +77,7 @@ def _prepare_dump_data(self) -> dict: if exec_report: r_dump["step_count"] = len(_document["tasks"]) - r_dump["step_failed"] = len( - [item for item in exec_report if not item.is_success] - ) + r_dump["step_failed"] = len([item for item in exec_report if not item.is_success]) r_dump["tasks"] = [] @@ -98,9 +92,7 @@ def _prepare_dump_data(self) -> dict: } if item.task.uses == "fetch": response_task_dump["fetch_request_method"] = ( - item.others["request_method"] - if "request_method" in item.others - else "" + item.others["request_method"] if "request_method" in item.others else "" ) response_task_dump["fetch_request_url"] = ( item.others["request_url"] if "request_url" in item.others else "" @@ -167,15 +159,11 @@ def _prepare_dump_str_for_steps(self) -> str: if not one_task["is_success"]: _computed_str += f"\n>> With message: {one_task['exception']}" elif one_task["uses"] == "validate": - _computed_str += ( - f">> Total tests: {one_task['validate_asserts_count_all']}, " - ) + _computed_str += f">> Total tests: {one_task['validate_asserts_count_all']}, " _computed_str += f"Failed: {one_task['validate_asserts_count_fail']}" if not one_task["is_success"]: _computed_str += f"\n>> With message: {one_task['exception']}\n" - _computed_str += "\n".join( - one_task["validate_asserts_err_messages"] - ) + _computed_str += "\n".join(one_task["validate_asserts_err_messages"]) return _computed_str