Fix type annotations

This commit is contained in:
Gabriel Augendre 2022-09-23 20:47:19 +01:00
parent c67dcdc266
commit d02877bdce
11 changed files with 99 additions and 78 deletions

116
poetry.lock generated
View file

@ -54,6 +54,14 @@ category = "main"
optional = false optional = false
python-versions = "*" python-versions = "*"
[[package]]
name = "cerberus"
version = "1.3.4"
description = "Lightweight, extensible schema and data validation tool for Python dictionaries."
category = "dev"
optional = false
python-versions = ">=2.7"
[[package]] [[package]]
name = "certifi" name = "certifi"
version = "2021.10.8" version = "2021.10.8"
@ -81,6 +89,17 @@ python-versions = ">=3.5.0"
[package.extras] [package.extras]
unicode_backport = ["unicodedata2"] unicode_backport = ["unicodedata2"]
[[package]]
name = "click"
version = "8.1.3"
description = "Composable command line interface toolkit"
category = "dev"
optional = false
python-versions = ">=3.7"
[package.dependencies]
colorama = {version = "*", markers = "platform_system == \"Windows\""}
[[package]] [[package]]
name = "colorama" name = "colorama"
version = "0.4.4" version = "0.4.4"
@ -91,14 +110,14 @@ python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*"
[[package]] [[package]]
name = "coverage" name = "coverage"
version = "6.3.2" version = "6.4.4"
description = "Code coverage measurement for Python" description = "Code coverage measurement for Python"
category = "dev" category = "dev"
optional = false optional = false
python-versions = ">=3.7" python-versions = ">=3.7"
[package.dependencies] [package.dependencies]
tomli = {version = "*", optional = true, markers = "extra == \"toml\""} tomli = {version = "*", optional = true, markers = "python_full_version <= \"3.11.0a6\" and extra == \"toml\""}
[package.extras] [package.extras]
toml = ["tomli"] toml = ["tomli"]
@ -138,8 +157,8 @@ bcrypt = ["bcrypt"]
[[package]] [[package]]
name = "django-anymail" name = "django-anymail"
version = "8.5" version = "8.6"
description = "Django email integration for Amazon SES, Mailgun, Mailjet, Postmark, SendGrid, SendinBlue, SparkPost and other transactional ESPs" description = "Django email backends and webhooks for Amazon SES, Mailgun, Mailjet, Mandrill, Postal, Postmark, SendGrid, SendinBlue, and SparkPost"
category = "main" category = "main"
optional = false optional = false
python-versions = ">=3.5" python-versions = ">=3.5"
@ -332,6 +351,24 @@ category = "dev"
optional = false optional = false
python-versions = "*" python-versions = "*"
[[package]]
name = "kolo"
version = "2.0.3"
description = "See everything happening in your running Django app"
category = "dev"
optional = false
python-versions = "*"
[package.dependencies]
cerberus = ">=1.3.4"
click = ">=7.1.2"
tomli = {version = ">=2.0.0", markers = "python_version < \"3.11\""}
toolz = ">=0.11.1"
ulid-py = ">=1.1.0"
[package.extras]
test_generation = ["jinja2 (>=3.0.0)"]
[[package]] [[package]]
name = "lxml" name = "lxml"
version = "4.8.0" version = "4.8.0"
@ -763,6 +800,14 @@ category = "dev"
optional = false optional = false
python-versions = ">=3.7" python-versions = ">=3.7"
[[package]]
name = "toolz"
version = "0.12.0"
description = "List processing tools and functional utilities"
category = "dev"
optional = false
python-versions = ">=3.5"
[[package]] [[package]]
name = "types-beautifulsoup4" name = "types-beautifulsoup4"
version = "4.10.19" version = "4.10.19"
@ -838,6 +883,14 @@ category = "main"
optional = false optional = false
python-versions = ">=2" python-versions = ">=2"
[[package]]
name = "ulid-py"
version = "1.1.0"
description = "Universally Unique Lexicographically Sortable Identifier"
category = "dev"
optional = false
python-versions = "*"
[[package]] [[package]]
name = "urllib3" name = "urllib3"
version = "1.26.9" version = "1.26.9"
@ -920,7 +973,7 @@ multidict = ">=4.0"
[metadata] [metadata]
lock-version = "1.1" lock-version = "1.1"
python-versions = "^3.10" python-versions = "^3.10"
content-hash = "c028a335a533ac4671836cf273e5026afa6b7324634116653f3d7631d030bbcc" content-hash = "7940617ffd193623a91d63618c413a52c334673b2cf47d1749a9ff25e1693dc6"
[metadata.files] [metadata.files]
asgiref = [ asgiref = [
@ -1003,6 +1056,7 @@ brotli = [
{file = "Brotli-1.0.9-pp37-pypy37_pp73-win_amd64.whl", hash = "sha256:76ffebb907bec09ff511bb3acc077695e2c32bc2142819491579a695f77ffd4d"}, {file = "Brotli-1.0.9-pp37-pypy37_pp73-win_amd64.whl", hash = "sha256:76ffebb907bec09ff511bb3acc077695e2c32bc2142819491579a695f77ffd4d"},
{file = "Brotli-1.0.9.zip", hash = "sha256:4d1b810aa0ed773f81dceda2cc7b403d01057458730e309856356d4ef4188438"}, {file = "Brotli-1.0.9.zip", hash = "sha256:4d1b810aa0ed773f81dceda2cc7b403d01057458730e309856356d4ef4188438"},
] ]
cerberus = []
certifi = [ certifi = [
{file = "certifi-2021.10.8-py2.py3-none-any.whl", hash = "sha256:d62a0163eb4c2344ac042ab2bdf75399a71a2d8c7d47eac2e2ee91b9d6339569"}, {file = "certifi-2021.10.8-py2.py3-none-any.whl", hash = "sha256:d62a0163eb4c2344ac042ab2bdf75399a71a2d8c7d47eac2e2ee91b9d6339569"},
{file = "certifi-2021.10.8.tar.gz", hash = "sha256:78884e7c1d4b00ce3cea67b44566851c4343c120abd683433ce934a68ea58872"}, {file = "certifi-2021.10.8.tar.gz", hash = "sha256:78884e7c1d4b00ce3cea67b44566851c4343c120abd683433ce934a68ea58872"},
@ -1015,53 +1069,12 @@ charset-normalizer = [
{file = "charset-normalizer-2.0.12.tar.gz", hash = "sha256:2857e29ff0d34db842cd7ca3230549d1a697f96ee6d3fb071cfa6c7393832597"}, {file = "charset-normalizer-2.0.12.tar.gz", hash = "sha256:2857e29ff0d34db842cd7ca3230549d1a697f96ee6d3fb071cfa6c7393832597"},
{file = "charset_normalizer-2.0.12-py3-none-any.whl", hash = "sha256:6881edbebdb17b39b4eaaa821b438bf6eddffb4468cf344f09f89def34a8b1df"}, {file = "charset_normalizer-2.0.12-py3-none-any.whl", hash = "sha256:6881edbebdb17b39b4eaaa821b438bf6eddffb4468cf344f09f89def34a8b1df"},
] ]
click = []
colorama = [ colorama = [
{file = "colorama-0.4.4-py2.py3-none-any.whl", hash = "sha256:9f47eda37229f68eee03b24b9748937c7dc3868f906e8ba69fbcbdd3bc5dc3e2"}, {file = "colorama-0.4.4-py2.py3-none-any.whl", hash = "sha256:9f47eda37229f68eee03b24b9748937c7dc3868f906e8ba69fbcbdd3bc5dc3e2"},
{file = "colorama-0.4.4.tar.gz", hash = "sha256:5941b2b48a20143d2267e95b1c2a7603ce057ee39fd88e7329b0c292aa16869b"}, {file = "colorama-0.4.4.tar.gz", hash = "sha256:5941b2b48a20143d2267e95b1c2a7603ce057ee39fd88e7329b0c292aa16869b"},
] ]
coverage = [ coverage = []
{file = "coverage-6.3.2-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:9b27d894748475fa858f9597c0ee1d4829f44683f3813633aaf94b19cb5453cf"},
{file = "coverage-6.3.2-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:37d1141ad6b2466a7b53a22e08fe76994c2d35a5b6b469590424a9953155afac"},
{file = "coverage-6.3.2-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f9987b0354b06d4df0f4d3e0ec1ae76d7ce7cbca9a2f98c25041eb79eec766f1"},
{file = "coverage-6.3.2-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:26e2deacd414fc2f97dd9f7676ee3eaecd299ca751412d89f40bc01557a6b1b4"},
{file = "coverage-6.3.2-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4dd8bafa458b5c7d061540f1ee9f18025a68e2d8471b3e858a9dad47c8d41903"},
{file = "coverage-6.3.2-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:46191097ebc381fbf89bdce207a6c107ac4ec0890d8d20f3360345ff5976155c"},
{file = "coverage-6.3.2-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:6f89d05e028d274ce4fa1a86887b071ae1755082ef94a6740238cd7a8178804f"},
{file = "coverage-6.3.2-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:58303469e9a272b4abdb9e302a780072c0633cdcc0165db7eec0f9e32f901e05"},
{file = "coverage-6.3.2-cp310-cp310-win32.whl", hash = "sha256:2fea046bfb455510e05be95e879f0e768d45c10c11509e20e06d8fcaa31d9e39"},
{file = "coverage-6.3.2-cp310-cp310-win_amd64.whl", hash = "sha256:a2a8b8bcc399edb4347a5ca8b9b87e7524c0967b335fbb08a83c8421489ddee1"},
{file = "coverage-6.3.2-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:f1555ea6d6da108e1999b2463ea1003fe03f29213e459145e70edbaf3e004aaa"},
{file = "coverage-6.3.2-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e5f4e1edcf57ce94e5475fe09e5afa3e3145081318e5fd1a43a6b4539a97e518"},
{file = "coverage-6.3.2-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:7a15dc0a14008f1da3d1ebd44bdda3e357dbabdf5a0b5034d38fcde0b5c234b7"},
{file = "coverage-6.3.2-cp37-cp37m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:21b7745788866028adeb1e0eca3bf1101109e2dc58456cb49d2d9b99a8c516e6"},
{file = "coverage-6.3.2-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:8ce257cac556cb03be4a248d92ed36904a59a4a5ff55a994e92214cde15c5bad"},
{file = "coverage-6.3.2-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:b0be84e5a6209858a1d3e8d1806c46214e867ce1b0fd32e4ea03f4bd8b2e3359"},
{file = "coverage-6.3.2-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:acf53bc2cf7282ab9b8ba346746afe703474004d9e566ad164c91a7a59f188a4"},
{file = "coverage-6.3.2-cp37-cp37m-win32.whl", hash = "sha256:8bdde1177f2311ee552f47ae6e5aa7750c0e3291ca6b75f71f7ffe1f1dab3dca"},
{file = "coverage-6.3.2-cp37-cp37m-win_amd64.whl", hash = "sha256:b31651d018b23ec463e95cf10070d0b2c548aa950a03d0b559eaa11c7e5a6fa3"},
{file = "coverage-6.3.2-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:07e6db90cd9686c767dcc593dff16c8c09f9814f5e9c51034066cad3373b914d"},
{file = "coverage-6.3.2-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:2c6dbb42f3ad25760010c45191e9757e7dce981cbfb90e42feef301d71540059"},
{file = "coverage-6.3.2-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c76aeef1b95aff3905fb2ae2d96e319caca5b76fa41d3470b19d4e4a3a313512"},
{file = "coverage-6.3.2-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:8cf5cfcb1521dc3255d845d9dca3ff204b3229401994ef8d1984b32746bb45ca"},
{file = "coverage-6.3.2-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8fbbdc8d55990eac1b0919ca69eb5a988a802b854488c34b8f37f3e2025fa90d"},
{file = "coverage-6.3.2-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:ec6bc7fe73a938933d4178c9b23c4e0568e43e220aef9472c4f6044bfc6dd0f0"},
{file = "coverage-6.3.2-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:9baff2a45ae1f17c8078452e9e5962e518eab705e50a0aa8083733ea7d45f3a6"},
{file = "coverage-6.3.2-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:fd9e830e9d8d89b20ab1e5af09b32d33e1a08ef4c4e14411e559556fd788e6b2"},
{file = "coverage-6.3.2-cp38-cp38-win32.whl", hash = "sha256:f7331dbf301b7289013175087636bbaf5b2405e57259dd2c42fdcc9fcc47325e"},
{file = "coverage-6.3.2-cp38-cp38-win_amd64.whl", hash = "sha256:68353fe7cdf91f109fc7d474461b46e7f1f14e533e911a2a2cbb8b0fc8613cf1"},
{file = "coverage-6.3.2-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:b78e5afb39941572209f71866aa0b206c12f0109835aa0d601e41552f9b3e620"},
{file = "coverage-6.3.2-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:4e21876082ed887baed0146fe222f861b5815455ada3b33b890f4105d806128d"},
{file = "coverage-6.3.2-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:34626a7eee2a3da12af0507780bb51eb52dca0e1751fd1471d0810539cefb536"},
{file = "coverage-6.3.2-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:1ebf730d2381158ecf3dfd4453fbca0613e16eaa547b4170e2450c9707665ce7"},
{file = "coverage-6.3.2-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:dd6fe30bd519694b356cbfcaca9bd5c1737cddd20778c6a581ae20dc8c04def2"},
{file = "coverage-6.3.2-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:96f8a1cb43ca1422f36492bebe63312d396491a9165ed3b9231e778d43a7fca4"},
{file = "coverage-6.3.2-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:dd035edafefee4d573140a76fdc785dc38829fe5a455c4bb12bac8c20cfc3d69"},
{file = "coverage-6.3.2-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:5ca5aeb4344b30d0bec47481536b8ba1181d50dbe783b0e4ad03c95dc1296684"},
{file = "coverage-6.3.2-cp39-cp39-win32.whl", hash = "sha256:f5fa5803f47e095d7ad8443d28b01d48c0359484fec1b9d8606d0e3282084bc4"},
{file = "coverage-6.3.2-cp39-cp39-win_amd64.whl", hash = "sha256:9548f10d8be799551eb3a9c74bbf2b4934ddb330e08a73320123c07f95cc2d92"},
{file = "coverage-6.3.2-pp36.pp37.pp38-none-any.whl", hash = "sha256:18d520c6860515a771708937d2f78f63cc47ab3b80cb78e86573b0a760161faf"},
{file = "coverage-6.3.2.tar.gz", hash = "sha256:03e2a7826086b91ef345ff18742ee9fc47a6839ccd517061ef8fa1976e652ce9"},
]
cssselect = [ cssselect = [
{file = "cssselect-1.1.0-py2.py3-none-any.whl", hash = "sha256:f612ee47b749c877ebae5bb77035d8f4202c6ad0f0fc1271b3c18ad6c4468ecf"}, {file = "cssselect-1.1.0-py2.py3-none-any.whl", hash = "sha256:f612ee47b749c877ebae5bb77035d8f4202c6ad0f0fc1271b3c18ad6c4468ecf"},
{file = "cssselect-1.1.0.tar.gz", hash = "sha256:f95f8dedd925fd8f54edb3d2dfb44c190d9d18512377d3c1e2388d16126879bc"}, {file = "cssselect-1.1.0.tar.gz", hash = "sha256:f95f8dedd925fd8f54edb3d2dfb44c190d9d18512377d3c1e2388d16126879bc"},
@ -1075,8 +1088,8 @@ django = [
{file = "Django-4.0.4.tar.gz", hash = "sha256:4e8177858524417563cc0430f29ea249946d831eacb0068a1455686587df40b5"}, {file = "Django-4.0.4.tar.gz", hash = "sha256:4e8177858524417563cc0430f29ea249946d831eacb0068a1455686587df40b5"},
] ]
django-anymail = [ django-anymail = [
{file = "django-anymail-8.5.tar.gz", hash = "sha256:677e937dc9e2671ca7631abb1d94ddc6b840beb3d53c0fbf699e866a6a9ba92f"}, {file = "django-anymail-8.6.tar.gz", hash = "sha256:783342d49dd07d68778b81dd12a94c86e1d217463a68a85450a0513fabe31345"},
{file = "django_anymail-8.5-py3-none-any.whl", hash = "sha256:2325932f56f914d96e0a54db850f2b246ed2277b753f75319620d051a51551e2"}, {file = "django_anymail-8.6-py3-none-any.whl", hash = "sha256:49d83d7c16316ca86a624097496881d59b7d71b16bf1c5211cffa5b19ef98d0c"},
] ]
django-cleanup = [ django-cleanup = [
{file = "django-cleanup-5.2.0.tar.gz", hash = "sha256:909d10ff574f5ce1a40fa63bd5c94c9ed866fd7ae770994c46cdf66c3db3e846"}, {file = "django-cleanup-5.2.0.tar.gz", hash = "sha256:909d10ff574f5ce1a40fa63bd5c94c9ed866fd7ae770994c46cdf66c3db3e846"},
@ -1131,6 +1144,7 @@ invoke = [
{file = "invoke-1.7.0-py3-none-any.whl", hash = "sha256:a5159fc63dba6ca2a87a1e33d282b99cea69711b03c64a35bb4e1c53c6c4afa0"}, {file = "invoke-1.7.0-py3-none-any.whl", hash = "sha256:a5159fc63dba6ca2a87a1e33d282b99cea69711b03c64a35bb4e1c53c6c4afa0"},
{file = "invoke-1.7.0.tar.gz", hash = "sha256:e332e49de40463f2016315f51df42313855772be86435686156bc18f45b5cc6c"}, {file = "invoke-1.7.0.tar.gz", hash = "sha256:e332e49de40463f2016315f51df42313855772be86435686156bc18f45b5cc6c"},
] ]
kolo = []
lxml = [ lxml = [
{file = "lxml-4.8.0-cp27-cp27m-macosx_10_14_x86_64.whl", hash = "sha256:e1ab2fac607842ac36864e358c42feb0960ae62c34aa4caaf12ada0a1fb5d99b"}, {file = "lxml-4.8.0-cp27-cp27m-macosx_10_14_x86_64.whl", hash = "sha256:e1ab2fac607842ac36864e358c42feb0960ae62c34aa4caaf12ada0a1fb5d99b"},
{file = "lxml-4.8.0-cp27-cp27m-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:28d1af847786f68bec57961f31221125c29d6f52d9187c01cd34dc14e2b29430"}, {file = "lxml-4.8.0-cp27-cp27m-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:28d1af847786f68bec57961f31221125c29d6f52d9187c01cd34dc14e2b29430"},
@ -1503,6 +1517,7 @@ tomli = [
{file = "tomli-2.0.1-py3-none-any.whl", hash = "sha256:939de3e7a6161af0c887ef91b7d41a53e7c5a1ca976325f429cb46ea9bc30ecc"}, {file = "tomli-2.0.1-py3-none-any.whl", hash = "sha256:939de3e7a6161af0c887ef91b7d41a53e7c5a1ca976325f429cb46ea9bc30ecc"},
{file = "tomli-2.0.1.tar.gz", hash = "sha256:de526c12914f0c550d15924c62d72abc48d6fe7364aa87328337a31007fe8a4f"}, {file = "tomli-2.0.1.tar.gz", hash = "sha256:de526c12914f0c550d15924c62d72abc48d6fe7364aa87328337a31007fe8a4f"},
] ]
toolz = []
types-beautifulsoup4 = [ types-beautifulsoup4 = [
{file = "types-beautifulsoup4-4.10.19.tar.gz", hash = "sha256:dfbee0b788fdd0e59c2a62594b3152abff639bba5ad01e55628bd5e39adc8010"}, {file = "types-beautifulsoup4-4.10.19.tar.gz", hash = "sha256:dfbee0b788fdd0e59c2a62594b3152abff639bba5ad01e55628bd5e39adc8010"},
{file = "types_beautifulsoup4-4.10.19-py3-none-any.whl", hash = "sha256:209030fecc9770ebed79e94a308aa29009d53c81fe08f0b5dff1d837cd00bdd7"}, {file = "types_beautifulsoup4-4.10.19-py3-none-any.whl", hash = "sha256:209030fecc9770ebed79e94a308aa29009d53c81fe08f0b5dff1d837cd00bdd7"},
@ -1539,6 +1554,7 @@ tzdata = [
{file = "tzdata-2022.1-py2.py3-none-any.whl", hash = "sha256:238e70234214138ed7b4e8a0fab0e5e13872edab3be586ab8198c407620e2ab9"}, {file = "tzdata-2022.1-py2.py3-none-any.whl", hash = "sha256:238e70234214138ed7b4e8a0fab0e5e13872edab3be586ab8198c407620e2ab9"},
{file = "tzdata-2022.1.tar.gz", hash = "sha256:8b536a8ec63dc0751342b3984193a3118f8fca2afe25752bb9b7fffd398552d3"}, {file = "tzdata-2022.1.tar.gz", hash = "sha256:8b536a8ec63dc0751342b3984193a3118f8fca2afe25752bb9b7fffd398552d3"},
] ]
ulid-py = []
urllib3 = [ urllib3 = [
{file = "urllib3-1.26.9-py2.py3-none-any.whl", hash = "sha256:44ece4d53fb1706f667c9bd1c648f5469a2ec925fcf3a776667042d645472c14"}, {file = "urllib3-1.26.9-py2.py3-none-any.whl", hash = "sha256:44ece4d53fb1706f667c9bd1c648f5469a2ec925fcf3a776667042d645472c14"},
{file = "urllib3-1.26.9.tar.gz", hash = "sha256:aabaf16477806a5e1dd19aa41f8c2b7950dd3c746362d7e3223dbe6de6ac448e"}, {file = "urllib3-1.26.9.tar.gz", hash = "sha256:aabaf16477806a5e1dd19aa41f8c2b7950dd3c746362d7e3223dbe6de6ac448e"},

View file

@ -42,6 +42,7 @@ types-setuptools = "^57.4.5"
types-toml = "^0.10.1" types-toml = "^0.10.1"
types-beautifulsoup4 = "^4.10.7" types-beautifulsoup4 = "^4.10.7"
types-Pillow = "^8.3.11" types-Pillow = "^8.3.11"
kolo = "^2.0.3"
[tool.black] [tool.black]
target-version = ['py310'] target-version = ['py310']

View file

@ -3,8 +3,9 @@ from typing import cast
from django.contrib import admin, messages from django.contrib import admin, messages
from django.contrib.admin import register from django.contrib.admin import register
from django.contrib.auth.admin import UserAdmin from django.contrib.auth.admin import UserAdmin
from django.core.handlers.wsgi import WSGIRequest
from django.db.models import QuerySet from django.db.models import QuerySet
from django.http import HttpRequest, HttpResponse, HttpResponseRedirect from django.http import HttpResponse, HttpResponseRedirect
from django.shortcuts import redirect from django.shortcuts import redirect
from .models import Article, Tag, User from .models import Article, Tag, User
@ -77,13 +78,13 @@ class ArticleAdmin(admin.ModelAdmin):
autocomplete_fields = ["tags"] autocomplete_fields = ["tags"]
show_full_result_count = False show_full_result_count = False
def get_queryset(self, request: HttpRequest) -> QuerySet: def get_queryset(self, request: WSGIRequest) -> QuerySet:
queryset = super().get_queryset(request) queryset = super().get_queryset(request)
queryset = queryset.prefetch_related("tags") queryset = queryset.prefetch_related("tags")
return queryset return queryset
@admin.action(description="Publish selected articles") @admin.action(description="Publish selected articles")
def publish(self, request: HttpRequest, queryset: QuerySet) -> None: def publish(self, request: WSGIRequest, queryset: QuerySet) -> None:
if not request.user.has_perm("articles.change_article"): if not request.user.has_perm("articles.change_article"):
messages.warning(request, "You're not allowed to do this.") messages.warning(request, "You're not allowed to do this.")
return return
@ -92,7 +93,7 @@ class ArticleAdmin(admin.ModelAdmin):
messages.success(request, f"{len(queryset)} articles published.") messages.success(request, f"{len(queryset)} articles published.")
@admin.action(description="Unpublish selected articles") @admin.action(description="Unpublish selected articles")
def unpublish(self, request: HttpRequest, queryset: QuerySet) -> None: def unpublish(self, request: WSGIRequest, queryset: QuerySet) -> None:
if not request.user.has_perm("articles.change_article"): if not request.user.has_perm("articles.change_article"):
messages.warning(request, "You're not allowed to do this.") messages.warning(request, "You're not allowed to do this.")
return return
@ -101,7 +102,7 @@ class ArticleAdmin(admin.ModelAdmin):
messages.success(request, f"{len(queryset)} articles unpublished.") messages.success(request, f"{len(queryset)} articles unpublished.")
@admin.action(description="Refresh draft key of selected articles") @admin.action(description="Refresh draft key of selected articles")
def refresh_draft_key(self, request: HttpRequest, queryset: QuerySet) -> None: def refresh_draft_key(self, request: WSGIRequest, queryset: QuerySet) -> None:
if not request.user.has_perm("articles.change_article"): if not request.user.has_perm("articles.change_article"):
messages.warning(request, "You're not allowed to do this.") messages.warning(request, "You're not allowed to do this.")
return return
@ -120,13 +121,13 @@ class ArticleAdmin(admin.ModelAdmin):
} }
def response_post_save_add( def response_post_save_add(
self, request: HttpRequest, obj: Article self, request: WSGIRequest, obj: Article
) -> HttpResponseRedirect: ) -> HttpResponseRedirect:
if "_preview" in request.POST: if "_preview" in request.POST:
return cast(HttpResponseRedirect, redirect("article-detail", slug=obj.slug)) return cast(HttpResponseRedirect, redirect("article-detail", slug=obj.slug))
return super().response_post_save_add(request, obj) return super().response_post_save_add(request, obj)
def response_change(self, request: HttpRequest, obj: Article) -> HttpResponse: def response_change(self, request: WSGIRequest, obj: Article) -> HttpResponse:
if "_preview" in request.POST: if "_preview" in request.POST:
obj.save() obj.save()
return redirect("article-detail", slug=obj.slug) return redirect("article-detail", slug=obj.slug)

View file

@ -2,7 +2,7 @@ import copy
from typing import Any from typing import Any
from django.conf import settings from django.conf import settings
from django.http import HttpRequest from django.core.handlers.wsgi import WSGIRequest
from articles.models import Article from articles.models import Article
from attachments.models import Attachment from attachments.models import Attachment
@ -12,7 +12,7 @@ IGNORED_PATHS = [
] ]
def drafts_count(request: HttpRequest) -> dict[str, Any]: def drafts_count(request: WSGIRequest) -> dict[str, Any]:
if request.path in IGNORED_PATHS: if request.path in IGNORED_PATHS:
return {} return {}
if not request.user.is_authenticated: if not request.user.is_authenticated:
@ -20,13 +20,13 @@ def drafts_count(request: HttpRequest) -> dict[str, Any]:
return {"drafts_count": Article.objects.filter(status=Article.DRAFT).count()} return {"drafts_count": Article.objects.filter(status=Article.DRAFT).count()}
def date_format(request: HttpRequest) -> dict[str, Any]: def date_format(request: WSGIRequest) -> dict[str, Any]:
if request.path in IGNORED_PATHS: if request.path in IGNORED_PATHS:
return {} return {}
return {"CUSTOM_ISO": r"Y-m-d\TH:i:sO", "ISO_DATE": "Y-m-d"} return {"CUSTOM_ISO": r"Y-m-d\TH:i:sO", "ISO_DATE": "Y-m-d"}
def git_version(request: HttpRequest) -> dict[str, Any]: def git_version(request: WSGIRequest) -> dict[str, Any]:
if request.path in IGNORED_PATHS: if request.path in IGNORED_PATHS:
return {} return {}
try: try:
@ -40,13 +40,13 @@ def git_version(request: HttpRequest) -> dict[str, Any]:
return {"git_version": version, "git_version_url": url} return {"git_version": version, "git_version_url": url}
def analytics(request: HttpRequest) -> dict[str, Any]: def analytics(request: WSGIRequest) -> dict[str, Any]:
return { return {
"goatcounter_domain": settings.GOATCOUNTER_DOMAIN, "goatcounter_domain": settings.GOATCOUNTER_DOMAIN,
} }
def open_graph_image_url(request: HttpRequest) -> dict[str, Any]: def open_graph_image_url(request: WSGIRequest) -> dict[str, Any]:
if request.path in IGNORED_PATHS: if request.path in IGNORED_PATHS:
return {} return {}
open_graph_image = Attachment.objects.get_open_graph_image() open_graph_image = Attachment.objects.get_open_graph_image()
@ -56,7 +56,7 @@ def open_graph_image_url(request: HttpRequest) -> dict[str, Any]:
return {"open_graph_image_url": url} return {"open_graph_image_url": url}
def blog_metadata(request: HttpRequest) -> dict[str, Any]: def blog_metadata(request: WSGIRequest) -> dict[str, Any]:
blog_settings = copy.deepcopy(settings.BLOG) blog_settings = copy.deepcopy(settings.BLOG)
return { return {
"blog": blog_settings, "blog": blog_settings,

View file

@ -3,14 +3,14 @@ import re
import markdown import markdown
from bs4 import BeautifulSoup from bs4 import BeautifulSoup
from django.conf import settings from django.conf import settings
from django.http import HttpRequest from django.core.handlers.wsgi import WSGIRequest
from markdown.extensions.codehilite import CodeHiliteExtension from markdown.extensions.codehilite import CodeHiliteExtension
from markdown.extensions.toc import TocExtension from markdown.extensions.toc import TocExtension
from articles.markdown import LazyLoadingImageExtension from articles.markdown import LazyLoadingImageExtension
def build_full_absolute_url(request: HttpRequest | None, url: str) -> str: def build_full_absolute_url(request: WSGIRequest | None, url: str) -> str:
if request: if request:
return request.build_absolute_uri(url) return request.build_absolute_uri(url)
else: else:

View file

@ -1,7 +1,8 @@
from typing import Any from typing import Any
from django.contrib.auth.decorators import login_required from django.contrib.auth.decorators import login_required
from django.http import HttpRequest, HttpResponse from django.core.handlers.wsgi import WSGIRequest
from django.http import HttpResponse
from django.shortcuts import render from django.shortcuts import render
from django.views.decorators.http import require_POST from django.views.decorators.http import require_POST
@ -10,7 +11,8 @@ from articles.models import Article, Tag
@login_required @login_required
@require_POST @require_POST
def render_article(request: HttpRequest, article_pk: int) -> HttpResponse: def render_article(request: WSGIRequest, article_pk: int) -> HttpResponse:
print(f"{type(request)=}")
template = "articles/article_detail.html" template = "articles/article_detail.html"
article = Article.objects.get(pk=article_pk) article = Article.objects.get(pk=article_pk)
article.content = request.POST.get("content", article.content) article.content = request.POST.get("content", article.content)

View file

@ -2,8 +2,8 @@ from datetime import datetime
from typing import Any, Iterable from typing import Any, Iterable
from django.contrib.syndication.views import Feed from django.contrib.syndication.views import Feed
from django.core.handlers.wsgi import WSGIRequest
from django.db.models import QuerySet from django.db.models import QuerySet
from django.http import HttpRequest
from articles.models import Article, Tag from articles.models import Article, Tag
from blog import settings from blog import settings
@ -34,7 +34,7 @@ class CompleteFeed(BaseFeed):
class TagFeed(BaseFeed): class TagFeed(BaseFeed):
def get_object(self, request: HttpRequest, *args: Any, **kwargs: Any) -> Tag: def get_object(self, request: WSGIRequest, *args: Any, **kwargs: Any) -> Tag:
return Tag.objects.get(slug=kwargs.get("slug")) return Tag.objects.get(slug=kwargs.get("slug"))
def title(self, tag: Tag) -> str: def title(self, tag: Tag) -> str:

View file

@ -4,10 +4,10 @@ from typing import Any
from django.conf import settings from django.conf import settings
from django.contrib.auth.mixins import LoginRequiredMixin from django.contrib.auth.mixins import LoginRequiredMixin
from django.core.handlers.wsgi import WSGIRequest
from django.core.paginator import Page from django.core.paginator import Page
from django.db.models import F, Q, QuerySet from django.db.models import F, Q, QuerySet
from django.http import HttpRequest from django.http.response import HttpResponse, HttpResponseBase
from django.http.response import HttpResponseBase
from django.shortcuts import get_object_or_404 from django.shortcuts import get_object_or_404
from django.views import generic from django.views import generic
from django.views.generic import DetailView from django.views.generic import DetailView
@ -101,7 +101,7 @@ class TagArticlesListView(PublicArticleListView):
html_title = "" html_title = ""
def dispatch( def dispatch(
self, request: HttpRequest, *args: Any, **kwargs: Any self, request: WSGIRequest, *args: Any, **kwargs: Any
) -> HttpResponseBase: ) -> HttpResponseBase:
self.tag = get_object_or_404(Tag, slug=self.kwargs.get("slug")) self.tag = get_object_or_404(Tag, slug=self.kwargs.get("slug"))
self.main_title = self.html_title = f"{self.tag.name} articles" self.main_title = self.html_title = f"{self.tag.name} articles"

View file

@ -1,7 +1,7 @@
from django.contrib import admin, messages from django.contrib import admin, messages
from django.contrib.admin import register from django.contrib.admin import register
from django.core.handlers.wsgi import WSGIRequest
from django.db.models import QuerySet from django.db.models import QuerySet
from django.http import HttpRequest
from django.utils.html import format_html from django.utils.html import format_html
from attachments.models import Attachment from attachments.models import Attachment
@ -59,7 +59,7 @@ class AttachmentAdmin(admin.ModelAdmin):
return "" return ""
@admin.action(description="Set as open graph image") @admin.action(description="Set as open graph image")
def set_as_open_graph_image(self, request: HttpRequest, queryset: QuerySet) -> None: def set_as_open_graph_image(self, request: WSGIRequest, queryset: QuerySet) -> None:
if len(queryset) != 1: if len(queryset) != 1:
messages.error(request, "You must select only one attachment") messages.error(request, "You must select only one attachment")
return return
@ -69,7 +69,7 @@ class AttachmentAdmin(admin.ModelAdmin):
@admin.action(description="Reprocess selected attachments") @admin.action(description="Reprocess selected attachments")
def reprocess_selected_attachments( def reprocess_selected_attachments(
self, request: HttpRequest, queryset: QuerySet self, request: WSGIRequest, queryset: QuerySet
) -> None: ) -> None:
if len(queryset) == 0: if len(queryset) == 0:
messages.error(request, "You must select at least one attachment") messages.error(request, "You must select at least one attachment")

View file

@ -8,16 +8,16 @@ from typing import Any
import requests import requests
from django.conf import settings from django.conf import settings
from django.core.files import File from django.core.files import File
from django.core.handlers.wsgi import WSGIRequest
from django.db import models from django.db import models
from django.db.models.fields.files import FieldFile from django.db.models.fields.files import FieldFile
from django.http import HttpRequest
from PIL import Image from PIL import Image
from articles.utils import build_full_absolute_url from articles.utils import build_full_absolute_url
class AbsoluteUrlFieldFile(FieldFile): class AbsoluteUrlFieldFile(FieldFile):
def get_full_absolute_url(self, request: HttpRequest) -> str: def get_full_absolute_url(self, request: WSGIRequest) -> str:
return build_full_absolute_url(request, self.url) return build_full_absolute_url(request, self.url)

View file

@ -96,6 +96,7 @@ INSTALLED_APPS = [
] ]
MIDDLEWARE = [ MIDDLEWARE = [
"kolo.middleware.KoloMiddleware",
"django.middleware.security.SecurityMiddleware", "django.middleware.security.SecurityMiddleware",
"whitenoise.middleware.WhiteNoiseMiddleware", "whitenoise.middleware.WhiteNoiseMiddleware",
"django.middleware.gzip.GZipMiddleware", "django.middleware.gzip.GZipMiddleware",