From c3bbb0a93eb3ce03179b7e61cf25a6bc586151c0 Mon Sep 17 00:00:00 2001 From: faucomte97 Date: Wed, 18 Sep 2024 11:07:34 +0100 Subject: [PATCH 01/11] fix: Upgrade to Python 3.12 --- .github/workflows/main.yml | 4 +- Pipfile | 14 +- Pipfile.lock | 463 ++++++++++++++++++++----------------- setup.py | 4 +- 4 files changed, 256 insertions(+), 229 deletions(-) diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index 2567d630..4f005ef1 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -16,7 +16,7 @@ jobs: secrets: inherit with: # Cannot be set with an env var. Value must match in the release job. - python-version: 3.8 + python-version: 3.12 release: concurrency: release @@ -25,7 +25,7 @@ jobs: if: github.ref_name == 'main' env: # Value must match in the test job. - PYTHON_VERSION: 3.8 + PYTHON_VERSION: 3.12 steps: - name: 🛫 Checkout uses: actions/checkout@v4 diff --git a/Pipfile b/Pipfile index 7d5eb43e..a45a3ccb 100644 --- a/Pipfile +++ b/Pipfile @@ -18,14 +18,14 @@ importlib-metadata = "==4.13.0" # TODO: remove. needed by old portal django-formtools = "==2.2" # TODO: remove. needed by old portal django-otp = "==1.0.2" # TODO: remove. needed by old portal # https://pypi.org/user/codeforlife/ -cfl-common = "==7.1.1" # TODO: remove -codeforlife-portal = "==7.1.1" # TODO: remove -rapid-router = "==6.0.1" # TODO: remove +cfl-common = "==7.3.3" # TODO: remove +codeforlife-portal = "==7.3.3" # TODO: remove +rapid-router = "==6.5.2" # TODO: remove phonenumbers = "==8.12.12" # TODO: remove [dev-packages] -black = "==23.1.0" -pytest = "==7.2.1" +black = "==24.8.0" +pytest = "==8.3.3" pytest-cov = "==5.0.0" pytest-env = "==0.8.1" pytest-xdist = {version = "==3.5.0", extras = ["psutil"]} @@ -34,7 +34,7 @@ django-extensions = "==3.2.1" django-test-migrations = "==1.2.0" pyparsing = "==3.0.9" pydot = "==1.4.2" -pylint = "==3.0.2" +pylint = "==3.2.7" pylint-django = "==2.5.5" isort = "==5.13.2" mypy = "==1.6.1" @@ -42,4 +42,4 @@ django-stubs = {version = "==4.2.6", extras = ["compatible-mypy"]} djangorestframework-stubs = {version = "==3.14.4", extras = ["compatible-mypy"]} [requires] -python_version = "3.8" +python_version = "3.12" diff --git a/Pipfile.lock b/Pipfile.lock index ec016233..0fb86605 100644 --- a/Pipfile.lock +++ b/Pipfile.lock @@ -1,11 +1,11 @@ { "_meta": { "hash": { - "sha256": "3452219b58681c3108990b3c6382d14f009c501c87a6c1c97858e7878513bfa4" + "sha256": "e5cbbfb8d045e2d6130c5df4c6d3dfac6092d75473e0cb02a95fd88bb7dc696b" }, "pipfile-spec": 6, "requires": { - "python_version": "3.8" + "python_version": "3.12" }, "sources": [ { @@ -26,19 +26,19 @@ }, "certifi": { "hashes": [ - "sha256:5a1e7645bc0ec61a09e26c36f6106dd4cf40c6db3a1fb6352b0244e7fb057c7b", - "sha256:c198e21b1289c2ab85ee4e67bb4b4ef3ead0892059901a8d5b622f24a1101e90" + "sha256:922820b53db7a7257ffbda3f597266d435245903d80737e34f8a45ff3e3230d8", + "sha256:bec941d2aa8195e248a60b31ff9f0558284cf01a52591ceda73ea9afffd69fd9" ], "markers": "python_version >= '3.6'", - "version": "==2024.7.4" + "version": "==2024.8.30" }, "cfl-common": { "hashes": [ - "sha256:888cb1feb8f38de6b29adb0a9217d45d7f95c93d47fb82b393eb49145d16f8a9", - "sha256:93a9a63be4f285d16aee5ecde362c245d3cfd0719f60bf631ab80a768ddf1955" + "sha256:dbad0d2b6372c9336957028a5e214880600b43eaff3630a414e0f78759fc2d50", + "sha256:e7205975d94e46be9dc789db10587236312ace0ea01d5a07905891ade37a4a7a" ], "index": "pypi", - "version": "==7.1.1" + "version": "==7.3.3" }, "charset-normalizer": { "hashes": [ @@ -138,11 +138,11 @@ }, "codeforlife-portal": { "hashes": [ - "sha256:1aa19971324828c03e087ad4996f23eb5959d57ae18f5d061cde26cb85f44ebd", - "sha256:c61039cfdd554a488e89b92c3ef54eb242b6b3d025072354b2ed938954b32786" + "sha256:4c6b479a28c5592976759b6f2d5615f9c9166cb1a971f9f1b1802f32dce04035", + "sha256:a5fbaabb819dedccab6529040a2112af889b8a111f6b502c0f643d9292926d57" ], "index": "pypi", - "version": "==7.1.1" + "version": "==7.3.3" }, "diff-match-patch": { "hashes": [ @@ -219,13 +219,6 @@ "markers": "python_version >= '3.8'", "version": "==4.0.3" }, - "django-js-reverse": { - "hashes": [ - "sha256:2a392d169f44e30b883c30dfcfd917a14167ce8fe196c99d2385b31c90d77aa0", - "sha256:8134c2ab6307c945edfa90671ca65e85d6c1754d48566bdd6464be259cc80c30" - ], - "version": "==0.9.1" - }, "django-otp": { "hashes": [ "sha256:8ba5ab9bd2738c7321376c349d7cce49cf4404e79f6804e0a3cc462a91728e18", @@ -269,6 +262,14 @@ ], "version": "==2.0.6" }, + "django-reverse-js": { + "hashes": [ + "sha256:7d626f4d660604e4c2623a494a08ddb70587375110cf4e7bb6f56eeb4471630f", + "sha256:89c15e3f1bd656a6f7c7f3641144c0a79d42ec692182c8edd6a91061674f6b62" + ], + "markers": "python_version >= '3.10'", + "version": "==0.1.7" + }, "django-sekizai": { "hashes": [ "sha256:5c5e16845d37ce822fc655ce79ec02715191b3d03330b550997bcb842cf24fdf", @@ -301,11 +302,11 @@ }, "idna": { "hashes": [ - "sha256:028ff3aadf0609c1fd278d8ea3089299412a7a8b9bd005dd08b9f8285bcb5cfc", - "sha256:82fee1fc78add43492d3a1898bfa6d8a904cc97d8427f683ed8e798d07761aa0" + "sha256:12f65c9b470abda6dc35cf8e63cc574b1c52b11df2c86030af0ac09b01b13ea9", + "sha256:946d195a0d259cbba61165e88e65941f16e9b36ea6ddb97f00452bae8b1287d3" ], - "markers": "python_version >= '3.5'", - "version": "==3.7" + "markers": "python_version >= '3.6'", + "version": "==3.10" }, "importlib-metadata": { "hashes": [ @@ -338,68 +339,97 @@ }, "numpy": { "hashes": [ - "sha256:04640dab83f7c6c85abf9cd729c5b65f1ebd0ccf9de90b270cd61935eef0197f", - "sha256:1452241c290f3e2a312c137a9999cdbf63f78864d63c79039bda65ee86943f61", - "sha256:222e40d0e2548690405b0b3c7b21d1169117391c2e82c378467ef9ab4c8f0da7", - "sha256:2541312fbf09977f3b3ad449c4e5f4bb55d0dbf79226d7724211acc905049400", - "sha256:31f13e25b4e304632a4619d0e0777662c2ffea99fcae2029556b17d8ff958aef", - "sha256:4602244f345453db537be5314d3983dbf5834a9701b7723ec28923e2889e0bb2", - "sha256:4979217d7de511a8d57f4b4b5b2b965f707768440c17cb70fbf254c4b225238d", - "sha256:4c21decb6ea94057331e111a5bed9a79d335658c27ce2adb580fb4d54f2ad9bc", - "sha256:6620c0acd41dbcb368610bb2f4d83145674040025e5536954782467100aa8835", - "sha256:692f2e0f55794943c5bfff12b3f56f99af76f902fc47487bdfe97856de51a706", - "sha256:7215847ce88a85ce39baf9e89070cb860c98fdddacbaa6c0da3ffb31b3350bd5", - "sha256:79fc682a374c4a8ed08b331bef9c5f582585d1048fa6d80bc6c35bc384eee9b4", - "sha256:7ffe43c74893dbf38c2b0a1f5428760a1a9c98285553c89e12d70a96a7f3a4d6", - "sha256:80f5e3a4e498641401868df4208b74581206afbee7cf7b8329daae82676d9463", - "sha256:95f7ac6540e95bc440ad77f56e520da5bf877f87dca58bd095288dce8940532a", - "sha256:9667575fb6d13c95f1b36aca12c5ee3356bf001b714fc354eb5465ce1609e62f", - "sha256:a5425b114831d1e77e4b5d812b69d11d962e104095a5b9c3b641a218abcc050e", - "sha256:b4bea75e47d9586d31e892a7401f76e909712a0fd510f58f5337bea9572c571e", - "sha256:b7b1fc9864d7d39e28f41d089bfd6353cb5f27ecd9905348c24187a768c79694", - "sha256:befe2bf740fd8373cf56149a5c23a0f601e82869598d41f8e188a0e9869926f8", - "sha256:c0bfb52d2169d58c1cdb8cc1f16989101639b34c7d3ce60ed70b19c63eba0b64", - "sha256:d11efb4dbecbdf22508d55e48d9c8384db795e1b7b51ea735289ff96613ff74d", - "sha256:dd80e219fd4c71fc3699fc1dadac5dcf4fd882bfc6f7ec53d30fa197b8ee22dc", - "sha256:e2926dac25b313635e4d6cf4dc4e51c8c0ebfed60b801c799ffc4c32bf3d1254", - "sha256:e98f220aa76ca2a977fe435f5b04d7b3470c0a2e6312907b37ba6068f26787f2", - "sha256:ed094d4f0c177b1b8e7aa9cba7d6ceed51c0e569a5318ac0ca9a090680a6a1b1", - "sha256:f136bab9c2cfd8da131132c2cf6cc27331dd6fae65f95f69dcd4ae3c3639c810", - "sha256:f3a86ed21e4f87050382c7bc96571755193c4c1392490744ac73d660e8f564a9" - ], - "markers": "python_version >= '3.8'", - "version": "==1.24.4" + "sha256:046356b19d7ad1890c751b99acad5e82dc4a02232013bd9a9a712fddf8eb60f5", + "sha256:0b8cc2715a84b7c3b161f9ebbd942740aaed913584cae9cdc7f8ad5ad41943d0", + "sha256:0d07841fd284718feffe7dd17a63a2e6c78679b2d386d3e82f44f0108c905550", + "sha256:13cc11c00000848702322af4de0147ced365c81d66053a67c2e962a485b3717c", + "sha256:13ce49a34c44b6de5241f0b38b07e44c1b2dcacd9e36c30f9c2fcb1bb5135db7", + "sha256:24c2ad697bd8593887b019817ddd9974a7f429c14a5469d7fad413f28340a6d2", + "sha256:251105b7c42abe40e3a689881e1793370cc9724ad50d64b30b358bbb3a97553b", + "sha256:2ca4b53e1e0b279142113b8c5eb7d7a877e967c306edc34f3b58e9be12fda8df", + "sha256:3269c9eb8745e8d975980b3a7411a98976824e1fdef11f0aacf76147f662b15f", + "sha256:397bc5ce62d3fb73f304bec332171535c187e0643e176a6e9421a6e3eacef06d", + "sha256:3fc5eabfc720db95d68e6646e88f8b399bfedd235994016351b1d9e062c4b270", + "sha256:50a95ca3560a6058d6ea91d4629a83a897ee27c00630aed9d933dff191f170cd", + "sha256:52ac2e48f5ad847cd43c4755520a2317f3380213493b9d8a4c5e37f3b87df504", + "sha256:53e27293b3a2b661c03f79aa51c3987492bd4641ef933e366e0f9f6c9bf257ec", + "sha256:57eb525e7c2a8fdee02d731f647146ff54ea8c973364f3b850069ffb42799647", + "sha256:5889dd24f03ca5a5b1e8a90a33b5a0846d8977565e4ae003a63d22ecddf6782f", + "sha256:59ca673ad11d4b84ceb385290ed0ebe60266e356641428c845b39cd9df6713ab", + "sha256:6435c48250c12f001920f0751fe50c0348f5f240852cfddc5e2f97e007544cbe", + "sha256:6e5a9cb2be39350ae6c8f79410744e80154df658d5bea06e06e0ac5bb75480d5", + "sha256:7be6a07520b88214ea85d8ac8b7d6d8a1839b0b5cb87412ac9f49fa934eb15d5", + "sha256:7c803b7934a7f59563db459292e6aa078bb38b7ab1446ca38dd138646a38203e", + "sha256:7dd86dfaf7c900c0bbdcb8b16e2f6ddf1eb1fe39c6c8cca6e94844ed3152a8fd", + "sha256:8661c94e3aad18e1ea17a11f60f843a4933ccaf1a25a7c6a9182af70610b2313", + "sha256:8ae0fd135e0b157365ac7cc31fff27f07a5572bdfc38f9c2d43b2aff416cc8b0", + "sha256:910b47a6d0635ec1bd53b88f86120a52bf56dcc27b51f18c7b4a2e2224c29f0f", + "sha256:913cc1d311060b1d409e609947fa1b9753701dac96e6581b58afc36b7ee35af6", + "sha256:920b0911bb2e4414c50e55bd658baeb78281a47feeb064ab40c2b66ecba85553", + "sha256:950802d17a33c07cba7fd7c3dcfa7d64705509206be1606f196d179e539111ed", + "sha256:981707f6b31b59c0c24bcda52e5605f9701cb46da4b86c2e8023656ad3e833cb", + "sha256:98ce7fb5b8063cfdd86596b9c762bf2b5e35a2cdd7e967494ab78a1fa7f8b86e", + "sha256:99f4a9ee60eed1385a86e82288971a51e71df052ed0b2900ed30bc840c0f2e39", + "sha256:9a8e06c7a980869ea67bbf551283bbed2856915f0a792dc32dd0f9dd2fb56728", + "sha256:ae8ce252404cdd4de56dcfce8b11eac3c594a9c16c231d081fb705cf23bd4d9e", + "sha256:afd9c680df4de71cd58582b51e88a61feed4abcc7530bcd3d48483f20fc76f2a", + "sha256:b49742cdb85f1f81e4dc1b39dcf328244f4d8d1ded95dea725b316bd2cf18c95", + "sha256:b5613cfeb1adfe791e8e681128f5f49f22f3fcaa942255a6124d58ca59d9528f", + "sha256:bab7c09454460a487e631ffc0c42057e3d8f2a9ddccd1e60c7bb8ed774992480", + "sha256:c8a0e34993b510fc19b9a2ce7f31cb8e94ecf6e924a40c0c9dd4f62d0aac47d9", + "sha256:caf5d284ddea7462c32b8d4a6b8af030b6c9fd5332afb70e7414d7fdded4bfd0", + "sha256:cea427d1350f3fd0d2818ce7350095c1a2ee33e30961d2f0fef48576ddbbe90f", + "sha256:d0cf7d55b1051387807405b3898efafa862997b4cba8aa5dbe657be794afeafd", + "sha256:d10c39947a2d351d6d466b4ae83dad4c37cd6c3cdd6d5d0fa797da56f710a6ae", + "sha256:d2b9cd92c8f8e7b313b80e93cedc12c0112088541dcedd9197b5dee3738c1201", + "sha256:d4c57b68c8ef5e1ebf47238e99bf27657511ec3f071c465f6b1bccbef12d4136", + "sha256:d51fc141ddbe3f919e91a096ec739f49d686df8af254b2053ba21a910ae518bf", + "sha256:e097507396c0be4e547ff15b13dc3866f45f3680f789c1a1301b07dadd3fbc78", + "sha256:e30356d530528a42eeba51420ae8bf6c6c09559051887196599d96ee5f536468", + "sha256:e8d5f8a8e3bc87334f025194c6193e408903d21ebaeb10952264943a985066ca", + "sha256:e8dfa9e94fc127c40979c3eacbae1e61fda4fe71d84869cc129e2721973231ef", + "sha256:f212d4f46b67ff604d11fff7cc62d36b3e8714edf68e44e9760e19be38c03eb0", + "sha256:f7506387e191fe8cdb267f912469a3cccc538ab108471291636a96a54e599556", + "sha256:fac6e277a41163d27dfab5f4ec1f7a83fac94e170665a4a50191b545721c6521", + "sha256:fcd8f556cdc8cfe35e70efb92463082b7f43dd7e547eb071ffc36abc0ca4699b" + ], + "markers": "python_version >= '3.10'", + "version": "==2.1.1" }, "pandas": { "hashes": [ - "sha256:04dbdbaf2e4d46ca8da896e1805bc04eb85caa9a82e259e8eed00254d5e0c682", - "sha256:1168574b036cd8b93abc746171c9b4f1b83467438a5e45909fed645cf8692dbc", - "sha256:1994c789bf12a7c5098277fb43836ce090f1073858c10f9220998ac74f37c69b", - "sha256:258d3624b3ae734490e4d63c430256e716f488c4fcb7c8e9bde2d3aa46c29089", - "sha256:32fca2ee1b0d93dd71d979726b12b61faa06aeb93cf77468776287f41ff8fdc5", - "sha256:37673e3bdf1551b95bf5d4ce372b37770f9529743d2498032439371fc7b7eb26", - "sha256:3ef285093b4fe5058eefd756100a367f27029913760773c8bf1d2d8bebe5d210", - "sha256:5247fb1ba347c1261cbbf0fcfba4a3121fbb4029d95d9ef4dc45406620b25c8b", - "sha256:5ec591c48e29226bcbb316e0c1e9423622bc7a4eaf1ef7c3c9fa1a3981f89641", - "sha256:694888a81198786f0e164ee3a581df7d505024fbb1f15202fc7db88a71d84ebd", - "sha256:69d7f3884c95da3a31ef82b7618af5710dba95bb885ffab339aad925c3e8ce78", - "sha256:6a21ab5c89dcbd57f78d0ae16630b090eec626360085a4148693def5452d8a6b", - "sha256:81af086f4543c9d8bb128328b5d32e9986e0c84d3ee673a2ac6fb57fd14f755e", - "sha256:9e4da0d45e7f34c069fe4d522359df7d23badf83abc1d1cef398895822d11061", - "sha256:9eae3dc34fa1aa7772dd3fc60270d13ced7346fcbcfee017d3132ec625e23bb0", - "sha256:9ee1a69328d5c36c98d8e74db06f4ad518a1840e8ccb94a4ba86920986bb617e", - "sha256:b084b91d8d66ab19f5bb3256cbd5ea661848338301940e17f4492b2ce0801fe8", - "sha256:b9cb1e14fdb546396b7e1b923ffaeeac24e4cedd14266c3497216dd4448e4f2d", - "sha256:ba619e410a21d8c387a1ea6e8a0e49bb42216474436245718d7f2e88a2f8d7c0", - "sha256:c02f372a88e0d17f36d3093a644c73cfc1788e876a7c4bcb4020a77512e2043c", - "sha256:ce0c6f76a0f1ba361551f3e6dceaff06bde7514a374aa43e33b588ec10420183", - "sha256:d9cd88488cceb7635aebb84809d087468eb33551097d600c6dad13602029c2df", - "sha256:e4c7c9f27a4185304c7caf96dc7d91bc60bc162221152de697c98eb0b2648dd8", - "sha256:f167beed68918d62bffb6ec64f2e1d8a7d297a038f86d4aed056b9493fca407f", - "sha256:f3421a7afb1a43f7e38e82e844e2bca9a6d793d66c1a7f9f0ff39a795bbc5e02" - ], - "markers": "python_version >= '3.8'", - "version": "==2.0.3" + "sha256:001910ad31abc7bf06f49dcc903755d2f7f3a9186c0c040b827e522e9cef0863", + "sha256:0ca6377b8fca51815f382bd0b697a0814c8bda55115678cbc94c30aacbb6eff2", + "sha256:0cace394b6ea70c01ca1595f839cf193df35d1575986e484ad35c4aeae7266c1", + "sha256:1cb51fe389360f3b5a4d57dbd2848a5f033350336ca3b340d1c53a1fad33bcad", + "sha256:2925720037f06e89af896c70bca73459d7e6a4be96f9de79e2d440bd499fe0db", + "sha256:3e374f59e440d4ab45ca2fffde54b81ac3834cf5ae2cdfa69c90bc03bde04d76", + "sha256:40ae1dffb3967a52203105a077415a86044a2bea011b5f321c6aa64b379a3f51", + "sha256:43498c0bdb43d55cb162cdc8c06fac328ccb5d2eabe3cadeb3529ae6f0517c32", + "sha256:4abfe0be0d7221be4f12552995e58723c7422c80a659da13ca382697de830c08", + "sha256:58b84b91b0b9f4bafac2a0ac55002280c094dfc6402402332c0913a59654ab2b", + "sha256:640cef9aa381b60e296db324337a554aeeb883ead99dc8f6c18e81a93942f5f4", + "sha256:66b479b0bd07204e37583c191535505410daa8df638fd8e75ae1b383851fe921", + "sha256:696039430f7a562b74fa45f540aca068ea85fa34c244d0deee539cb6d70aa288", + "sha256:6d2123dc9ad6a814bcdea0f099885276b31b24f7edf40f6cdbc0912672e22eee", + "sha256:8635c16bf3d99040fdf3ca3db669a7250ddf49c55dc4aa8fe0ae0fa8d6dcc1f0", + "sha256:873d13d177501a28b2756375d59816c365e42ed8417b41665f346289adc68d24", + "sha256:8e5a0b00e1e56a842f922e7fae8ae4077aee4af0acb5ae3622bd4b4c30aedf99", + "sha256:8e90497254aacacbc4ea6ae5e7a8cd75629d6ad2b30025a4a8b09aa4faf55151", + "sha256:9057e6aa78a584bc93a13f0a9bf7e753a5e9770a30b4d758b8d5f2a62a9433cd", + "sha256:90c6fca2acf139569e74e8781709dccb6fe25940488755716d1d354d6bc58bce", + "sha256:92fd6b027924a7e178ac202cfbe25e53368db90d56872d20ffae94b96c7acc57", + "sha256:9dfde2a0ddef507a631dc9dc4af6a9489d5e2e740e226ad426a05cabfbd7c8ef", + "sha256:9e79019aba43cb4fda9e4d983f8e88ca0373adbb697ae9c6c43093218de28b54", + "sha256:a77e9d1c386196879aa5eb712e77461aaee433e54c68cf253053a73b7e49c33a", + "sha256:c7adfc142dac335d8c1e0dcbd37eb8617eac386596eb9e1a1b77791cf2498238", + "sha256:d187d355ecec3629624fccb01d104da7d7f391db0311145817525281e2804d23", + "sha256:ddf818e4e6c7c6f4f7c8a12709696d193976b591cc7dc50588d3d1a6b5dc8772", + "sha256:e9b79011ff7a0f4b1d6da6a61aa1aa604fb312d6647de5bad20013682d1429ce", + "sha256:eee3a87076c0756de40b05c5e9a6069c035ba43e8dd71c379e68cab2c20f16ad" + ], + "markers": "python_version >= '3.9'", + "version": "==2.2.2" }, "pgeocode": { "hashes": [ @@ -545,45 +575,69 @@ }, "pytz": { "hashes": [ - "sha256:2a29735ea9c18baf14b448846bde5a48030ed267578472d8955cd0e7443a9812", - "sha256:328171f4e3623139da4983451950b28e95ac706e13f3f2630a879749e7a8b319" + "sha256:2aa355083c50a0f93fa581709deac0c9ad65cca8a9e9beac660adcbd493c798a", + "sha256:31c7c1817eb7fae7ca4b8c7ee50c72f93aa2dd863de768e1ef4245d426aa0725" ], - "version": "==2024.1" + "version": "==2024.2" }, "pyyaml": { "hashes": [ - "sha256:08682f6b72c722394747bddaf0aa62277e02557c0fd1c42cb853016a38f8dedf", - "sha256:0f5f5786c0e09baddcd8b4b45f20a7b5d61a7e7e99846e3c799b05c7c53fa696", - "sha256:129def1b7c1bf22faffd67b8f3724645203b79d8f4cc81f674654d9902cb4393", - "sha256:294db365efa064d00b8d1ef65d8ea2c3426ac366c0c4368d930bf1c5fb497f77", - "sha256:3b2b1824fe7112845700f815ff6a489360226a5609b96ec2190a45e62a9fc922", - "sha256:3bd0e463264cf257d1ffd2e40223b197271046d09dadf73a0fe82b9c1fc385a5", - "sha256:4465124ef1b18d9ace298060f4eccc64b0850899ac4ac53294547536533800c8", - "sha256:49d4cdd9065b9b6e206d0595fee27a96b5dd22618e7520c33204a4a3239d5b10", - "sha256:4e0583d24c881e14342eaf4ec5fbc97f934b999a6828693a99157fde912540cc", - "sha256:5accb17103e43963b80e6f837831f38d314a0495500067cb25afab2e8d7a4018", - "sha256:607774cbba28732bfa802b54baa7484215f530991055bb562efbed5b2f20a45e", - "sha256:6c78645d400265a062508ae399b60b8c167bf003db364ecb26dcab2bda048253", - "sha256:72a01f726a9c7851ca9bfad6fd09ca4e090a023c00945ea05ba1638c09dc3347", - "sha256:74c1485f7707cf707a7aef42ef6322b8f97921bd89be2ab6317fd782c2d53183", - "sha256:895f61ef02e8fed38159bb70f7e100e00f471eae2bc838cd0f4ebb21e28f8541", - "sha256:8c1be557ee92a20f184922c7b6424e8ab6691788e6d86137c5d93c1a6ec1b8fb", - "sha256:bb4191dfc9306777bc594117aee052446b3fa88737cd13b7188d0e7aa8162185", - "sha256:bfb51918d4ff3d77c1c856a9699f8492c612cde32fd3bcd344af9be34999bfdc", - "sha256:c20cfa2d49991c8b4147af39859b167664f2ad4561704ee74c1de03318e898db", - "sha256:cb333c16912324fd5f769fff6bc5de372e9e7a202247b48870bc251ed40239aa", - "sha256:d2d9808ea7b4af864f35ea216be506ecec180628aced0704e34aca0b040ffe46", - "sha256:d483ad4e639292c90170eb6f7783ad19490e7a8defb3e46f97dfe4bacae89122", - "sha256:dd5de0646207f053eb0d6c74ae45ba98c3395a571a2891858e87df7c9b9bd51b", - "sha256:e1d4970ea66be07ae37a3c2e48b5ec63f7ba6804bdddfdbd3cfd954d25a82e63", - "sha256:e4fac90784481d221a8e4b1162afa7c47ed953be40d31ab4629ae917510051df", - "sha256:fa5ae20527d8e831e8230cbffd9f8fe952815b2b7dae6ffec25318803a7528fc", - "sha256:fd7f6999a8070df521b6384004ef42833b9bd62cfee11a09bda1079b4b704247", - "sha256:fdc842473cd33f45ff6bce46aea678a54e3d21f1b61a7750ce3c498eedfe25d6", - "sha256:fe69978f3f768926cfa37b867e3843918e012cf83f680806599ddce33c2c68b0" - ], - "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3, 3.4, 3.5'", - "version": "==5.4.1" + "sha256:01179a4a8559ab5de078078f37e5c1a30d76bb88519906844fd7bdea1b7729ff", + "sha256:0833f8694549e586547b576dcfaba4a6b55b9e96098b36cdc7ebefe667dfed48", + "sha256:0a9a2848a5b7feac301353437eb7d5957887edbf81d56e903999a75a3d743086", + "sha256:0b69e4ce7a131fe56b7e4d770c67429700908fc0752af059838b1cfb41960e4e", + "sha256:0ffe8360bab4910ef1b9e87fb812d8bc0a308b0d0eef8c8f44e0254ab3b07133", + "sha256:11d8f3dd2b9c1207dcaf2ee0bbbfd5991f571186ec9cc78427ba5bd32afae4b5", + "sha256:17e311b6c678207928d649faa7cb0d7b4c26a0ba73d41e99c4fff6b6c3276484", + "sha256:1e2120ef853f59c7419231f3bf4e7021f1b936f6ebd222406c3b60212205d2ee", + "sha256:1f71ea527786de97d1a0cc0eacd1defc0985dcf6b3f17bb77dcfc8c34bec4dc5", + "sha256:23502f431948090f597378482b4812b0caae32c22213aecf3b55325e049a6c68", + "sha256:24471b829b3bf607e04e88d79542a9d48bb037c2267d7927a874e6c205ca7e9a", + "sha256:29717114e51c84ddfba879543fb232a6ed60086602313ca38cce623c1d62cfbf", + "sha256:2e99c6826ffa974fe6e27cdb5ed0021786b03fc98e5ee3c5bfe1fd5015f42b99", + "sha256:39693e1f8320ae4f43943590b49779ffb98acb81f788220ea932a6b6c51004d8", + "sha256:3ad2a3decf9aaba3d29c8f537ac4b243e36bef957511b4766cb0057d32b0be85", + "sha256:3b1fdb9dc17f5a7677423d508ab4f243a726dea51fa5e70992e59a7411c89d19", + "sha256:41e4e3953a79407c794916fa277a82531dd93aad34e29c2a514c2c0c5fe971cc", + "sha256:43fa96a3ca0d6b1812e01ced1044a003533c47f6ee8aca31724f78e93ccc089a", + "sha256:50187695423ffe49e2deacb8cd10510bc361faac997de9efef88badc3bb9e2d1", + "sha256:5ac9328ec4831237bec75defaf839f7d4564be1e6b25ac710bd1a96321cc8317", + "sha256:5d225db5a45f21e78dd9358e58a98702a0302f2659a3c6cd320564b75b86f47c", + "sha256:6395c297d42274772abc367baaa79683958044e5d3835486c16da75d2a694631", + "sha256:688ba32a1cffef67fd2e9398a2efebaea461578b0923624778664cc1c914db5d", + "sha256:68ccc6023a3400877818152ad9a1033e3db8625d899c72eacb5a668902e4d652", + "sha256:70b189594dbe54f75ab3a1acec5f1e3faa7e8cf2f1e08d9b561cb41b845f69d5", + "sha256:797b4f722ffa07cc8d62053e4cff1486fa6dc094105d13fea7b1de7d8bf71c9e", + "sha256:7c36280e6fb8385e520936c3cb3b8042851904eba0e58d277dca80a5cfed590b", + "sha256:7e7401d0de89a9a855c839bc697c079a4af81cf878373abd7dc625847d25cbd8", + "sha256:80bab7bfc629882493af4aa31a4cfa43a4c57c83813253626916b8c7ada83476", + "sha256:82d09873e40955485746739bcb8b4586983670466c23382c19cffecbf1fd8706", + "sha256:8388ee1976c416731879ac16da0aff3f63b286ffdd57cdeb95f3f2e085687563", + "sha256:8824b5a04a04a047e72eea5cec3bc266db09e35de6bdfe34c9436ac5ee27d237", + "sha256:8b9c7197f7cb2738065c481a0461e50ad02f18c78cd75775628afb4d7137fb3b", + "sha256:9056c1ecd25795207ad294bcf39f2db3d845767be0ea6e6a34d856f006006083", + "sha256:936d68689298c36b53b29f23c6dbb74de12b4ac12ca6cfe0e047bedceea56180", + "sha256:9b22676e8097e9e22e36d6b7bda33190d0d400f345f23d4065d48f4ca7ae0425", + "sha256:a4d3091415f010369ae4ed1fc6b79def9416358877534caf6a0fdd2146c87a3e", + "sha256:a8786accb172bd8afb8be14490a16625cbc387036876ab6ba70912730faf8e1f", + "sha256:a9f8c2e67970f13b16084e04f134610fd1d374bf477b17ec1599185cf611d725", + "sha256:bc2fa7c6b47d6bc618dd7fb02ef6fdedb1090ec036abab80d4681424b84c1183", + "sha256:c70c95198c015b85feafc136515252a261a84561b7b1d51e3384e0655ddf25ab", + "sha256:cc1c1159b3d456576af7a3e4d1ba7e6924cb39de8f67111c735f6fc832082774", + "sha256:ce826d6ef20b1bc864f0a68340c8b3287705cae2f8b4b1d932177dcc76721725", + "sha256:d584d9ec91ad65861cc08d42e834324ef890a082e591037abe114850ff7bbc3e", + "sha256:d7fded462629cfa4b685c5416b949ebad6cec74af5e2d42905d41e257e0869f5", + "sha256:d84a1718ee396f54f3a086ea0a66d8e552b2ab2017ef8b420e92edbc841c352d", + "sha256:d8e03406cac8513435335dbab54c0d385e4a49e4945d2909a581c83647ca0290", + "sha256:e10ce637b18caea04431ce14fabcf5c64a1c61ec9c56b071a4b7ca131ca52d44", + "sha256:ec031d5d2feb36d1d1a24380e4db6d43695f3748343d99434e6f5f9156aaa2ed", + "sha256:ef6107725bd54b262d6dedcc2af448a266975032bc85ef0172c5f059da6325b4", + "sha256:efdca5630322a10774e8e98e1af481aad470dd62c3170801852d752aa7a783ba", + "sha256:f753120cb8181e736c57ef7636e83f31b9c0d1722c516f7e86cf15b7aa57ff12", + "sha256:ff3824dc5261f50c9b0dfb3be22b4567a6f938ccce4587b38952d85fd9e9afe4" + ], + "markers": "python_version >= '3.8'", + "version": "==6.0.2" }, "qrcode": { "hashes": [ @@ -595,11 +649,11 @@ }, "rapid-router": { "hashes": [ - "sha256:1cb2ec011c45c281803700dcb8363155d219cbc59a79e87de6ef7c577fd17006", - "sha256:38aa7a0a0d0ce9097c8710f48796a3c6afc5d5a36d599e894a4bef108fa59f8c" + "sha256:5aebf3eee4ca7775579ac0da81a1fc2163e6b3c0cc24a1eeba69eaa2eb0ead92", + "sha256:dd6e5067ec21bba5333c5d7f5c55472e5e9acabbf7a582c1c91dd0c7b2174bec" ], "index": "pypi", - "version": "==6.0.1" + "version": "==6.5.2" }, "reportlab": { "hashes": [ @@ -663,11 +717,11 @@ }, "setuptools": { "hashes": [ - "sha256:f171bab1dfbc86b132997f26a119f6056a57950d058587841a0082e8830f9dc5", - "sha256:fe384da74336c398e0d956d1cae0669bc02eed936cdb1d49b57de1990dc11ffc" + "sha256:0274581a0037b638b9fc1c6883cc71c0210865aaa76073f7882376b641b84e8f", + "sha256:a85e96b8be2b906f3e3e789adec6a9323abf79758ecfa3065bd740d81158b11e" ], "markers": "python_version >= '3.8'", - "version": "==70.3.0" + "version": "==74.0.0" }, "six": { "hashes": [ @@ -718,19 +772,19 @@ }, "urllib3": { "hashes": [ - "sha256:a448b2f64d686155468037e1ace9f2d2199776e17f0a46610480d311f73e3472", - "sha256:dd505485549a7a552833da5e6063639d0d177c04f23bc3864e41e5dc5f612168" + "sha256:ca899ca043dcb1bafa3e262d73aa25c465bfb49e0bd9dd5d59f1d0acba2f8fac", + "sha256:e7d814a81dad81e6caf2ec9fdedb284ecc9c73076b62654547cc64ccdcae26e9" ], "markers": "python_version >= '3.8'", - "version": "==2.2.2" + "version": "==2.2.3" }, "zipp": { "hashes": [ - "sha256:bf1dcf6450f873a13e952a29504887c89e6de7506209e5b1bcc3460135d4de19", - "sha256:f091755f667055f2d02b32c53771a7a6c8b47e1fdbc4b72a8b9072b3eef8015c" + "sha256:a817ac80d6cf4b23bf7f2828b7cabf326f15a001bea8b1f9b49631780ba28350", + "sha256:bc9eb26f4506fda01b81bcde0ca78103b6e62f991b381fec825435c836edbc29" ], "markers": "python_version >= '3.8'", - "version": "==3.19.2" + "version": "==3.20.2" } }, "develop": { @@ -744,59 +798,48 @@ }, "astroid": { "hashes": [ - "sha256:4148645659b08b70d72460ed1921158027a9e53ae8b7234149b1400eddacbb93", - "sha256:92fcf218b89f449cdf9f7b39a269f8d5d617b27be68434912e11e79203963a17" + "sha256:0e14202810b30da1b735827f78f5157be2bbd4a7a59b7707ca0bfc2fb4c0063a", + "sha256:413658a61eeca6202a59231abb473f932038fbcbf1666587f66d482083413a25" ], "markers": "python_full_version >= '3.8.0'", - "version": "==3.0.3" - }, - "attrs": { - "hashes": [ - "sha256:5cfb1b9148b5b086569baec03f20d7b6bf3bcacc9a42bebf87ffaaca362f6346", - "sha256:81921eb96de3191c8258c199618104dd27ac608d9366f5e35d011eae1867ede2" - ], - "markers": "python_version >= '3.7'", - "version": "==24.2.0" + "version": "==3.2.4" }, "black": { "hashes": [ - "sha256:0052dba51dec07ed029ed61b18183942043e00008ec65d5028814afaab9a22fd", - "sha256:0680d4380db3719ebcfb2613f34e86c8e6d15ffeabcf8ec59355c5e7b85bb555", - "sha256:121ca7f10b4a01fd99951234abdbd97728e1240be89fde18480ffac16503d481", - "sha256:162e37d49e93bd6eb6f1afc3e17a3d23a823042530c37c3c42eeeaf026f38468", - "sha256:2a951cc83ab535d248c89f300eccbd625e80ab880fbcfb5ac8afb5f01a258ac9", - "sha256:2bf649fda611c8550ca9d7592b69f0637218c2369b7744694c5e4902873b2f3a", - "sha256:382998821f58e5c8238d3166c492139573325287820963d2f7de4d518bd76958", - "sha256:49f7b39e30f326a34b5c9a4213213a6b221d7ae9d58ec70df1c4a307cf2a1580", - "sha256:57c18c5165c1dbe291d5306e53fb3988122890e57bd9b3dcb75f967f13411a26", - "sha256:7a0f701d314cfa0896b9001df70a530eb2472babb76086344e688829efd97d32", - "sha256:8178318cb74f98bc571eef19068f6ab5613b3e59d4f47771582f04e175570ed8", - "sha256:8b70eb40a78dfac24842458476135f9b99ab952dd3f2dab738c1881a9b38b753", - "sha256:9880d7d419bb7e709b37e28deb5e68a49227713b623c72b2b931028ea65f619b", - "sha256:9afd3f493666a0cd8f8df9a0200c6359ac53940cbde049dcb1a7eb6ee2dd7074", - "sha256:a29650759a6a0944e7cca036674655c2f0f63806ddecc45ed40b7b8aa314b651", - "sha256:a436e7881d33acaf2536c46a454bb964a50eff59b21b51c6ccf5a40601fbef24", - "sha256:a59db0a2094d2259c554676403fa2fac3473ccf1354c1c63eccf7ae65aac8ab6", - "sha256:a8471939da5e824b891b25751955be52ee7f8a30a916d570a5ba8e0f2eb2ecad", - "sha256:b0bd97bea8903f5a2ba7219257a44e3f1f9d00073d6cc1add68f0beec69692ac", - "sha256:b6a92a41ee34b883b359998f0c8e6eb8e99803aa8bf3123bf2b2e6fec505a221", - "sha256:bb460c8561c8c1bec7824ecbc3ce085eb50005883a6203dcfb0122e95797ee06", - "sha256:bfffba28dc52a58f04492181392ee380e95262af14ee01d4bc7bb1b1c6ca8d27", - "sha256:c1c476bc7b7d021321e7d93dc2cbd78ce103b84d5a4cf97ed535fbc0d6660648", - "sha256:c91dfc2c2a4e50df0026f88d2215e166616e0c80e86004d0003ece0488db2739", - "sha256:e6663f91b6feca5d06f2ccd49a10f254f9298cc1f7f49c46e498a0771b507104" + "sha256:09cdeb74d494ec023ded657f7092ba518e8cf78fa8386155e4a03fdcc44679e6", + "sha256:1f13f7f386f86f8121d76599114bb8c17b69d962137fc70efe56137727c7047e", + "sha256:2500945420b6784c38b9ee885af039f5e7471ef284ab03fa35ecdde4688cd83f", + "sha256:2b59b250fdba5f9a9cd9d0ece6e6d993d91ce877d121d161e4698af3eb9c1018", + "sha256:3c4285573d4897a7610054af5a890bde7c65cb466040c5f0c8b732812d7f0e5e", + "sha256:505289f17ceda596658ae81b61ebbe2d9b25aa78067035184ed0a9d855d18afd", + "sha256:62e8730977f0b77998029da7971fa896ceefa2c4c4933fcd593fa599ecbf97a4", + "sha256:649f6d84ccbae73ab767e206772cc2d7a393a001070a4c814a546afd0d423aed", + "sha256:6e55d30d44bed36593c3163b9bc63bf58b3b30e4611e4d88a0c3c239930ed5b2", + "sha256:707a1ca89221bc8a1a64fb5e15ef39cd755633daa672a9db7498d1c19de66a42", + "sha256:72901b4913cbac8972ad911dc4098d5753704d1f3c56e44ae8dce99eecb0e3af", + "sha256:73bbf84ed136e45d451a260c6b73ed674652f90a2b3211d6a35e78054563a9bb", + "sha256:7c046c1d1eeb7aea9335da62472481d3bbf3fd986e093cffd35f4385c94ae368", + "sha256:81c6742da39f33b08e791da38410f32e27d632260e599df7245cccee2064afeb", + "sha256:837fd281f1908d0076844bc2b801ad2d369c78c45cf800cad7b61686051041af", + "sha256:972085c618ee94f402da1af548a4f218c754ea7e5dc70acb168bfaca4c2542ed", + "sha256:9e84e33b37be070ba135176c123ae52a51f82306def9f7d063ee302ecab2cf47", + "sha256:b19c9ad992c7883ad84c9b22aaa73562a16b819c1d8db7a1a1a49fb7ec13c7d2", + "sha256:d6417535d99c37cee4091a2f24eb2b6d5ec42b144d50f1f2e436d9fe1916fe1a", + "sha256:eab4dd44ce80dea27dc69db40dab62d4ca96112f87996bca68cd75639aeb2e4c", + "sha256:f490dbd59680d809ca31efdae20e634f3fae27fba3ce0ba3208333b713bc3920", + "sha256:fb6e2c0b86bbd43dee042e48059c9ad7830abd5c94b0bc518c0eeec57c3eddc1" ], "index": "pypi", - "markers": "python_version >= '3.7'", - "version": "==23.1.0" + "markers": "python_version >= '3.8'", + "version": "==24.8.0" }, "certifi": { "hashes": [ - "sha256:5a1e7645bc0ec61a09e26c36f6106dd4cf40c6db3a1fb6352b0244e7fb057c7b", - "sha256:c198e21b1289c2ab85ee4e67bb4b4ef3ead0892059901a8d5b622f24a1101e90" + "sha256:922820b53db7a7257ffbda3f597266d435245903d80737e34f8a45ff3e3230d8", + "sha256:bec941d2aa8195e248a60b31ff9f0558284cf01a52591ceda73ea9afffd69fd9" ], "markers": "python_version >= '3.6'", - "version": "==2024.7.4" + "version": "==2024.8.30" }, "charset-normalizer": { "hashes": [ @@ -988,7 +1031,7 @@ "sha256:3ebe3c479ad625c4553aca177444d89b486b1d84982eeacded644afc0cf797ca", "sha256:c36ca9ffb54365bdd2f8eb3eff7d2a21237f8452b57ace88b1ac615b7e815bd7" ], - "markers": "python_version < '3.11'", + "markers": "python_version >= '3.11'", "version": "==0.3.8" }, "django": { @@ -1048,14 +1091,6 @@ "markers": "python_version >= '3.8'", "version": "==3.14.4" }, - "exceptiongroup": { - "hashes": [ - "sha256:3111b9d131c238bec2f8f516e123e14ba243563fb135d3fe885990585aa7795b", - "sha256:47c2edf7c6738fafb49fd34290706d1a1a2f4d1c6df275526b62cbb4aa5393cc" - ], - "markers": "python_version < '3.11'", - "version": "==1.2.2" - }, "execnet": { "hashes": [ "sha256:26dee51f1b80cebd6d0ca8e74dd8745419761d3bef34163928cbebbdc4749fdc", @@ -1066,11 +1101,11 @@ }, "idna": { "hashes": [ - "sha256:028ff3aadf0609c1fd278d8ea3089299412a7a8b9bd005dd08b9f8285bcb5cfc", - "sha256:82fee1fc78add43492d3a1898bfa6d8a904cc97d8427f683ed8e798d07761aa0" + "sha256:12f65c9b470abda6dc35cf8e63cc574b1c52b11df2c86030af0ac09b01b13ea9", + "sha256:946d195a0d259cbba61165e88e65941f16e9b36ea6ddb97f00452bae8b1287d3" ], - "markers": "python_version >= '3.5'", - "version": "==3.7" + "markers": "python_version >= '3.6'", + "version": "==3.10" }, "iniconfig": { "hashes": [ @@ -1157,11 +1192,11 @@ }, "platformdirs": { "hashes": [ - "sha256:2d7a1657e36a80ea911db832a8a6ece5ee53d8de21edd5cc5879af6530b1bfee", - "sha256:38b7b51f512eed9e84a22788b4bce1de17c0adb134d6becb09836e37d8654cd3" + "sha256:357fb2acbc885b0419afd3ce3ed34564c13c9b95c89360cd9563f73aa5e2b907", + "sha256:73e575e1408ab8103900836b97580d5307456908a03e92031bab39e4554cc3fb" ], "markers": "python_version >= '3.8'", - "version": "==4.2.2" + "version": "==4.3.6" }, "pluggy": { "hashes": [ @@ -1204,12 +1239,12 @@ }, "pylint": { "hashes": [ - "sha256:0d4c286ef6d2f66c8bfb527a7f8a629009e42c99707dec821a03e1b51a4c1496", - "sha256:60ed5f3a9ff8b61839ff0348b3624ceeb9e6c2a92c514d81c9cc273da3b6bcda" + "sha256:02f4aedeac91be69fb3b4bea997ce580a4ac68ce58b89eaefeaf06749df73f4b", + "sha256:1b7a721b575eaeaa7d39db076b6e7743c993ea44f57979127c517c6c572c803e" ], "index": "pypi", "markers": "python_full_version >= '3.8.0'", - "version": "==3.0.2" + "version": "==3.2.7" }, "pylint-django": { "hashes": [ @@ -1239,12 +1274,12 @@ }, "pytest": { "hashes": [ - "sha256:c7c6ca206e93355074ae32f7403e8ea12163b1163c976fee7d4d84027c162be5", - "sha256:d45e0952f3727241918b8fd0f376f5ff6b301cc0777c6f9a556935c92d8a7d42" + "sha256:70b98107bd648308a7952b06e6ca9a50bc660be218d53c257cc1fc94fda10181", + "sha256:a6853c7375b2663155079443d2e45de913a911a11d669df02a50814944db57b2" ], "index": "pypi", - "markers": "python_version >= '3.7'", - "version": "==7.2.1" + "markers": "python_version >= '3.8'", + "version": "==8.3.3" }, "pytest-cov": { "hashes": [ @@ -1286,10 +1321,10 @@ }, "pytz": { "hashes": [ - "sha256:2a29735ea9c18baf14b448846bde5a48030ed267578472d8955cd0e7443a9812", - "sha256:328171f4e3623139da4983451950b28e95ac706e13f3f2630a879749e7a8b319" + "sha256:2aa355083c50a0f93fa581709deac0c9ad65cca8a9e9beac660adcbd493c798a", + "sha256:31c7c1817eb7fae7ca4b8c7ee50c72f93aa2dd863de768e1ef4245d426aa0725" ], - "version": "==2024.1" + "version": "==2024.2" }, "requests": { "hashes": [ @@ -1308,45 +1343,37 @@ "markers": "python_version >= '3.8'", "version": "==0.5.1" }, - "tomli": { - "hashes": [ - "sha256:939de3e7a6161af0c887ef91b7d41a53e7c5a1ca976325f429cb46ea9bc30ecc", - "sha256:de526c12914f0c550d15924c62d72abc48d6fe7364aa87328337a31007fe8a4f" - ], - "markers": "python_version < '3.11'", - "version": "==2.0.1" - }, "tomlkit": { "hashes": [ - "sha256:08ad192699734149f5b97b45f1f18dad7eb1b6d16bc72ad0c2335772650d7b72", - "sha256:7075d3042d03b80f603482d69bf0c8f345c2b30e41699fd8883227f89972b264" + "sha256:7a974427f6e119197f670fbbbeae7bef749a6c14e793db934baefc1b5f03efde", + "sha256:fff5fe59a87295b278abd31bec92c15d9bc4a06885ab12bcea52c71119392e79" ], "markers": "python_version >= '3.8'", - "version": "==0.13.0" + "version": "==0.13.2" }, "types-pytz": { "hashes": [ - "sha256:6810c8a1f68f21fdf0f4f374a432487c77645a0ac0b31de4bf4690cf21ad3981", - "sha256:8335d443310e2db7b74e007414e74c4f53b67452c0cb0d228ca359ccfba59659" + "sha256:4433b5df4a6fc587bbed41716d86a5ba5d832b4378e506f40d34bc9c81df2c24", + "sha256:a1eebf57ebc6e127a99d2fa2ba0a88d2b173784ef9b3defcc2004ab6855a44df" ], "markers": "python_version >= '3.8'", - "version": "==2024.1.0.20240417" + "version": "==2024.2.0.20240913" }, "types-pyyaml": { "hashes": [ - "sha256:b8f76ddbd7f65440a8bda5526a9607e4c7a322dc2f8e1a8c405644f9a6f4b9af", - "sha256:deda34c5c655265fc517b546c902aa6eed2ef8d3e921e4765fe606fe2afe8d35" + "sha256:392b267f1c0fe6022952462bf5d6523f31e37f6cea49b14cee7ad634b6301570", + "sha256:d1405a86f9576682234ef83bcb4e6fff7c9305c8b1fbad5e0bcd4f7dbdc9c587" ], "markers": "python_version >= '3.8'", - "version": "==6.0.12.20240808" + "version": "==6.0.12.20240917" }, "types-requests": { "hashes": [ - "sha256:90c079ff05e549f6bf50e02e910210b98b8ff1ebdd18e19c873cd237737c1358", - "sha256:f754283e152c752e46e70942fa2a146b5bc70393522257bb85bd1ef7e019dcc3" + "sha256:2850e178db3919d9bf809e434eef65ba49d0e7e33ac92d588f4a5e295fffd405", + "sha256:59c2f673eb55f32a99b2894faf6020e1a9f4a402ad0f192bfee0b64469054310" ], "markers": "python_version >= '3.8'", - "version": "==2.32.0.20240712" + "version": "==2.32.0.20240914" }, "typing-extensions": { "hashes": [ @@ -1358,11 +1385,11 @@ }, "urllib3": { "hashes": [ - "sha256:a448b2f64d686155468037e1ace9f2d2199776e17f0a46610480d311f73e3472", - "sha256:dd505485549a7a552833da5e6063639d0d177c04f23bc3864e41e5dc5f612168" + "sha256:ca899ca043dcb1bafa3e262d73aa25c465bfb49e0bd9dd5d59f1d0acba2f8fac", + "sha256:e7d814a81dad81e6caf2ec9fdedb284ecc9c73076b62654547cc64ccdcae26e9" ], "markers": "python_version >= '3.8'", - "version": "==2.2.2" + "version": "==2.2.3" } } } diff --git a/setup.py b/setup.py index dd65c239..6fd96eff 100644 --- a/setup.py +++ b/setup.py @@ -2,7 +2,7 @@ © Ocado Group Created on 11/12/2023 at 10:59:40(+00:00). -Setup the Code for Life package during installation. +Setup the Code for Life package during installation. """ import json @@ -93,7 +93,7 @@ def parse_requirements(packages: t.Dict[str, t.Dict[str, t.Any]]): include_package_data=True, data_files=[get_data_files(DATA_DIR), get_data_files(USER_FIXTURES_DIR)], package_data={"codeforlife": ["py.typed"]}, - python_requires="==3.8.*", + python_requires="==3.12.*", install_requires=install_requires, extras_require={"dev": dev_requires}, dependency_links=[], From 708b3b5e1e3a1de6eb63f7596d4592e20a88df78 Mon Sep 17 00:00:00 2001 From: faucomte97 Date: Wed, 18 Sep 2024 11:21:10 +0100 Subject: [PATCH 02/11] Black --- codeforlife/models/signals/__init__.py | 1 - codeforlife/settings/__init__.py | 1 + codeforlife/settings/custom.py | 1 + codeforlife/settings/django.py | 1 + codeforlife/settings/third_party.py | 1 + codeforlife/tests/model_serializer.py | 6 +++--- codeforlife/tests/model_view_set.py | 6 +++--- .../user/auth/password_validators/independent_test.py | 1 + codeforlife/user/auth/password_validators/student_test.py | 1 + codeforlife/user/auth/password_validators/teacher_test.py | 1 + codeforlife/user/models/__init__.py | 1 + codeforlife/user/views/school_test.py | 1 - 12 files changed, 14 insertions(+), 8 deletions(-) diff --git a/codeforlife/models/signals/__init__.py b/codeforlife/models/signals/__init__.py index a2b951a7..8d6873a8 100644 --- a/codeforlife/models/signals/__init__.py +++ b/codeforlife/models/signals/__init__.py @@ -6,6 +6,5 @@ https://docs.djangoproject.com/en/3.2/ref/signals/#module-django.db.models.signals """ - from .general import UpdateFields, update_fields_includes from .receiver import model_receiver diff --git a/codeforlife/settings/__init__.py b/codeforlife/settings/__init__.py index e3d889d0..eba87e37 100644 --- a/codeforlife/settings/__init__.py +++ b/codeforlife/settings/__init__.py @@ -13,6 +13,7 @@ cfl_settings.EXAMPLE_SETTING ` """ + from .custom import * from .django import * from .third_party import * diff --git a/codeforlife/settings/custom.py b/codeforlife/settings/custom.py index faf9b34d..f90ac722 100644 --- a/codeforlife/settings/custom.py +++ b/codeforlife/settings/custom.py @@ -1,6 +1,7 @@ """ This file contains all of our custom settings we define for our own purposes. """ + import os # The name of the current service. diff --git a/codeforlife/settings/django.py b/codeforlife/settings/django.py index 41da658b..b92221f9 100644 --- a/codeforlife/settings/django.py +++ b/codeforlife/settings/django.py @@ -2,6 +2,7 @@ This file contains all the settings Django supports out of the box. https://docs.djangoproject.com/en/3.2/ref/settings/ """ + import os from pathlib import Path diff --git a/codeforlife/settings/third_party.py b/codeforlife/settings/third_party.py index e547197a..700f6eeb 100644 --- a/codeforlife/settings/third_party.py +++ b/codeforlife/settings/third_party.py @@ -1,6 +1,7 @@ """ This file contains custom settings defined by third party extensions. """ + from .django import DEBUG # CORS diff --git a/codeforlife/tests/model_serializer.py b/codeforlife/tests/model_serializer.py index f8ce0b56..a42fcaff 100644 --- a/codeforlife/tests/model_serializer.py +++ b/codeforlife/tests/model_serializer.py @@ -146,9 +146,9 @@ def _assert_many( assert len(new_data) == len(validated_data) kwargs.pop("many", None) # many must be True - serializer: ModelListSerializer[ - RequestUser, AnyModel - ] = self._init_model_serializer(*args, **kwargs, many=True) + serializer: ModelListSerializer[RequestUser, AnyModel] = ( + self._init_model_serializer(*args, **kwargs, many=True) + ) models = get_models(serializer, deepcopy(validated_data)) assert len(models) == len(validated_data) diff --git a/codeforlife/tests/model_view_set.py b/codeforlife/tests/model_view_set.py index eed7aa22..0344fe0c 100644 --- a/codeforlife/tests/model_view_set.py +++ b/codeforlife/tests/model_view_set.py @@ -614,9 +614,9 @@ class ModelViewSetTestCase( basename: str model_view_set_class: t.Type[ModelViewSet[RequestUser, AnyModel]] client: ModelViewSetClient[RequestUser, AnyModel] - client_class: t.Type[ - ModelViewSetClient[RequestUser, AnyModel] - ] = ModelViewSetClient + client_class: t.Type[ModelViewSetClient[RequestUser, AnyModel]] = ( + ModelViewSetClient + ) @classmethod def get_model_class(cls) -> t.Type[AnyModel]: diff --git a/codeforlife/user/auth/password_validators/independent_test.py b/codeforlife/user/auth/password_validators/independent_test.py index d849308e..b705c833 100644 --- a/codeforlife/user/auth/password_validators/independent_test.py +++ b/codeforlife/user/auth/password_validators/independent_test.py @@ -2,6 +2,7 @@ © Ocado Group Created on 30/01/2024 at 12:36:00(+00:00). """ + from ....tests import TestCase from ...models import User from .independent import IndependentPasswordValidator diff --git a/codeforlife/user/auth/password_validators/student_test.py b/codeforlife/user/auth/password_validators/student_test.py index e627522d..9f275235 100644 --- a/codeforlife/user/auth/password_validators/student_test.py +++ b/codeforlife/user/auth/password_validators/student_test.py @@ -2,6 +2,7 @@ © Ocado Group Created on 30/01/2024 at 12:36:00(+00:00). """ + from ....tests import TestCase from ...models import User from .student import StudentPasswordValidator diff --git a/codeforlife/user/auth/password_validators/teacher_test.py b/codeforlife/user/auth/password_validators/teacher_test.py index dec01a8b..85d0f382 100644 --- a/codeforlife/user/auth/password_validators/teacher_test.py +++ b/codeforlife/user/auth/password_validators/teacher_test.py @@ -2,6 +2,7 @@ © Ocado Group Created on 30/01/2024 at 12:36:00(+00:00). """ + from ....tests import TestCase from ...models import User from .teacher import TeacherPasswordValidator diff --git a/codeforlife/user/models/__init__.py b/codeforlife/user/models/__init__.py index db4f2187..1fd36638 100644 --- a/codeforlife/user/models/__init__.py +++ b/codeforlife/user/models/__init__.py @@ -2,6 +2,7 @@ © Ocado Group Created on 05/02/2024 at 13:48:55(+00:00). """ + from .auth_factor import AuthFactor from .klass import Class from .otp_bypass_token import OtpBypassToken diff --git a/codeforlife/user/views/school_test.py b/codeforlife/user/views/school_test.py index 0cf090ec..9c59e6c1 100644 --- a/codeforlife/user/views/school_test.py +++ b/codeforlife/user/views/school_test.py @@ -3,7 +3,6 @@ Created on 20/01/2024 at 09:47:30(+00:00). """ - from ...permissions import OR, AllowNone from ...tests import ModelViewSetTestCase from ..models import School, SchoolTeacherUser, StudentUser, User From 1bde5717207afa420d059f0902579992dba3c3ee Mon Sep 17 00:00:00 2001 From: faucomte97 Date: Wed, 18 Sep 2024 12:11:41 +0100 Subject: [PATCH 03/11] Use assertEqual instead of assertDictContainsSubset --- codeforlife/tests/model_serializer.py | 8 ++++---- codeforlife/tests/model_view_set.py | 19 +++++++++---------- 2 files changed, 13 insertions(+), 14 deletions(-) diff --git a/codeforlife/tests/model_serializer.py b/codeforlife/tests/model_serializer.py index a42fcaff..8d19ef9f 100644 --- a/codeforlife/tests/model_serializer.py +++ b/codeforlife/tests/model_serializer.py @@ -125,7 +125,7 @@ def _assert_data_is_subset_of_model(self, data: DataDict, model): elif isinstance(value, Model): data[field] = getattr(value, "id") - self.assertDictContainsSubset(data, model_to_dict(model)) + self.assertEqual(model_to_dict(model), {**model_to_dict(model), **data}) def _assert_many( self, @@ -146,9 +146,9 @@ def _assert_many( assert len(new_data) == len(validated_data) kwargs.pop("many", None) # many must be True - serializer: ModelListSerializer[RequestUser, AnyModel] = ( - self._init_model_serializer(*args, **kwargs, many=True) - ) + serializer: ModelListSerializer[ + RequestUser, AnyModel + ] = self._init_model_serializer(*args, **kwargs, many=True) models = get_models(serializer, deepcopy(validated_data)) assert len(models) == len(validated_data) diff --git a/codeforlife/tests/model_view_set.py b/codeforlife/tests/model_view_set.py index 0344fe0c..f991d50a 100644 --- a/codeforlife/tests/model_view_set.py +++ b/codeforlife/tests/model_view_set.py @@ -614,9 +614,9 @@ class ModelViewSetTestCase( basename: str model_view_set_class: t.Type[ModelViewSet[RequestUser, AnyModel]] client: ModelViewSetClient[RequestUser, AnyModel] - client_class: t.Type[ModelViewSetClient[RequestUser, AnyModel]] = ( - ModelViewSetClient - ) + client_class: t.Type[ + ModelViewSetClient[RequestUser, AnyModel] + ] = ModelViewSetClient @classmethod def get_model_class(cls) -> t.Type[AnyModel]: @@ -743,11 +743,9 @@ def datetime_values_to_representation(data: DataDict): # Assert the JSON model provided in the response is an exact match or # subset of the serialized model. - ( - self.assertDictContainsSubset - if contains_subset - else self.assertDictEqual - )(json_model, serialized_model) + (self.assertEqual if contains_subset else self.assertDictEqual)( + json_model, serialized_model + ) def assert_get_serializer_class( self, @@ -820,6 +818,7 @@ def assert_get_serializer_context( *args, **kwargs, action=action ) actual_serializer_context = model_view_set.get_serializer_context() - self.assertDictContainsSubset( - serializer_context, actual_serializer_context + self.assertEqual( + actual_serializer_context, + actual_serializer_context | serializer_context, ) From 37fbaa1130848db93a31674b06530e10bdc88a22 Mon Sep 17 00:00:00 2001 From: faucomte97 Date: Wed, 18 Sep 2024 12:16:10 +0100 Subject: [PATCH 04/11] Black again --- codeforlife/tests/model_serializer.py | 10 +++++----- codeforlife/tests/model_view_set.py | 8 ++++---- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/codeforlife/tests/model_serializer.py b/codeforlife/tests/model_serializer.py index 8d19ef9f..99a0a8c7 100644 --- a/codeforlife/tests/model_serializer.py +++ b/codeforlife/tests/model_serializer.py @@ -13,11 +13,11 @@ from django.forms.models import model_to_dict from rest_framework.serializers import BaseSerializer, ValidationError +from .api_request_factory import APIRequestFactory +from .test import TestCase from ..serializers import ModelListSerializer, ModelSerializer from ..types import DataDict from ..user.models import AnyUser as RequestUser -from .api_request_factory import APIRequestFactory -from .test import TestCase AnyModel = t.TypeVar("AnyModel", bound=Model) @@ -146,9 +146,9 @@ def _assert_many( assert len(new_data) == len(validated_data) kwargs.pop("many", None) # many must be True - serializer: ModelListSerializer[ - RequestUser, AnyModel - ] = self._init_model_serializer(*args, **kwargs, many=True) + serializer: ModelListSerializer[RequestUser, AnyModel] = ( + self._init_model_serializer(*args, **kwargs, many=True) + ) models = get_models(serializer, deepcopy(validated_data)) assert len(models) == len(validated_data) diff --git a/codeforlife/tests/model_view_set.py b/codeforlife/tests/model_view_set.py index f991d50a..b4a6c320 100644 --- a/codeforlife/tests/model_view_set.py +++ b/codeforlife/tests/model_view_set.py @@ -16,12 +16,12 @@ from rest_framework import status from rest_framework.response import Response +from .api import APIClient, APITestCase from ..permissions import Permission from ..serializers import BaseSerializer from ..types import DataDict, JsonDict, KwArgs from ..user.models import AnyUser as RequestUser from ..views import ModelViewSet -from .api import APIClient, APITestCase AnyModel = t.TypeVar("AnyModel", bound=Model) @@ -614,9 +614,9 @@ class ModelViewSetTestCase( basename: str model_view_set_class: t.Type[ModelViewSet[RequestUser, AnyModel]] client: ModelViewSetClient[RequestUser, AnyModel] - client_class: t.Type[ - ModelViewSetClient[RequestUser, AnyModel] - ] = ModelViewSetClient + client_class: t.Type[ModelViewSetClient[RequestUser, AnyModel]] = ( + ModelViewSetClient + ) @classmethod def get_model_class(cls) -> t.Type[AnyModel]: From 8eb388db7fd0cf6e339bb312195dd1a718b32f38 Mon Sep 17 00:00:00 2001 From: faucomte97 Date: Wed, 18 Sep 2024 12:18:58 +0100 Subject: [PATCH 05/11] isort --- codeforlife/tests/model_serializer.py | 4 ++-- codeforlife/tests/model_view_set.py | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/codeforlife/tests/model_serializer.py b/codeforlife/tests/model_serializer.py index 99a0a8c7..74e8b007 100644 --- a/codeforlife/tests/model_serializer.py +++ b/codeforlife/tests/model_serializer.py @@ -13,11 +13,11 @@ from django.forms.models import model_to_dict from rest_framework.serializers import BaseSerializer, ValidationError -from .api_request_factory import APIRequestFactory -from .test import TestCase from ..serializers import ModelListSerializer, ModelSerializer from ..types import DataDict from ..user.models import AnyUser as RequestUser +from .api_request_factory import APIRequestFactory +from .test import TestCase AnyModel = t.TypeVar("AnyModel", bound=Model) diff --git a/codeforlife/tests/model_view_set.py b/codeforlife/tests/model_view_set.py index b4a6c320..e4f8e718 100644 --- a/codeforlife/tests/model_view_set.py +++ b/codeforlife/tests/model_view_set.py @@ -16,12 +16,12 @@ from rest_framework import status from rest_framework.response import Response -from .api import APIClient, APITestCase from ..permissions import Permission from ..serializers import BaseSerializer from ..types import DataDict, JsonDict, KwArgs from ..user.models import AnyUser as RequestUser from ..views import ModelViewSet +from .api import APIClient, APITestCase AnyModel = t.TypeVar("AnyModel", bound=Model) From 4975dcb094683a1b6e9e6ada898633433468ef66 Mon Sep 17 00:00:00 2001 From: faucomte97 Date: Wed, 18 Sep 2024 12:30:04 +0100 Subject: [PATCH 06/11] pylint --- codeforlife/tests/api.py | 2 ++ codeforlife/user/models/teacher.py | 1 + codeforlife/user/models/user.py | 1 + 3 files changed, 4 insertions(+) diff --git a/codeforlife/tests/api.py b/codeforlife/tests/api.py index a99cbae6..89c771be 100644 --- a/codeforlife/tests/api.py +++ b/codeforlife/tests/api.py @@ -268,6 +268,8 @@ def login_as(self, user: TypedUser, password: str = "password"): user: The user to log in as. password: The user's password. """ + auth_user = None + if isinstance(user, AdminSchoolTeacherUser): auth_user = self.login_admin_school_teacher(user.email, password) elif isinstance(user, NonAdminSchoolTeacherUser): diff --git a/codeforlife/user/models/teacher.py b/codeforlife/user/models/teacher.py index 0b816a8e..3ce2d699 100644 --- a/codeforlife/user/models/teacher.py +++ b/codeforlife/user/models/teacher.py @@ -174,6 +174,7 @@ def get_queryset(self): objects: models.Manager["NonSchoolTeacher"] = Manager() +# pylint: disable-next=invalid-name TypedTeacher = t.Union[ SchoolTeacher, AdminSchoolTeacher, diff --git a/codeforlife/user/models/user.py b/codeforlife/user/models/user.py index 050d8e53..881d4bb9 100644 --- a/codeforlife/user/models/user.py +++ b/codeforlife/user/models/user.py @@ -605,6 +605,7 @@ class Meta(TypedModelMeta): ) +# pylint: disable-next=invalid-name TypedUser = t.Union[ TeacherUser, SchoolTeacherUser, From 2e947de2767ef19b73f3c88563df414a8500cab7 Mon Sep 17 00:00:00 2001 From: faucomte97 Date: Wed, 18 Sep 2024 13:00:19 +0100 Subject: [PATCH 07/11] Feedback --- codeforlife/tests/model_serializer.py | 13 +++++++++---- codeforlife/tests/model_view_set.py | 15 ++++++++------- 2 files changed, 17 insertions(+), 11 deletions(-) diff --git a/codeforlife/tests/model_serializer.py b/codeforlife/tests/model_serializer.py index 74e8b007..cf87536e 100644 --- a/codeforlife/tests/model_serializer.py +++ b/codeforlife/tests/model_serializer.py @@ -125,7 +125,12 @@ def _assert_data_is_subset_of_model(self, data: DataDict, model): elif isinstance(value, Model): data[field] = getattr(value, "id") - self.assertEqual(model_to_dict(model), {**model_to_dict(model), **data}) + model_dict = { + field: value + for field, value in model.__dict__.items() + if not field.startswith("_") + } + self.assertDictEqual(model_dict | data, model_dict) def _assert_many( self, @@ -146,9 +151,9 @@ def _assert_many( assert len(new_data) == len(validated_data) kwargs.pop("many", None) # many must be True - serializer: ModelListSerializer[RequestUser, AnyModel] = ( - self._init_model_serializer(*args, **kwargs, many=True) - ) + serializer: ModelListSerializer[ + RequestUser, AnyModel + ] = self._init_model_serializer(*args, **kwargs, many=True) models = get_models(serializer, deepcopy(validated_data)) assert len(models) == len(validated_data) diff --git a/codeforlife/tests/model_view_set.py b/codeforlife/tests/model_view_set.py index e4f8e718..fe59186a 100644 --- a/codeforlife/tests/model_view_set.py +++ b/codeforlife/tests/model_view_set.py @@ -614,9 +614,9 @@ class ModelViewSetTestCase( basename: str model_view_set_class: t.Type[ModelViewSet[RequestUser, AnyModel]] client: ModelViewSetClient[RequestUser, AnyModel] - client_class: t.Type[ModelViewSetClient[RequestUser, AnyModel]] = ( - ModelViewSetClient - ) + client_class: t.Type[ + ModelViewSetClient[RequestUser, AnyModel] + ] = ModelViewSetClient @classmethod def get_model_class(cls) -> t.Type[AnyModel]: @@ -743,8 +743,9 @@ def datetime_values_to_representation(data: DataDict): # Assert the JSON model provided in the response is an exact match or # subset of the serialized model. - (self.assertEqual if contains_subset else self.assertDictEqual)( - json_model, serialized_model + self.assertDictEqual( + serialized_model | json_model if contains_subset else json_model, + serialized_model, ) def assert_get_serializer_class( @@ -818,7 +819,7 @@ def assert_get_serializer_context( *args, **kwargs, action=action ) actual_serializer_context = model_view_set.get_serializer_context() - self.assertEqual( - actual_serializer_context, + self.assertDictEqual( actual_serializer_context | serializer_context, + actual_serializer_context, ) From b9a9f706b177cf2b774b980475375ce7399bc754 Mon Sep 17 00:00:00 2001 From: faucomte97 Date: Wed, 18 Sep 2024 13:03:38 +0100 Subject: [PATCH 08/11] Black --- codeforlife/tests/model_serializer.py | 7 +++---- codeforlife/tests/model_view_set.py | 6 +++--- 2 files changed, 6 insertions(+), 7 deletions(-) diff --git a/codeforlife/tests/model_serializer.py b/codeforlife/tests/model_serializer.py index cf87536e..e077feae 100644 --- a/codeforlife/tests/model_serializer.py +++ b/codeforlife/tests/model_serializer.py @@ -10,7 +10,6 @@ from unittest.case import _AssertRaisesContext from django.db.models import Model -from django.forms.models import model_to_dict from rest_framework.serializers import BaseSerializer, ValidationError from ..serializers import ModelListSerializer, ModelSerializer @@ -151,9 +150,9 @@ def _assert_many( assert len(new_data) == len(validated_data) kwargs.pop("many", None) # many must be True - serializer: ModelListSerializer[ - RequestUser, AnyModel - ] = self._init_model_serializer(*args, **kwargs, many=True) + serializer: ModelListSerializer[RequestUser, AnyModel] = ( + self._init_model_serializer(*args, **kwargs, many=True) + ) models = get_models(serializer, deepcopy(validated_data)) assert len(models) == len(validated_data) diff --git a/codeforlife/tests/model_view_set.py b/codeforlife/tests/model_view_set.py index fe59186a..4ce34499 100644 --- a/codeforlife/tests/model_view_set.py +++ b/codeforlife/tests/model_view_set.py @@ -614,9 +614,9 @@ class ModelViewSetTestCase( basename: str model_view_set_class: t.Type[ModelViewSet[RequestUser, AnyModel]] client: ModelViewSetClient[RequestUser, AnyModel] - client_class: t.Type[ - ModelViewSetClient[RequestUser, AnyModel] - ] = ModelViewSetClient + client_class: t.Type[ModelViewSetClient[RequestUser, AnyModel]] = ( + ModelViewSetClient + ) @classmethod def get_model_class(cls) -> t.Type[AnyModel]: From fb24f0d5bc54c3f3c734c52ee22dbfa6388032e0 Mon Sep 17 00:00:00 2001 From: SKairinos Date: Wed, 18 Sep 2024 13:39:56 +0000 Subject: [PATCH 09/11] fix: tests --- codeforlife/tests/model_serializer.py | 21 +++++++++++++-------- codeforlife/user/serializers/user.py | 4 ++-- codeforlife/user/serializers/user_test.py | 4 ++++ 3 files changed, 19 insertions(+), 10 deletions(-) diff --git a/codeforlife/tests/model_serializer.py b/codeforlife/tests/model_serializer.py index e077feae..8c6cc7bf 100644 --- a/codeforlife/tests/model_serializer.py +++ b/codeforlife/tests/model_serializer.py @@ -10,6 +10,7 @@ from unittest.case import _AssertRaisesContext from django.db.models import Model +from django.forms.models import model_to_dict from rest_framework.serializers import BaseSerializer, ValidationError from ..serializers import ModelListSerializer, ModelSerializer @@ -124,11 +125,7 @@ def _assert_data_is_subset_of_model(self, data: DataDict, model): elif isinstance(value, Model): data[field] = getattr(value, "id") - model_dict = { - field: value - for field, value in model.__dict__.items() - if not field.startswith("_") - } + model_dict = model_to_dict(model) self.assertDictEqual(model_dict | data, model_dict) def _assert_many( @@ -340,7 +337,12 @@ def assert_update_many( ) def assert_to_representation( - self, instance: AnyModel, new_data: DataDict, *args, **kwargs + self, + instance: AnyModel, + new_data: DataDict, + *args, + non_model_fields: t.Optional[NonModelFields] = None, + **kwargs, ): """Assert: 1. the new data fields not contained in the model are equal. @@ -349,6 +351,7 @@ def assert_to_representation( Args: instance: The model instance to represent. new_data: The field values not contained in the model. + non_model_fields: Data fields that are not in the model. """ serializer = self._init_model_serializer(*args, **kwargs) data = serializer.to_representation(instance) @@ -357,12 +360,14 @@ def assert_new_data_is_subset_of_data(new_data: DataDict, data): assert isinstance(data, dict) for field, new_value in new_data.items(): + value = data[field] if isinstance(new_value, dict): - assert_new_data_is_subset_of_data(new_value, data[field]) + assert_new_data_is_subset_of_data(new_value, value) else: - assert new_value == data.pop(field) + assert new_value == value assert_new_data_is_subset_of_data(new_data, data) + data = self._get_data(data, None, non_model_fields) self._assert_data_is_subset_of_model(data, instance) diff --git a/codeforlife/user/serializers/user.py b/codeforlife/user/serializers/user.py index 15eefdd6..9044cdc3 100644 --- a/codeforlife/user/serializers/user.py +++ b/codeforlife/user/serializers/user.py @@ -64,7 +64,7 @@ class Meta(BaseUserSerializer.Meta): def to_representation(self, instance): try: student = ( - StudentSerializer(instance.new_student).data + dict(StudentSerializer(instance.new_student).data) if instance.new_student and instance.new_student.class_field else None ) @@ -83,7 +83,7 @@ def to_representation(self, instance): try: teacher = ( - TeacherSerializer[Teacher](instance.new_teacher).data + dict(TeacherSerializer[Teacher](instance.new_teacher).data) if instance.new_teacher else None ) diff --git a/codeforlife/user/serializers/user_test.py b/codeforlife/user/serializers/user_test.py index a2985ac4..fe41d483 100644 --- a/codeforlife/user/serializers/user_test.py +++ b/codeforlife/user/serializers/user_test.py @@ -30,6 +30,8 @@ def test_to_representation__teacher(self): }, "student": None, }, + # TODO: remove in new schema. + non_model_fields=["requesting_to_join_class", "teacher", "student"], ) def test_to_representation__student(self): @@ -48,6 +50,8 @@ def test_to_representation__student(self): "school": user.student.class_field.teacher.school.id, }, }, + # TODO: remove in new schema. + non_model_fields=["requesting_to_join_class", "teacher", "student"], ) def test_to_representation__indy(self): From 92eed28cc1cf3c741e7bcd10717bbd7162dc8e22 Mon Sep 17 00:00:00 2001 From: SKairinos Date: Wed, 18 Sep 2024 13:44:09 +0000 Subject: [PATCH 10/11] fix type --- codeforlife/user/serializers/user_test.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/codeforlife/user/serializers/user_test.py b/codeforlife/user/serializers/user_test.py index fe41d483..c6d14075 100644 --- a/codeforlife/user/serializers/user_test.py +++ b/codeforlife/user/serializers/user_test.py @@ -31,7 +31,7 @@ def test_to_representation__teacher(self): "student": None, }, # TODO: remove in new schema. - non_model_fields=["requesting_to_join_class", "teacher", "student"], + non_model_fields={"requesting_to_join_class", "teacher", "student"}, ) def test_to_representation__student(self): @@ -51,7 +51,7 @@ def test_to_representation__student(self): }, }, # TODO: remove in new schema. - non_model_fields=["requesting_to_join_class", "teacher", "student"], + non_model_fields={"requesting_to_join_class", "teacher", "student"}, ) def test_to_representation__indy(self): From 8d5f59e13d6b5aef3ee092395035c6e356d0d798 Mon Sep 17 00:00:00 2001 From: SKairinos Date: Wed, 18 Sep 2024 13:47:29 +0000 Subject: [PATCH 11/11] missed one --- codeforlife/user/serializers/user_test.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/codeforlife/user/serializers/user_test.py b/codeforlife/user/serializers/user_test.py index c6d14075..415a1462 100644 --- a/codeforlife/user/serializers/user_test.py +++ b/codeforlife/user/serializers/user_test.py @@ -66,4 +66,6 @@ def test_to_representation__indy(self): "teacher": None, "student": None, }, + # TODO: remove in new schema. + non_model_fields={"requesting_to_join_class", "teacher", "student"}, )