From 059ff725d7aa7858ffe904ba31d1ea44c54741fe Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Sat, 3 Aug 2024 01:16:10 +0000 Subject: [PATCH 01/59] chore(deps): update all dependencies --- .pre-commit-config.yaml | 4 ++-- poetry.lock | 38 +++++++++++++++++++------------------- 2 files changed, 21 insertions(+), 21 deletions(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index f9994aeee..14c7652b8 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -29,7 +29,7 @@ repos: - id: trailing-whitespace - id: mixed-line-ending - repo: https://github.com/RobertCraigie/pyright-python - rev: v1.1.373 + rev: v1.1.374 hooks: - id: pyright additional_dependencies: @@ -49,7 +49,7 @@ repos: - sqlalchemy==2.0.31 - typing-extensions==4.12.2 - repo: https://github.com/astral-sh/ruff-pre-commit - rev: v0.5.5 + rev: v0.5.6 hooks: - id: ruff args: [--fix, --unsafe-fixes] diff --git a/poetry.lock b/poetry.lock index e6de1fd50..cf1253ffb 100644 --- a/poetry.lock +++ b/poetry.lock @@ -1302,29 +1302,29 @@ use-chardet-on-py3 = ["chardet (>=3.0.2,<6)"] [[package]] name = "ruff" -version = "0.5.5" +version = "0.5.6" description = "An extremely fast Python linter and code formatter, written in Rust." optional = false python-versions = ">=3.7" files = [ - {file = "ruff-0.5.5-py3-none-linux_armv6l.whl", hash = "sha256:605d589ec35d1da9213a9d4d7e7a9c761d90bba78fc8790d1c5e65026c1b9eaf"}, - {file = "ruff-0.5.5-py3-none-macosx_10_12_x86_64.whl", hash = "sha256:00817603822a3e42b80f7c3298c8269e09f889ee94640cd1fc7f9329788d7bf8"}, - {file = "ruff-0.5.5-py3-none-macosx_11_0_arm64.whl", hash = "sha256:187a60f555e9f865a2ff2c6984b9afeffa7158ba6e1eab56cb830404c942b0f3"}, - {file = "ruff-0.5.5-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:fe26fc46fa8c6e0ae3f47ddccfbb136253c831c3289bba044befe68f467bfb16"}, - {file = "ruff-0.5.5-py3-none-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:4ad25dd9c5faac95c8e9efb13e15803cd8bbf7f4600645a60ffe17c73f60779b"}, - {file = "ruff-0.5.5-py3-none-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:f70737c157d7edf749bcb952d13854e8f745cec695a01bdc6e29c29c288fc36e"}, - {file = "ruff-0.5.5-py3-none-manylinux_2_17_ppc64.manylinux2014_ppc64.whl", hash = "sha256:cfd7de17cef6ab559e9f5ab859f0d3296393bc78f69030967ca4d87a541b97a0"}, - {file = "ruff-0.5.5-py3-none-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:a09b43e02f76ac0145f86a08e045e2ea452066f7ba064fd6b0cdccb486f7c3e7"}, - {file = "ruff-0.5.5-py3-none-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:d0b856cb19c60cd40198be5d8d4b556228e3dcd545b4f423d1ad812bfdca5884"}, - {file = "ruff-0.5.5-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3687d002f911e8a5faf977e619a034d159a8373514a587249cc00f211c67a091"}, - {file = "ruff-0.5.5-py3-none-musllinux_1_2_aarch64.whl", hash = "sha256:ac9dc814e510436e30d0ba535f435a7f3dc97f895f844f5b3f347ec8c228a523"}, - {file = "ruff-0.5.5-py3-none-musllinux_1_2_armv7l.whl", hash = "sha256:af9bdf6c389b5add40d89b201425b531e0a5cceb3cfdcc69f04d3d531c6be74f"}, - {file = "ruff-0.5.5-py3-none-musllinux_1_2_i686.whl", hash = "sha256:d40a8533ed545390ef8315b8e25c4bb85739b90bd0f3fe1280a29ae364cc55d8"}, - {file = "ruff-0.5.5-py3-none-musllinux_1_2_x86_64.whl", hash = "sha256:cab904683bf9e2ecbbe9ff235bfe056f0eba754d0168ad5407832928d579e7ab"}, - {file = "ruff-0.5.5-py3-none-win32.whl", hash = "sha256:696f18463b47a94575db635ebb4c178188645636f05e934fdf361b74edf1bb2d"}, - {file = "ruff-0.5.5-py3-none-win_amd64.whl", hash = "sha256:50f36d77f52d4c9c2f1361ccbfbd09099a1b2ea5d2b2222c586ab08885cf3445"}, - {file = "ruff-0.5.5-py3-none-win_arm64.whl", hash = "sha256:3191317d967af701f1b73a31ed5788795936e423b7acce82a2b63e26eb3e89d6"}, - {file = "ruff-0.5.5.tar.gz", hash = "sha256:cc5516bdb4858d972fbc31d246bdb390eab8df1a26e2353be2dbc0c2d7f5421a"}, + {file = "ruff-0.5.6-py3-none-linux_armv6l.whl", hash = "sha256:a0ef5930799a05522985b9cec8290b185952f3fcd86c1772c3bdbd732667fdcd"}, + {file = "ruff-0.5.6-py3-none-macosx_10_12_x86_64.whl", hash = "sha256:b652dc14f6ef5d1552821e006f747802cc32d98d5509349e168f6bf0ee9f8f42"}, + {file = "ruff-0.5.6-py3-none-macosx_11_0_arm64.whl", hash = "sha256:80521b88d26a45e871f31e4b88938fd87db7011bb961d8afd2664982dfc3641a"}, + {file = "ruff-0.5.6-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d9bc8f328a9f1309ae80e4d392836e7dbc77303b38ed4a7112699e63d3b066ab"}, + {file = "ruff-0.5.6-py3-none-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:4d394940f61f7720ad371ddedf14722ee1d6250fd8d020f5ea5a86e7be217daf"}, + {file = "ruff-0.5.6-py3-none-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:111a99cdb02f69ddb2571e2756e017a1496c2c3a2aeefe7b988ddab38b416d36"}, + {file = "ruff-0.5.6-py3-none-manylinux_2_17_ppc64.manylinux2014_ppc64.whl", hash = "sha256:e395daba77a79f6dc0d07311f94cc0560375ca20c06f354c7c99af3bf4560c5d"}, + {file = "ruff-0.5.6-py3-none-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:c476acb43c3c51e3c614a2e878ee1589655fa02dab19fe2db0423a06d6a5b1b6"}, + {file = "ruff-0.5.6-py3-none-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:e2ff8003f5252fd68425fd53d27c1f08b201d7ed714bb31a55c9ac1d4c13e2eb"}, + {file = "ruff-0.5.6-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c94e084ba3eaa80c2172918c2ca2eb2230c3f15925f4ed8b6297260c6ef179ad"}, + {file = "ruff-0.5.6-py3-none-musllinux_1_2_aarch64.whl", hash = "sha256:1f77c1c3aa0669fb230b06fb24ffa3e879391a3ba3f15e3d633a752da5a3e670"}, + {file = "ruff-0.5.6-py3-none-musllinux_1_2_armv7l.whl", hash = "sha256:f908148c93c02873210a52cad75a6eda856b2cbb72250370ce3afef6fb99b1ed"}, + {file = "ruff-0.5.6-py3-none-musllinux_1_2_i686.whl", hash = "sha256:563a7ae61ad284187d3071d9041c08019975693ff655438d8d4be26e492760bd"}, + {file = "ruff-0.5.6-py3-none-musllinux_1_2_x86_64.whl", hash = "sha256:94fe60869bfbf0521e04fd62b74cbca21cbc5beb67cbb75ab33fe8c174f54414"}, + {file = "ruff-0.5.6-py3-none-win32.whl", hash = "sha256:e6a584c1de6f8591c2570e171cc7ce482bb983d49c70ddf014393cd39e9dfaed"}, + {file = "ruff-0.5.6-py3-none-win_amd64.whl", hash = "sha256:d7fe7dccb1a89dc66785d7aa0ac283b2269712d8ed19c63af908fdccca5ccc1a"}, + {file = "ruff-0.5.6-py3-none-win_arm64.whl", hash = "sha256:57c6c0dd997b31b536bff49b9eee5ed3194d60605a4427f735eeb1f9c1b8d264"}, + {file = "ruff-0.5.6.tar.gz", hash = "sha256:07c9e3c2a8e1fe377dd460371c3462671a728c981c3205a5217291422209f642"}, ] [[package]] From eb611f4ea1168da9f125ae7545eb55b2511e6883 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Sat, 3 Aug 2024 01:16:26 +0000 Subject: [PATCH 02/59] chore(deps): update all dependencies --- poetry.lock | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/poetry.lock b/poetry.lock index e6de1fd50..11205fc70 100644 --- a/poetry.lock +++ b/poetry.lock @@ -1343,13 +1343,13 @@ sqlalchemy = "*" [[package]] name = "setuptools" -version = "71.1.0" +version = "72.1.0" description = "Easily download, build, install, upgrade, and uninstall Python packages" optional = false python-versions = ">=3.8" files = [ - {file = "setuptools-71.1.0-py3-none-any.whl", hash = "sha256:33874fdc59b3188304b2e7c80d9029097ea31627180896fb549c578ceb8a0855"}, - {file = "setuptools-71.1.0.tar.gz", hash = "sha256:032d42ee9fb536e33087fb66cac5f840eb9391ed05637b3f2a76a7c8fb477936"}, + {file = "setuptools-72.1.0-py3-none-any.whl", hash = "sha256:5a03e1860cf56bb6ef48ce186b0e557fdba433237481a9a625176c2831be15d1"}, + {file = "setuptools-72.1.0.tar.gz", hash = "sha256:8d243eff56d095e5817f796ede6ae32941278f542e0f941867cc05ae52b162ec"}, ] [package.extras] From 58d121aacdb1ba3911f963e332675bd42127171b Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Mon, 5 Aug 2024 00:42:49 +0000 Subject: [PATCH 03/59] chore(deps): lock file maintenance --- poetry.lock | 200 +++++++++++++++++++++++++++++----------------------- 1 file changed, 110 insertions(+), 90 deletions(-) diff --git a/poetry.lock b/poetry.lock index 3e2121427..4a87beda4 100644 --- a/poetry.lock +++ b/poetry.lock @@ -81,22 +81,22 @@ files = [ [[package]] name = "attrs" -version = "23.2.0" +version = "24.1.0" description = "Classes Without Boilerplate" optional = false python-versions = ">=3.7" files = [ - {file = "attrs-23.2.0-py3-none-any.whl", hash = "sha256:99b87a485a5820b23b879f04c2305b44b951b502fd64be915879d77a7e8fc6f1"}, - {file = "attrs-23.2.0.tar.gz", hash = "sha256:935dc3b529c262f6cf76e50877d35a4bd3c1de194fd41f47a2b7ae8f19971f30"}, + {file = "attrs-24.1.0-py3-none-any.whl", hash = "sha256:377b47448cb61fea38533f671fba0d0f8a96fd58facd4dc518e3dac9dbea0905"}, + {file = "attrs-24.1.0.tar.gz", hash = "sha256:adbdec84af72d38be7628e353a09b6a6790d15cd71819f6e9d7b0faa8a125745"}, ] [package.extras] -cov = ["attrs[tests]", "coverage[toml] (>=5.3)"] -dev = ["attrs[tests]", "pre-commit"] -docs = ["furo", "myst-parser", "sphinx", "sphinx-notfound-page", "sphinxcontrib-towncrier", "towncrier", "zope-interface"] -tests = ["attrs[tests-no-zope]", "zope-interface"] -tests-mypy = ["mypy (>=1.6)", "pytest-mypy-plugins"] -tests-no-zope = ["attrs[tests-mypy]", "cloudpickle", "hypothesis", "pympler", "pytest (>=4.3.0)", "pytest-xdist[psutil]"] +benchmark = ["cloudpickle", "hypothesis", "mypy (>=1.11.1)", "pympler", "pytest (>=4.3.0)", "pytest-codspeed", "pytest-mypy-plugins", "pytest-xdist[psutil]"] +cov = ["cloudpickle", "coverage[toml] (>=5.3)", "hypothesis", "mypy (>=1.11.1)", "pympler", "pytest (>=4.3.0)", "pytest-mypy-plugins", "pytest-xdist[psutil]"] +dev = ["cloudpickle", "hypothesis", "mypy (>=1.11.1)", "pre-commit", "pympler", "pytest (>=4.3.0)", "pytest-mypy-plugins", "pytest-xdist[psutil]"] +docs = ["cogapp", "furo", "myst-parser", "sphinx", "sphinx-notfound-page", "sphinxcontrib-towncrier", "towncrier (<24.7)"] +tests = ["cloudpickle", "hypothesis", "mypy (>=1.11.1)", "pympler", "pytest (>=4.3.0)", "pytest-mypy-plugins", "pytest-xdist[psutil]"] +tests-mypy = ["mypy (>=1.11.1)", "pytest-mypy-plugins"] [[package]] name = "babel" @@ -298,63 +298,83 @@ files = [ [[package]] name = "coverage" -version = "7.6.0" +version = "7.6.1" description = "Code coverage measurement for Python" optional = false python-versions = ">=3.8" files = [ - {file = "coverage-7.6.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:dff044f661f59dace805eedb4a7404c573b6ff0cdba4a524141bc63d7be5c7fd"}, - {file = "coverage-7.6.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:a8659fd33ee9e6ca03950cfdcdf271d645cf681609153f218826dd9805ab585c"}, - {file = "coverage-7.6.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:7792f0ab20df8071d669d929c75c97fecfa6bcab82c10ee4adb91c7a54055463"}, - {file = "coverage-7.6.0-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:d4b3cd1ca7cd73d229487fa5caca9e4bc1f0bca96526b922d61053ea751fe791"}, - {file = "coverage-7.6.0-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e7e128f85c0b419907d1f38e616c4f1e9f1d1b37a7949f44df9a73d5da5cd53c"}, - {file = "coverage-7.6.0-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:a94925102c89247530ae1dab7dc02c690942566f22e189cbd53579b0693c0783"}, - {file = "coverage-7.6.0-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:dcd070b5b585b50e6617e8972f3fbbee786afca71b1936ac06257f7e178f00f6"}, - {file = "coverage-7.6.0-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:d50a252b23b9b4dfeefc1f663c568a221092cbaded20a05a11665d0dbec9b8fb"}, - {file = "coverage-7.6.0-cp310-cp310-win32.whl", hash = "sha256:0e7b27d04131c46e6894f23a4ae186a6a2207209a05df5b6ad4caee6d54a222c"}, - {file = "coverage-7.6.0-cp310-cp310-win_amd64.whl", hash = "sha256:54dece71673b3187c86226c3ca793c5f891f9fc3d8aa183f2e3653da18566169"}, - {file = "coverage-7.6.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:c7b525ab52ce18c57ae232ba6f7010297a87ced82a2383b1afd238849c1ff933"}, - {file = "coverage-7.6.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:4bea27c4269234e06f621f3fac3925f56ff34bc14521484b8f66a580aacc2e7d"}, - {file = "coverage-7.6.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ed8d1d1821ba5fc88d4a4f45387b65de52382fa3ef1f0115a4f7a20cdfab0e94"}, - {file = "coverage-7.6.0-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:01c322ef2bbe15057bc4bf132b525b7e3f7206f071799eb8aa6ad1940bcf5fb1"}, - {file = "coverage-7.6.0-cp311-cp311-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:03cafe82c1b32b770a29fd6de923625ccac3185a54a5e66606da26d105f37dac"}, - {file = "coverage-7.6.0-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:0d1b923fc4a40c5832be4f35a5dab0e5ff89cddf83bb4174499e02ea089daf57"}, - {file = "coverage-7.6.0-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:4b03741e70fb811d1a9a1d75355cf391f274ed85847f4b78e35459899f57af4d"}, - {file = "coverage-7.6.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:a73d18625f6a8a1cbb11eadc1d03929f9510f4131879288e3f7922097a429f63"}, - {file = "coverage-7.6.0-cp311-cp311-win32.whl", hash = "sha256:65fa405b837060db569a61ec368b74688f429b32fa47a8929a7a2f9b47183713"}, - {file = "coverage-7.6.0-cp311-cp311-win_amd64.whl", hash = "sha256:6379688fb4cfa921ae349c76eb1a9ab26b65f32b03d46bb0eed841fd4cb6afb1"}, - {file = "coverage-7.6.0-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:f7db0b6ae1f96ae41afe626095149ecd1b212b424626175a6633c2999eaad45b"}, - {file = "coverage-7.6.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:bbdf9a72403110a3bdae77948b8011f644571311c2fb35ee15f0f10a8fc082e8"}, - {file = "coverage-7.6.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:9cc44bf0315268e253bf563f3560e6c004efe38f76db03a1558274a6e04bf5d5"}, - {file = "coverage-7.6.0-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:da8549d17489cd52f85a9829d0e1d91059359b3c54a26f28bec2c5d369524807"}, - {file = "coverage-7.6.0-cp312-cp312-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0086cd4fc71b7d485ac93ca4239c8f75732c2ae3ba83f6be1c9be59d9e2c6382"}, - {file = "coverage-7.6.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:1fad32ee9b27350687035cb5fdf9145bc9cf0a094a9577d43e909948ebcfa27b"}, - {file = "coverage-7.6.0-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:044a0985a4f25b335882b0966625270a8d9db3d3409ddc49a4eb00b0ef5e8cee"}, - {file = "coverage-7.6.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:76d5f82213aa78098b9b964ea89de4617e70e0d43e97900c2778a50856dac605"}, - {file = "coverage-7.6.0-cp312-cp312-win32.whl", hash = "sha256:3c59105f8d58ce500f348c5b56163a4113a440dad6daa2294b5052a10db866da"}, - {file = "coverage-7.6.0-cp312-cp312-win_amd64.whl", hash = "sha256:ca5d79cfdae420a1d52bf177de4bc2289c321d6c961ae321503b2ca59c17ae67"}, - {file = "coverage-7.6.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:d39bd10f0ae453554798b125d2f39884290c480f56e8a02ba7a6ed552005243b"}, - {file = "coverage-7.6.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:beb08e8508e53a568811016e59f3234d29c2583f6b6e28572f0954a6b4f7e03d"}, - {file = "coverage-7.6.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b2e16f4cd2bc4d88ba30ca2d3bbf2f21f00f382cf4e1ce3b1ddc96c634bc48ca"}, - {file = "coverage-7.6.0-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:6616d1c9bf1e3faea78711ee42a8b972367d82ceae233ec0ac61cc7fec09fa6b"}, - {file = "coverage-7.6.0-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ad4567d6c334c46046d1c4c20024de2a1c3abc626817ae21ae3da600f5779b44"}, - {file = "coverage-7.6.0-cp38-cp38-musllinux_1_2_aarch64.whl", hash = "sha256:d17c6a415d68cfe1091d3296ba5749d3d8696e42c37fca5d4860c5bf7b729f03"}, - {file = "coverage-7.6.0-cp38-cp38-musllinux_1_2_i686.whl", hash = "sha256:9146579352d7b5f6412735d0f203bbd8d00113a680b66565e205bc605ef81bc6"}, - {file = "coverage-7.6.0-cp38-cp38-musllinux_1_2_x86_64.whl", hash = "sha256:cdab02a0a941af190df8782aafc591ef3ad08824f97850b015c8c6a8b3877b0b"}, - {file = "coverage-7.6.0-cp38-cp38-win32.whl", hash = "sha256:df423f351b162a702c053d5dddc0fc0ef9a9e27ea3f449781ace5f906b664428"}, - {file = "coverage-7.6.0-cp38-cp38-win_amd64.whl", hash = "sha256:f2501d60d7497fd55e391f423f965bbe9e650e9ffc3c627d5f0ac516026000b8"}, - {file = "coverage-7.6.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:7221f9ac9dad9492cecab6f676b3eaf9185141539d5c9689d13fd6b0d7de840c"}, - {file = "coverage-7.6.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:ddaaa91bfc4477d2871442bbf30a125e8fe6b05da8a0015507bfbf4718228ab2"}, - {file = "coverage-7.6.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c4cbe651f3904e28f3a55d6f371203049034b4ddbce65a54527a3f189ca3b390"}, - {file = "coverage-7.6.0-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:831b476d79408ab6ccfadaaf199906c833f02fdb32c9ab907b1d4aa0713cfa3b"}, - {file = "coverage-7.6.0-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:46c3d091059ad0b9c59d1034de74a7f36dcfa7f6d3bde782c49deb42438f2450"}, - {file = "coverage-7.6.0-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:4d5fae0a22dc86259dee66f2cc6c1d3e490c4a1214d7daa2a93d07491c5c04b6"}, - {file = "coverage-7.6.0-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:07ed352205574aad067482e53dd606926afebcb5590653121063fbf4e2175166"}, - {file = "coverage-7.6.0-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:49c76cdfa13015c4560702574bad67f0e15ca5a2872c6a125f6327ead2b731dd"}, - {file = "coverage-7.6.0-cp39-cp39-win32.whl", hash = "sha256:482855914928c8175735a2a59c8dc5806cf7d8f032e4820d52e845d1f731dca2"}, - {file = "coverage-7.6.0-cp39-cp39-win_amd64.whl", hash = "sha256:543ef9179bc55edfd895154a51792b01c017c87af0ebaae092720152e19e42ca"}, - {file = "coverage-7.6.0-pp38.pp39.pp310-none-any.whl", hash = "sha256:6fe885135c8a479d3e37a7aae61cbd3a0fb2deccb4dda3c25f92a49189f766d6"}, - {file = "coverage-7.6.0.tar.gz", hash = "sha256:289cc803fa1dc901f84701ac10c9ee873619320f2f9aff38794db4a4a0268d51"}, + {file = "coverage-7.6.1-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:b06079abebbc0e89e6163b8e8f0e16270124c154dc6e4a47b413dd538859af16"}, + {file = "coverage-7.6.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:cf4b19715bccd7ee27b6b120e7e9dd56037b9c0681dcc1adc9ba9db3d417fa36"}, + {file = "coverage-7.6.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e61c0abb4c85b095a784ef23fdd4aede7a2628478e7baba7c5e3deba61070a02"}, + {file = "coverage-7.6.1-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:fd21f6ae3f08b41004dfb433fa895d858f3f5979e7762d052b12aef444e29afc"}, + {file = "coverage-7.6.1-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8f59d57baca39b32db42b83b2a7ba6f47ad9c394ec2076b084c3f029b7afca23"}, + {file = "coverage-7.6.1-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:a1ac0ae2b8bd743b88ed0502544847c3053d7171a3cff9228af618a068ed9c34"}, + {file = "coverage-7.6.1-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:e6a08c0be454c3b3beb105c0596ebdc2371fab6bb90c0c0297f4e58fd7e1012c"}, + {file = "coverage-7.6.1-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:f5796e664fe802da4f57a168c85359a8fbf3eab5e55cd4e4569fbacecc903959"}, + {file = "coverage-7.6.1-cp310-cp310-win32.whl", hash = "sha256:7bb65125fcbef8d989fa1dd0e8a060999497629ca5b0efbca209588a73356232"}, + {file = "coverage-7.6.1-cp310-cp310-win_amd64.whl", hash = "sha256:3115a95daa9bdba70aea750db7b96b37259a81a709223c8448fa97727d546fe0"}, + {file = "coverage-7.6.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:7dea0889685db8550f839fa202744652e87c60015029ce3f60e006f8c4462c93"}, + {file = "coverage-7.6.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:ed37bd3c3b063412f7620464a9ac1314d33100329f39799255fb8d3027da50d3"}, + {file = "coverage-7.6.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d85f5e9a5f8b73e2350097c3756ef7e785f55bd71205defa0bfdaf96c31616ff"}, + {file = "coverage-7.6.1-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:9bc572be474cafb617672c43fe989d6e48d3c83af02ce8de73fff1c6bb3c198d"}, + {file = "coverage-7.6.1-cp311-cp311-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0c0420b573964c760df9e9e86d1a9a622d0d27f417e1a949a8a66dd7bcee7bc6"}, + {file = "coverage-7.6.1-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:1f4aa8219db826ce6be7099d559f8ec311549bfc4046f7f9fe9b5cea5c581c56"}, + {file = "coverage-7.6.1-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:fc5a77d0c516700ebad189b587de289a20a78324bc54baee03dd486f0855d234"}, + {file = "coverage-7.6.1-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:b48f312cca9621272ae49008c7f613337c53fadca647d6384cc129d2996d1133"}, + {file = "coverage-7.6.1-cp311-cp311-win32.whl", hash = "sha256:1125ca0e5fd475cbbba3bb67ae20bd2c23a98fac4e32412883f9bcbaa81c314c"}, + {file = "coverage-7.6.1-cp311-cp311-win_amd64.whl", hash = "sha256:8ae539519c4c040c5ffd0632784e21b2f03fc1340752af711f33e5be83a9d6c6"}, + {file = "coverage-7.6.1-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:95cae0efeb032af8458fc27d191f85d1717b1d4e49f7cb226cf526ff28179778"}, + {file = "coverage-7.6.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:5621a9175cf9d0b0c84c2ef2b12e9f5f5071357c4d2ea6ca1cf01814f45d2391"}, + {file = "coverage-7.6.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:260933720fdcd75340e7dbe9060655aff3af1f0c5d20f46b57f262ab6c86a5e8"}, + {file = "coverage-7.6.1-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:07e2ca0ad381b91350c0ed49d52699b625aab2b44b65e1b4e02fa9df0e92ad2d"}, + {file = "coverage-7.6.1-cp312-cp312-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c44fee9975f04b33331cb8eb272827111efc8930cfd582e0320613263ca849ca"}, + {file = "coverage-7.6.1-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:877abb17e6339d96bf08e7a622d05095e72b71f8afd8a9fefc82cf30ed944163"}, + {file = "coverage-7.6.1-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:3e0cadcf6733c09154b461f1ca72d5416635e5e4ec4e536192180d34ec160f8a"}, + {file = "coverage-7.6.1-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:c3c02d12f837d9683e5ab2f3d9844dc57655b92c74e286c262e0fc54213c216d"}, + {file = "coverage-7.6.1-cp312-cp312-win32.whl", hash = "sha256:e05882b70b87a18d937ca6768ff33cc3f72847cbc4de4491c8e73880766718e5"}, + {file = "coverage-7.6.1-cp312-cp312-win_amd64.whl", hash = "sha256:b5d7b556859dd85f3a541db6a4e0167b86e7273e1cdc973e5b175166bb634fdb"}, + {file = "coverage-7.6.1-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:a4acd025ecc06185ba2b801f2de85546e0b8ac787cf9d3b06e7e2a69f925b106"}, + {file = "coverage-7.6.1-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:a6d3adcf24b624a7b778533480e32434a39ad8fa30c315208f6d3e5542aeb6e9"}, + {file = "coverage-7.6.1-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d0c212c49b6c10e6951362f7c6df3329f04c2b1c28499563d4035d964ab8e08c"}, + {file = "coverage-7.6.1-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:6e81d7a3e58882450ec4186ca59a3f20a5d4440f25b1cff6f0902ad890e6748a"}, + {file = "coverage-7.6.1-cp313-cp313-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:78b260de9790fd81e69401c2dc8b17da47c8038176a79092a89cb2b7d945d060"}, + {file = "coverage-7.6.1-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:a78d169acd38300060b28d600344a803628c3fd585c912cacc9ea8790fe96862"}, + {file = "coverage-7.6.1-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:2c09f4ce52cb99dd7505cd0fc8e0e37c77b87f46bc9c1eb03fe3bc9991085388"}, + {file = "coverage-7.6.1-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:6878ef48d4227aace338d88c48738a4258213cd7b74fd9a3d4d7582bb1d8a155"}, + {file = "coverage-7.6.1-cp313-cp313-win32.whl", hash = "sha256:44df346d5215a8c0e360307d46ffaabe0f5d3502c8a1cefd700b34baf31d411a"}, + {file = "coverage-7.6.1-cp313-cp313-win_amd64.whl", hash = "sha256:8284cf8c0dd272a247bc154eb6c95548722dce90d098c17a883ed36e67cdb129"}, + {file = "coverage-7.6.1-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:d3296782ca4eab572a1a4eca686d8bfb00226300dcefdf43faa25b5242ab8a3e"}, + {file = "coverage-7.6.1-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:502753043567491d3ff6d08629270127e0c31d4184c4c8d98f92c26f65019962"}, + {file = "coverage-7.6.1-cp313-cp313t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6a89ecca80709d4076b95f89f308544ec8f7b4727e8a547913a35f16717856cb"}, + {file = "coverage-7.6.1-cp313-cp313t-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:a318d68e92e80af8b00fa99609796fdbcdfef3629c77c6283566c6f02c6d6704"}, + {file = "coverage-7.6.1-cp313-cp313t-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:13b0a73a0896988f053e4fbb7de6d93388e6dd292b0d87ee51d106f2c11b465b"}, + {file = "coverage-7.6.1-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:4421712dbfc5562150f7554f13dde997a2e932a6b5f352edcce948a815efee6f"}, + {file = "coverage-7.6.1-cp313-cp313t-musllinux_1_2_i686.whl", hash = "sha256:166811d20dfea725e2e4baa71fffd6c968a958577848d2131f39b60043400223"}, + {file = "coverage-7.6.1-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:225667980479a17db1048cb2bf8bfb39b8e5be8f164b8f6628b64f78a72cf9d3"}, + {file = "coverage-7.6.1-cp313-cp313t-win32.whl", hash = "sha256:170d444ab405852903b7d04ea9ae9b98f98ab6d7e63e1115e82620807519797f"}, + {file = "coverage-7.6.1-cp313-cp313t-win_amd64.whl", hash = "sha256:b9f222de8cded79c49bf184bdbc06630d4c58eec9459b939b4a690c82ed05657"}, + {file = "coverage-7.6.1-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:6db04803b6c7291985a761004e9060b2bca08da6d04f26a7f2294b8623a0c1a0"}, + {file = "coverage-7.6.1-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:f1adfc8ac319e1a348af294106bc6a8458a0f1633cc62a1446aebc30c5fa186a"}, + {file = "coverage-7.6.1-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a95324a9de9650a729239daea117df21f4b9868ce32e63f8b650ebe6cef5595b"}, + {file = "coverage-7.6.1-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:b43c03669dc4618ec25270b06ecd3ee4fa94c7f9b3c14bae6571ca00ef98b0d3"}, + {file = "coverage-7.6.1-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8929543a7192c13d177b770008bc4e8119f2e1f881d563fc6b6305d2d0ebe9de"}, + {file = "coverage-7.6.1-cp38-cp38-musllinux_1_2_aarch64.whl", hash = "sha256:a09ece4a69cf399510c8ab25e0950d9cf2b42f7b3cb0374f95d2e2ff594478a6"}, + {file = "coverage-7.6.1-cp38-cp38-musllinux_1_2_i686.whl", hash = "sha256:9054a0754de38d9dbd01a46621636689124d666bad1936d76c0341f7d71bf569"}, + {file = "coverage-7.6.1-cp38-cp38-musllinux_1_2_x86_64.whl", hash = "sha256:0dbde0f4aa9a16fa4d754356a8f2e36296ff4d83994b2c9d8398aa32f222f989"}, + {file = "coverage-7.6.1-cp38-cp38-win32.whl", hash = "sha256:da511e6ad4f7323ee5702e6633085fb76c2f893aaf8ce4c51a0ba4fc07580ea7"}, + {file = "coverage-7.6.1-cp38-cp38-win_amd64.whl", hash = "sha256:3f1156e3e8f2872197af3840d8ad307a9dd18e615dc64d9ee41696f287c57ad8"}, + {file = "coverage-7.6.1-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:abd5fd0db5f4dc9289408aaf34908072f805ff7792632250dcb36dc591d24255"}, + {file = "coverage-7.6.1-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:547f45fa1a93154bd82050a7f3cddbc1a7a4dd2a9bf5cb7d06f4ae29fe94eaf8"}, + {file = "coverage-7.6.1-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:645786266c8f18a931b65bfcefdbf6952dd0dea98feee39bd188607a9d307ed2"}, + {file = "coverage-7.6.1-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:9e0b2df163b8ed01d515807af24f63de04bebcecbd6c3bfeff88385789fdf75a"}, + {file = "coverage-7.6.1-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:609b06f178fe8e9f89ef676532760ec0b4deea15e9969bf754b37f7c40326dbc"}, + {file = "coverage-7.6.1-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:702855feff378050ae4f741045e19a32d57d19f3e0676d589df0575008ea5004"}, + {file = "coverage-7.6.1-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:2bdb062ea438f22d99cba0d7829c2ef0af1d768d1e4a4f528087224c90b132cb"}, + {file = "coverage-7.6.1-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:9c56863d44bd1c4fe2abb8a4d6f5371d197f1ac0ebdee542f07f35895fc07f36"}, + {file = "coverage-7.6.1-cp39-cp39-win32.whl", hash = "sha256:6e2cd258d7d927d09493c8df1ce9174ad01b381d4729a9d8d4e38670ca24774c"}, + {file = "coverage-7.6.1-cp39-cp39-win_amd64.whl", hash = "sha256:06a737c882bd26d0d6ee7269b20b12f14a8704807a01056c80bb881a4b2ce6ca"}, + {file = "coverage-7.6.1-pp38.pp39.pp310-none-any.whl", hash = "sha256:e9a6e0eb86070e8ccaedfbd9d38fec54864f3125ab95419970575b42af7541df"}, + {file = "coverage-7.6.1.tar.gz", hash = "sha256:953510dfb7b12ab69d20135a0662397f077c59b1e6379a768e97c59d852ee51d"}, ] [package.dependencies] @@ -796,38 +816,38 @@ pg = ["psycopg2-binary"] [[package]] name = "mypy" -version = "1.11.0" +version = "1.11.1" description = "Optional static typing for Python" optional = false python-versions = ">=3.8" files = [ - {file = "mypy-1.11.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:a3824187c99b893f90c845bab405a585d1ced4ff55421fdf5c84cb7710995229"}, - {file = "mypy-1.11.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:96f8dbc2c85046c81bcddc246232d500ad729cb720da4e20fce3b542cab91287"}, - {file = "mypy-1.11.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:1a5d8d8dd8613a3e2be3eae829ee891b6b2de6302f24766ff06cb2875f5be9c6"}, - {file = "mypy-1.11.0-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:72596a79bbfb195fd41405cffa18210af3811beb91ff946dbcb7368240eed6be"}, - {file = "mypy-1.11.0-cp310-cp310-win_amd64.whl", hash = "sha256:35ce88b8ed3a759634cb4eb646d002c4cef0a38f20565ee82b5023558eb90c00"}, - {file = "mypy-1.11.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:98790025861cb2c3db8c2f5ad10fc8c336ed2a55f4daf1b8b3f877826b6ff2eb"}, - {file = "mypy-1.11.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:25bcfa75b9b5a5f8d67147a54ea97ed63a653995a82798221cca2a315c0238c1"}, - {file = "mypy-1.11.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:0bea2a0e71c2a375c9fa0ede3d98324214d67b3cbbfcbd55ac8f750f85a414e3"}, - {file = "mypy-1.11.0-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:d2b3d36baac48e40e3064d2901f2fbd2a2d6880ec6ce6358825c85031d7c0d4d"}, - {file = "mypy-1.11.0-cp311-cp311-win_amd64.whl", hash = "sha256:d8e2e43977f0e09f149ea69fd0556623919f816764e26d74da0c8a7b48f3e18a"}, - {file = "mypy-1.11.0-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:1d44c1e44a8be986b54b09f15f2c1a66368eb43861b4e82573026e04c48a9e20"}, - {file = "mypy-1.11.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:cea3d0fb69637944dd321f41bc896e11d0fb0b0aa531d887a6da70f6e7473aba"}, - {file = "mypy-1.11.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:a83ec98ae12d51c252be61521aa5731f5512231d0b738b4cb2498344f0b840cd"}, - {file = "mypy-1.11.0-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:c7b73a856522417beb78e0fb6d33ef89474e7a622db2653bc1285af36e2e3e3d"}, - {file = "mypy-1.11.0-cp312-cp312-win_amd64.whl", hash = "sha256:f2268d9fcd9686b61ab64f077be7ffbc6fbcdfb4103e5dd0cc5eaab53a8886c2"}, - {file = "mypy-1.11.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:940bfff7283c267ae6522ef926a7887305945f716a7704d3344d6d07f02df850"}, - {file = "mypy-1.11.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:14f9294528b5f5cf96c721f231c9f5b2733164e02c1c018ed1a0eff8a18005ac"}, - {file = "mypy-1.11.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:d7b54c27783991399046837df5c7c9d325d921394757d09dbcbf96aee4649fe9"}, - {file = "mypy-1.11.0-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:65f190a6349dec29c8d1a1cd4aa71284177aee5949e0502e6379b42873eddbe7"}, - {file = "mypy-1.11.0-cp38-cp38-win_amd64.whl", hash = "sha256:dbe286303241fea8c2ea5466f6e0e6a046a135a7e7609167b07fd4e7baf151bf"}, - {file = "mypy-1.11.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:104e9c1620c2675420abd1f6c44bab7dd33cc85aea751c985006e83dcd001095"}, - {file = "mypy-1.11.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:f006e955718ecd8d159cee9932b64fba8f86ee6f7728ca3ac66c3a54b0062abe"}, - {file = "mypy-1.11.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:becc9111ca572b04e7e77131bc708480cc88a911adf3d0239f974c034b78085c"}, - {file = "mypy-1.11.0-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:6801319fe76c3f3a3833f2b5af7bd2c17bb93c00026a2a1b924e6762f5b19e13"}, - {file = "mypy-1.11.0-cp39-cp39-win_amd64.whl", hash = "sha256:c1a184c64521dc549324ec6ef7cbaa6b351912be9cb5edb803c2808a0d7e85ac"}, - {file = "mypy-1.11.0-py3-none-any.whl", hash = "sha256:56913ec8c7638b0091ef4da6fcc9136896914a9d60d54670a75880c3e5b99ace"}, - {file = "mypy-1.11.0.tar.gz", hash = "sha256:93743608c7348772fdc717af4aeee1997293a1ad04bc0ea6efa15bf65385c538"}, + {file = "mypy-1.11.1-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:a32fc80b63de4b5b3e65f4be82b4cfa362a46702672aa6a0f443b4689af7008c"}, + {file = "mypy-1.11.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:c1952f5ea8a5a959b05ed5f16452fddadbaae48b5d39235ab4c3fc444d5fd411"}, + {file = "mypy-1.11.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:e1e30dc3bfa4e157e53c1d17a0dad20f89dc433393e7702b813c10e200843b03"}, + {file = "mypy-1.11.1-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:2c63350af88f43a66d3dfeeeb8d77af34a4f07d760b9eb3a8697f0386c7590b4"}, + {file = "mypy-1.11.1-cp310-cp310-win_amd64.whl", hash = "sha256:a831671bad47186603872a3abc19634f3011d7f83b083762c942442d51c58d58"}, + {file = "mypy-1.11.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:7b6343d338390bb946d449677726edf60102a1c96079b4f002dedff375953fc5"}, + {file = "mypy-1.11.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:e4fe9f4e5e521b458d8feb52547f4bade7ef8c93238dfb5bbc790d9ff2d770ca"}, + {file = "mypy-1.11.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:886c9dbecc87b9516eff294541bf7f3655722bf22bb898ee06985cd7269898de"}, + {file = "mypy-1.11.1-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:fca4a60e1dd9fd0193ae0067eaeeb962f2d79e0d9f0f66223a0682f26ffcc809"}, + {file = "mypy-1.11.1-cp311-cp311-win_amd64.whl", hash = "sha256:0bd53faf56de9643336aeea1c925012837432b5faf1701ccca7fde70166ccf72"}, + {file = "mypy-1.11.1-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:f39918a50f74dc5969807dcfaecafa804fa7f90c9d60506835036cc1bc891dc8"}, + {file = "mypy-1.11.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:0bc71d1fb27a428139dd78621953effe0d208aed9857cb08d002280b0422003a"}, + {file = "mypy-1.11.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:b868d3bcff720dd7217c383474008ddabaf048fad8d78ed948bb4b624870a417"}, + {file = "mypy-1.11.1-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:a707ec1527ffcdd1c784d0924bf5cb15cd7f22683b919668a04d2b9c34549d2e"}, + {file = "mypy-1.11.1-cp312-cp312-win_amd64.whl", hash = "sha256:64f4a90e3ea07f590c5bcf9029035cf0efeae5ba8be511a8caada1a4893f5525"}, + {file = "mypy-1.11.1-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:749fd3213916f1751fff995fccf20c6195cae941dc968f3aaadf9bb4e430e5a2"}, + {file = "mypy-1.11.1-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:b639dce63a0b19085213ec5fdd8cffd1d81988f47a2dec7100e93564f3e8fb3b"}, + {file = "mypy-1.11.1-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:4c956b49c5d865394d62941b109728c5c596a415e9c5b2be663dd26a1ff07bc0"}, + {file = "mypy-1.11.1-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:45df906e8b6804ef4b666af29a87ad9f5921aad091c79cc38e12198e220beabd"}, + {file = "mypy-1.11.1-cp38-cp38-win_amd64.whl", hash = "sha256:d44be7551689d9d47b7abc27c71257adfdb53f03880841a5db15ddb22dc63edb"}, + {file = "mypy-1.11.1-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:2684d3f693073ab89d76da8e3921883019ea8a3ec20fa5d8ecca6a2db4c54bbe"}, + {file = "mypy-1.11.1-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:79c07eb282cb457473add5052b63925e5cc97dfab9812ee65a7c7ab5e3cb551c"}, + {file = "mypy-1.11.1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:11965c2f571ded6239977b14deebd3f4c3abd9a92398712d6da3a772974fad69"}, + {file = "mypy-1.11.1-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:a2b43895a0f8154df6519706d9bca8280cda52d3d9d1514b2d9c3e26792a0b74"}, + {file = "mypy-1.11.1-cp39-cp39-win_amd64.whl", hash = "sha256:1a81cf05975fd61aec5ae16501a091cfb9f605dc3e3c878c0da32f250b74760b"}, + {file = "mypy-1.11.1-py3-none-any.whl", hash = "sha256:0624bdb940255d2dd24e829d99a13cfeb72e4e9031f9492148f410ed30bcab54"}, + {file = "mypy-1.11.1.tar.gz", hash = "sha256:f404a0b069709f18bbdb702eb3dcfe51910602995de00bd39cea3050b5772d08"}, ] [package.dependencies] From 3001234548d6be433f5e0620790bdb184f20ee7e Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Mon, 5 Aug 2024 00:43:00 +0000 Subject: [PATCH 04/59] [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci --- .pre-commit-config.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 14c7652b8..0c513f719 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -36,7 +36,7 @@ repos: - aiopg==1.4.0 - anyio==4.4.0 - asgiref==3.8.1 - - attrs==23.2.0 + - attrs==24.1.0 - contextlib2==21.6.0 - croniter==3.0.3 - django-stubs==5.0.4 From 296f0a74381ef1455c49113d97fe4ef11a0c58ab Mon Sep 17 00:00:00 2001 From: Katlyn Lorimer Date: Wed, 7 Aug 2024 09:59:47 -0800 Subject: [PATCH 05/59] feat: add cancelled and aborted jobs to delete_old_jobs --- procrastinate/builtin_tasks.py | 16 ++++++++++++++-- procrastinate/manager.py | 24 +++++++++++++++++------- 2 files changed, 31 insertions(+), 9 deletions(-) diff --git a/procrastinate/builtin_tasks.py b/procrastinate/builtin_tasks.py index f419558f9..c31afd5ef 100644 --- a/procrastinate/builtin_tasks.py +++ b/procrastinate/builtin_tasks.py @@ -12,6 +12,8 @@ async def remove_old_jobs( max_hours: int, queue: str | None = None, remove_error: bool | None = False, + remove_cancelled: bool | None = False, + remove_aborted: bool | None = False, ) -> None: """ This task cleans your database by removing old jobs. Note that jobs and linked @@ -24,11 +26,21 @@ async def remove_old_jobs( queue : The name of the queue in which jobs will be deleted. If not specified, the task will delete jobs from all queues. - remove_error : + remove_error : ``Optional[bool]`` By default only successful jobs will be removed. When this parameter is True failed jobs will also be deleted. + remove_cancelled : ``Optional[bool]`` + By default only successful jobs will be removed. When this parameter is True + cancelled jobs will also be deleted. + remove_aborted : ``Optional[bool]`` + By default only successful jobs will be removed. When this parameter is True + aborted jobs will also be deleted. """ assert context.app await context.app.job_manager.delete_old_jobs( - nb_hours=max_hours, queue=queue, include_error=remove_error + nb_hours=max_hours, + queue=queue, + include_error=remove_error, + include_cancelled=remove_cancelled, + include_aborted=remove_aborted, ) diff --git a/procrastinate/manager.py b/procrastinate/manager.py index 9657e4528..129b50962 100644 --- a/procrastinate/manager.py +++ b/procrastinate/manager.py @@ -181,9 +181,13 @@ async def delete_old_jobs( nb_hours: int, queue: str | None = None, include_error: bool | None = False, + include_cancelled: bool | None = False, + include_aborted: bool | None = False, ) -> None: """ - Delete jobs that have reached a final state (``succeeded`` or ``failed``). + Delete jobs that have reached a final state (``succeeded``, ``failed``, + ``cancelled``, or ``aborted``). By default, only considers jobs that have + succeeded. Parameters ---------- @@ -192,14 +196,20 @@ async def delete_old_jobs( queue : ``Optional[str]`` Filter by job queue name include_error : ``Optional[bool]`` - If ``True``, only succeeded jobs will be considered. If ``False``, both - succeeded and failed jobs will be considered, ``False`` by default + If ``True``, also consider errored jobs. ``False`` by default + include_cancelled : ``Optional[bool]`` + If ``True``, also consider cancelled jobs. ``False`` by default. + include_aborted : ``Optional[bool]`` + If ``True``, also consider aborted jobs. ``False`` by default. """ # We only consider finished jobs by default - if not include_error: - statuses = [jobs.Status.SUCCEEDED.value] - else: - statuses = [jobs.Status.SUCCEEDED.value, jobs.Status.FAILED.value] + statuses = [jobs.Status.SUCCEEDED.value] + if include_error: + statuses.append(jobs.Status.FAILED.value) + if include_cancelled: + statuses.append(jobs.Status.CANCELLED.value) + if include_aborted: + statuses.append(jobs.Status.ABORTED.value) await self.connector.execute_query_async( query=sql.queries["delete_old_jobs"], From 1b5a651e802a6627e5c623a9ca5ca736163e1b11 Mon Sep 17 00:00:00 2001 From: Katlyn Lorimer Date: Wed, 7 Aug 2024 10:04:01 -0800 Subject: [PATCH 06/59] test: add cancelled and aborted jobs to remove_old_jobs --- tests/unit/test_builtin_tasks.py | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/tests/unit/test_builtin_tasks.py b/tests/unit/test_builtin_tasks.py index 7c577b478..8849f9878 100644 --- a/tests/unit/test_builtin_tasks.py +++ b/tests/unit/test_builtin_tasks.py @@ -5,11 +5,20 @@ async def test_remove_old_jobs(app): await builtin_tasks.remove_old_jobs( - job_context.JobContext(app=app), max_hours=2, queue="queue_a", remove_error=True + job_context.JobContext(app=app), + max_hours=2, + queue="queue_a", + remove_error=True, + remove_cancelled=True, + remove_aborted=True, ) assert app.connector.queries == [ ( "delete_old_jobs", - {"nb_hours": 2, "queue": "queue_a", "statuses": ["succeeded", "failed"]}, + { + "nb_hours": 2, + "queue": "queue_a", + "statuses": ["succeeded", "failed", "cancelled", "aborted"], + }, ) ] From 9970d03385c91806fa41bd55c14e085f6ff63ea3 Mon Sep 17 00:00:00 2001 From: Katlyn Lorimer Date: Wed, 7 Aug 2024 10:04:43 -0800 Subject: [PATCH 07/59] docs: add removing cancelled and aborted jobs to example --- docs/howto/production/delete_finished_jobs.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/docs/howto/production/delete_finished_jobs.md b/docs/howto/production/delete_finished_jobs.md index e47ecbfb8..14a7502a7 100644 --- a/docs/howto/production/delete_finished_jobs.md +++ b/docs/howto/production/delete_finished_jobs.md @@ -88,6 +88,8 @@ async def remove_old_jobs(context, timestamp): context, max_hours=72, remove_error=True, + remove_cancelled=True, + remove_aborted=True, ) ``` From 97dc67a0f6351b3c6f5295afd6907ec3ae3ce160 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Wed, 7 Aug 2024 19:24:03 +0000 Subject: [PATCH 08/59] chore(deps): update dependency django to v4.2.15 [security] --- poetry.lock | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/poetry.lock b/poetry.lock index 4a87beda4..b777fe6ae 100644 --- a/poetry.lock +++ b/poetry.lock @@ -400,13 +400,13 @@ pytz = ">2021.1" [[package]] name = "django" -version = "4.2.14" +version = "4.2.15" description = "A high-level Python web framework that encourages rapid development and clean, pragmatic design." optional = false python-versions = ">=3.8" files = [ - {file = "Django-4.2.14-py3-none-any.whl", hash = "sha256:3ec32bc2c616ab02834b9cac93143a7dc1cdcd5b822d78ac95fc20a38c534240"}, - {file = "Django-4.2.14.tar.gz", hash = "sha256:fc6919875a6226c7ffcae1a7d51e0f2ceaf6f160393180818f6c95f51b1e7b96"}, + {file = "Django-4.2.15-py3-none-any.whl", hash = "sha256:61ee4a130efb8c451ef3467c67ca99fdce400fedd768634efc86a68c18d80d30"}, + {file = "Django-4.2.15.tar.gz", hash = "sha256:c77f926b81129493961e19c0e02188f8d07c112a1162df69bfab178ae447f94a"}, ] [package.dependencies] From ff9d24a0e72cc45ce8ee3997129ba50e26ea1ef1 Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Wed, 7 Aug 2024 19:24:18 +0000 Subject: [PATCH 09/59] [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci --- .pre-commit-config.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 0c513f719..06add7ab3 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -40,7 +40,7 @@ repos: - contextlib2==21.6.0 - croniter==3.0.3 - django-stubs==5.0.4 - - django==4.2.14 + - django==4.2.15 - importlib-metadata==8.2.0 - importlib-resources==6.4.0 - psycopg2-binary==2.9.9 From ba1060d7160f148724cd715e80c5bbf21cc5809e Mon Sep 17 00:00:00 2001 From: Nicolas Delaby Date: Thu, 1 Aug 2024 17:37:48 +0200 Subject: [PATCH 10/59] Make django Admin interface support slightly better UX wise - Display some fields on table view ["task_name", "queue_name", "attempts", "status"] - Allow to filter on status - Display Events inline --- procrastinate/contrib/django/admin.py | 74 +++++++++++++++++-- .../0030_alter_procrastinateevent_options.py | 17 +++++ procrastinate/contrib/django/models.py | 1 + .../contrib/django/templates/summary.html | 1 + 4 files changed, 85 insertions(+), 8 deletions(-) create mode 100644 procrastinate/contrib/django/migrations/0030_alter_procrastinateevent_options.py create mode 100644 procrastinate/contrib/django/templates/summary.html diff --git a/procrastinate/contrib/django/admin.py b/procrastinate/contrib/django/admin.py index 6d81bddc6..f067c0221 100644 --- a/procrastinate/contrib/django/admin.py +++ b/procrastinate/contrib/django/admin.py @@ -1,11 +1,56 @@ from __future__ import annotations from django.contrib import admin +from django.template.loader import render_to_string +from django.utils.safestring import mark_safe from . import models +JOB_STATUS_EMOJI_MAPPING = { + "todo": "🗓️", + "doing": "🚂", + "failed": "❌", + "succeeded": "✅", + "cancelled": "🤚", + "aborting": "🔌🕑️", + "aborted": "🔌", +} + + +class ProcrastinateEventInline(admin.StackedInline): + model = models.ProcrastinateEvent + + +@admin.register(models.ProcrastinateJob) +class ProcrastinateJobAdmin(admin.ModelAdmin): + fields = [ + "pk", + "short_task_name", + "pretty_args", + "pretty_status", + "queue_name", + "lock", + "queueing_lock", + "priority", + "scheduled_at", + "attempts", + "summary", + ] + list_display = [ + "pk", + "short_task_name", + "pretty_args", + "pretty_status", + "queue_name", + "lock", + "queueing_lock", + "priority", + "scheduled_at", + "attempts", + ] + list_filter = ["status"] + inlines = [ProcrastinateEventInline] -class ProcrastinateAdmin(admin.ModelAdmin): def get_readonly_fields( self, request, @@ -26,11 +71,24 @@ def has_add_permission(self, request, obj=None): def has_delete_permission(self, request, obj=None): return False + @admin.display(description="Status") + def pretty_status(self, instance: models.ProcrastinateJob) -> str: + emoji = JOB_STATUS_EMOJI_MAPPING.get(instance.status, "") + return f"{emoji} ({instance.status})" + + @admin.display(description="Task Name") + def short_task_name(self, instance: models.ProcrastinateJob) -> str: + *modules, name = instance.task_name.split(".") + return ".".join(m[0] for m in modules) + f".{name}" + + @admin.display(description="Args") + def pretty_args(self, instance: models.ProcrastinateJob) -> str: + return mark_safe(f"
{instance.args}
") -admin.site.register( - [ - models.ProcrastinateJob, - models.ProcrastinateEvent, - ], - ProcrastinateAdmin, -) + @admin.display(description="Summary") + def summary(self, instance: models.ProcrastinateJob) -> str: + if last_event := instance.procrastinateevent_set.latest(): # type: ignore[attr-defined] + return mark_safe( + render_to_string("summary.html", {"last_event": last_event}).strip() + ) + return "" diff --git a/procrastinate/contrib/django/migrations/0030_alter_procrastinateevent_options.py b/procrastinate/contrib/django/migrations/0030_alter_procrastinateevent_options.py new file mode 100644 index 000000000..7b5f72594 --- /dev/null +++ b/procrastinate/contrib/django/migrations/0030_alter_procrastinateevent_options.py @@ -0,0 +1,17 @@ +# Generated by Django 5.0.8 on 2024-08-08 14:27 + +from django.db import migrations + + +class Migration(migrations.Migration): + + dependencies = [ + ('procrastinate', '0029_add_additional_params_to_retry_job'), + ] + + operations = [ + migrations.AlterModelOptions( + name='procrastinateevent', + options={'get_latest_by': 'at', 'managed': False}, + ), + ] diff --git a/procrastinate/contrib/django/models.py b/procrastinate/contrib/django/models.py index 3dfeb1494..6c00103fb 100644 --- a/procrastinate/contrib/django/models.py +++ b/procrastinate/contrib/django/models.py @@ -108,6 +108,7 @@ class ProcrastinateEvent(ProcrastinateReadOnlyModelMixin, models.Model): class Meta: # type: ignore managed = False db_table = "procrastinate_events" + get_latest_by = "at" class ProcrastinatePeriodicDefer(ProcrastinateReadOnlyModelMixin, models.Model): diff --git a/procrastinate/contrib/django/templates/summary.html b/procrastinate/contrib/django/templates/summary.html new file mode 100644 index 000000000..f0ec3b9df --- /dev/null +++ b/procrastinate/contrib/django/templates/summary.html @@ -0,0 +1 @@ +{{ last_event.type | title }} {{ last_event.at|timesince }} ago From e26003746a350ff689a412ed70b7a1c7cbaeedee Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Thu, 8 Aug 2024 14:28:28 +0000 Subject: [PATCH 11/59] [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci --- .../migrations/0030_alter_procrastinateevent_options.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/procrastinate/contrib/django/migrations/0030_alter_procrastinateevent_options.py b/procrastinate/contrib/django/migrations/0030_alter_procrastinateevent_options.py index 7b5f72594..758c5a43c 100644 --- a/procrastinate/contrib/django/migrations/0030_alter_procrastinateevent_options.py +++ b/procrastinate/contrib/django/migrations/0030_alter_procrastinateevent_options.py @@ -1,17 +1,17 @@ # Generated by Django 5.0.8 on 2024-08-08 14:27 +from __future__ import annotations from django.db import migrations class Migration(migrations.Migration): - dependencies = [ - ('procrastinate', '0029_add_additional_params_to_retry_job'), + ("procrastinate", "0029_add_additional_params_to_retry_job"), ] operations = [ migrations.AlterModelOptions( - name='procrastinateevent', - options={'get_latest_by': 'at', 'managed': False}, + name="procrastinateevent", + options={"get_latest_by": "at", "managed": False}, ), ] From 6086a9602ada49a21cf38e6ca3c61600648224f1 Mon Sep 17 00:00:00 2001 From: Joachim Jablon Date: Thu, 8 Aug 2024 23:35:03 +0200 Subject: [PATCH 12/59] Move summary.html to procrastinate/admin/summary.html to avoid shadowing Also, add many other parts to the summary --- .../procrastinate/admin/summary.html | 48 +++++++++++++++++++ .../contrib/django/templates/summary.html | 1 - 2 files changed, 48 insertions(+), 1 deletion(-) create mode 100644 procrastinate/contrib/django/templates/procrastinate/admin/summary.html delete mode 100644 procrastinate/contrib/django/templates/summary.html diff --git a/procrastinate/contrib/django/templates/procrastinate/admin/summary.html b/procrastinate/contrib/django/templates/procrastinate/admin/summary.html new file mode 100644 index 000000000..733c66b97 --- /dev/null +++ b/procrastinate/contrib/django/templates/procrastinate/admin/summary.html @@ -0,0 +1,48 @@ +
    +
  • + {{ last_event.type | title }} + {{ last_event.at|timesince }} ago +
  • + {% if job.queue_name %} +
  • + Queue: + {{ job.queue_name }} +
  • + {% endif %} + {% if job.lock %} +
  • + Lock: + {{ job.lock }} +
  • + {% endif %} + {% if job.queueing_lock %} +
  • + Queueing lock: + {{ job.queueing_lock }} +
  • + {% endif %} + {% if job.priority != 0 %} +
  • + Priority: + {{ job.priority }} +
  • + {% endif %} + {% if job.scheduled_at %} +
  • + Scheduled: + + {% if job.scheduled_at > now %} + in {{ job.scheduled_at|timeuntil }} + {% else %} + {{ job.scheduled_at|timesince }} ago + {% endif %} + +
  • + {% endif %} + {% if job.attempts > 1 %} +
  • + Attempts: + {{ job.attempts }} +
  • + {% endif %} +
diff --git a/procrastinate/contrib/django/templates/summary.html b/procrastinate/contrib/django/templates/summary.html deleted file mode 100644 index f0ec3b9df..000000000 --- a/procrastinate/contrib/django/templates/summary.html +++ /dev/null @@ -1 +0,0 @@ -{{ last_event.type | title }} {{ last_event.at|timesince }} ago From de8593c5500f205caa2ab9d2decaa178ecb846bb Mon Sep 17 00:00:00 2001 From: Joachim Jablon Date: Thu, 8 Aug 2024 23:36:18 +0200 Subject: [PATCH 13/59] Continue improving the admin with small details --- procrastinate/contrib/django/admin.py | 39 +++++++++++++++++++++------ 1 file changed, 31 insertions(+), 8 deletions(-) diff --git a/procrastinate/contrib/django/admin.py b/procrastinate/contrib/django/admin.py index f067c0221..80576953f 100644 --- a/procrastinate/contrib/django/admin.py +++ b/procrastinate/contrib/django/admin.py @@ -1,7 +1,11 @@ from __future__ import annotations +import json + from django.contrib import admin from django.template.loader import render_to_string +from django.utils import timezone +from django.utils.html import format_html from django.utils.safestring import mark_safe from . import models @@ -34,21 +38,23 @@ class ProcrastinateJobAdmin(admin.ModelAdmin): "priority", "scheduled_at", "attempts", - "summary", ] list_display = [ "pk", "short_task_name", "pretty_args", "pretty_status", + "summary", + ] + list_filter = [ + "status", "queue_name", + "task_name", "lock", "queueing_lock", - "priority", "scheduled_at", - "attempts", + "priority", ] - list_filter = ["status"] inlines = [ProcrastinateEventInline] def get_readonly_fields( @@ -74,21 +80,38 @@ def has_delete_permission(self, request, obj=None): @admin.display(description="Status") def pretty_status(self, instance: models.ProcrastinateJob) -> str: emoji = JOB_STATUS_EMOJI_MAPPING.get(instance.status, "") - return f"{emoji} ({instance.status})" + return f"{emoji} {instance.status.title()}" @admin.display(description="Task Name") def short_task_name(self, instance: models.ProcrastinateJob) -> str: *modules, name = instance.task_name.split(".") - return ".".join(m[0] for m in modules) + f".{name}" + return format_html( + "{name}", + task_name=instance.task_name, + name=".".join(m[0] for m in modules) + f".{name}", + ) @admin.display(description="Args") def pretty_args(self, instance: models.ProcrastinateJob) -> str: - return mark_safe(f"
{instance.args}
") + indent = 2 if len(instance.args) > 1 or len(str(instance.args)) > 30 else None + pretty_json = json.dumps(instance.args, indent=indent) + if len(pretty_json) > 2000: + pretty_json = pretty_json[:2000] + "..." + return format_html( + '
{pretty_json}
', pretty_json=pretty_json + ) @admin.display(description="Summary") def summary(self, instance: models.ProcrastinateJob) -> str: if last_event := instance.procrastinateevent_set.latest(): # type: ignore[attr-defined] return mark_safe( - render_to_string("summary.html", {"last_event": last_event}).strip() + render_to_string( + "procrastinate/admin/summary.html", + { + "last_event": last_event, + "job": instance, + "now": timezone.now(), + }, + ).strip() ) return "" From 97f62488e9d44d9e545dca62b7c10c398307095d Mon Sep 17 00:00:00 2001 From: Joachim Jablon Date: Thu, 8 Aug 2024 23:39:12 +0200 Subject: [PATCH 14/59] Add __str__ to procrastinate models to improve appearance in the admin too --- procrastinate/contrib/django/models.py | 20 +++++++++++++ tests/acceptance/django_settings.py | 6 ++++ .../integration/contrib/django/test_models.py | 28 +++++++++++++++++++ 3 files changed, 54 insertions(+) diff --git a/procrastinate/contrib/django/models.py b/procrastinate/contrib/django/models.py index 6c00103fb..97194b709 100644 --- a/procrastinate/contrib/django/models.py +++ b/procrastinate/contrib/django/models.py @@ -4,6 +4,8 @@ from django.db import models +from procrastinate import jobs + from . import exceptions, settings @@ -85,6 +87,24 @@ class Meta: # type: ignore managed = False db_table = "procrastinate_jobs" + @property + def procrastinate_job(self) -> jobs.Job: + return jobs.Job( + id=self.id, + queue=self.queue_name, + task_name=self.task_name, + task_kwargs=self.args, + priority=self.priority, + lock=self.lock, + status=self.status, + scheduled_at=self.scheduled_at, + attempts=self.attempts, + queueing_lock=self.queueing_lock, + ) + + def __str__(self) -> str: + return self.procrastinate_job.call_string + class ProcrastinateEvent(ProcrastinateReadOnlyModelMixin, models.Model): TYPES = ( diff --git a/tests/acceptance/django_settings.py b/tests/acceptance/django_settings.py index c2b87cb5a..97a4d761c 100644 --- a/tests/acceptance/django_settings.py +++ b/tests/acceptance/django_settings.py @@ -11,6 +11,12 @@ }, } INSTALLED_APPS = [ + "django.contrib.admin", + "django.contrib.auth", + "django.contrib.contenttypes", + "django.contrib.sessions", + "django.contrib.messages", + "django.contrib.staticfiles", "procrastinate.contrib.django", ] USE_TZ = True # To avoid RemovedInDjango50Warning diff --git a/tests/integration/contrib/django/test_models.py b/tests/integration/contrib/django/test_models.py index f3fe8ba4a..022c81017 100644 --- a/tests/integration/contrib/django/test_models.py +++ b/tests/integration/contrib/django/test_models.py @@ -8,6 +8,7 @@ import procrastinate import procrastinate.contrib.django import procrastinate.contrib.django.exceptions +from procrastinate import jobs as jobs_module from procrastinate.contrib.django import models @@ -30,6 +31,33 @@ def test_procrastinate_job(db): } +def test_procrastinate_job__property(db): + job = models.ProcrastinateJob( + id=1, + queue_name="foo", + task_name="test_task", + priority=0, + lock="bar", + args={"a": 1, "b": 2}, + status="todo", + scheduled_at=datetime.datetime(2021, 1, 1, tzinfo=datetime.timezone.utc), + attempts=0, + queueing_lock="baz", + ) + assert job.procrastinate_job == jobs_module.Job( + id=1, + queue="foo", + task_name="test_task", + task_kwargs={"a": 1, "b": 2}, + priority=0, + lock="bar", + status="todo", + scheduled_at=datetime.datetime(2021, 1, 1, tzinfo=datetime.timezone.utc), + attempts=0, + queueing_lock="baz", + ) + + def test_procrastinate_job__no_create(db): with pytest.raises(procrastinate.contrib.django.exceptions.ReadOnlyModel): models.ProcrastinateJob.objects.create(task_name="test_task") From 7a6c2a48677aec10bb77153f775f4edd871e7def Mon Sep 17 00:00:00 2001 From: Joachim Jablon Date: Thu, 8 Aug 2024 23:39:40 +0200 Subject: [PATCH 15/59] Ensure the admin status emojis won't get out of sync with real statuses --- tests/unit/contrib/django/test_admin.py | 8 ++++++++ 1 file changed, 8 insertions(+) create mode 100644 tests/unit/contrib/django/test_admin.py diff --git a/tests/unit/contrib/django/test_admin.py b/tests/unit/contrib/django/test_admin.py new file mode 100644 index 000000000..53b25056c --- /dev/null +++ b/tests/unit/contrib/django/test_admin.py @@ -0,0 +1,8 @@ +from __future__ import annotations + +from procrastinate import jobs +from procrastinate.contrib.django import admin + + +def test_emoji_mapping(): + assert set(admin.JOB_STATUS_EMOJI_MAPPING) == {e.value for e in jobs.Status} From ed99be3afba8518987caf51223570d2e250a9627 Mon Sep 17 00:00:00 2001 From: Joachim Jablon Date: Thu, 8 Aug 2024 23:48:56 +0200 Subject: [PATCH 16/59] Add __str__ for events too --- procrastinate/contrib/django/models.py | 3 +++ 1 file changed, 3 insertions(+) diff --git a/procrastinate/contrib/django/models.py b/procrastinate/contrib/django/models.py index 97194b709..23206d710 100644 --- a/procrastinate/contrib/django/models.py +++ b/procrastinate/contrib/django/models.py @@ -130,6 +130,9 @@ class Meta: # type: ignore db_table = "procrastinate_events" get_latest_by = "at" + def __str__(self) -> str: + return f"Event {self.id} - Job {self.job_id}: {self.type} at {self.at}" # type: ignore + class ProcrastinatePeriodicDefer(ProcrastinateReadOnlyModelMixin, models.Model): id = models.BigAutoField(primary_key=True) From dd45b806c008b8b5d47931b11aa62b25705e18e9 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Sat, 10 Aug 2024 01:01:56 +0000 Subject: [PATCH 17/59] chore(deps): update all dependencies --- .pre-commit-config.yaml | 4 +- poetry.lock | 166 ++++++++++++++++++++-------------------- 2 files changed, 85 insertions(+), 85 deletions(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 06add7ab3..21b6bebef 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -29,7 +29,7 @@ repos: - id: trailing-whitespace - id: mixed-line-ending - repo: https://github.com/RobertCraigie/pyright-python - rev: v1.1.374 + rev: v1.1.375 hooks: - id: pyright additional_dependencies: @@ -49,7 +49,7 @@ repos: - sqlalchemy==2.0.31 - typing-extensions==4.12.2 - repo: https://github.com/astral-sh/ruff-pre-commit - rev: v0.5.6 + rev: v0.5.7 hooks: - id: ruff args: [--fix, --unsafe-fixes] diff --git a/poetry.lock b/poetry.lock index b777fe6ae..e148c3715 100644 --- a/poetry.lock +++ b/poetry.lock @@ -81,13 +81,13 @@ files = [ [[package]] name = "attrs" -version = "24.1.0" +version = "24.2.0" description = "Classes Without Boilerplate" optional = false python-versions = ">=3.7" files = [ - {file = "attrs-24.1.0-py3-none-any.whl", hash = "sha256:377b47448cb61fea38533f671fba0d0f8a96fd58facd4dc518e3dac9dbea0905"}, - {file = "attrs-24.1.0.tar.gz", hash = "sha256:adbdec84af72d38be7628e353a09b6a6790d15cd71819f6e9d7b0faa8a125745"}, + {file = "attrs-24.2.0-py3-none-any.whl", hash = "sha256:81921eb96de3191c8258c199618104dd27ac608d9366f5e35d011eae1867ede2"}, + {file = "attrs-24.2.0.tar.gz", hash = "sha256:5cfb1b9148b5b086569baec03f20d7b6bf3bcacc9a42bebf87ffaaca362f6346"}, ] [package.extras] @@ -471,13 +471,13 @@ files = [ [[package]] name = "dunamai" -version = "1.21.2" +version = "1.22.0" description = "Dynamic version generation" optional = false python-versions = ">=3.5" files = [ - {file = "dunamai-1.21.2-py3-none-any.whl", hash = "sha256:87db76405bf9366f9b4925ff5bb1db191a9a1bd9f9693f81c4d3abb8298be6f0"}, - {file = "dunamai-1.21.2.tar.gz", hash = "sha256:05827fb5f032f5596bfc944b23f613c147e676de118681f3bb1559533d8a65c4"}, + {file = "dunamai-1.22.0-py3-none-any.whl", hash = "sha256:eab3894b31e145bd028a74b13491c57db01986a7510482c9b5fff3b4e53d77b7"}, + {file = "dunamai-1.22.0.tar.gz", hash = "sha256:375a0b21309336f0d8b6bbaea3e038c36f462318c68795166e31f9873fdad676"}, ] [package.dependencies] @@ -499,19 +499,19 @@ test = ["pytest (>=6)"] [[package]] name = "furo" -version = "2024.7.18" +version = "2024.8.6" description = "A clean customisable Sphinx documentation theme." optional = false python-versions = ">=3.8" files = [ - {file = "furo-2024.7.18-py3-none-any.whl", hash = "sha256:b192c7c1f59805494c8ed606d9375fdac6e6ba8178e747e72bc116745fb7e13f"}, - {file = "furo-2024.7.18.tar.gz", hash = "sha256:37b08c5fccc95d46d8712c8be97acd46043963895edde05b0f4f135d58325c83"}, + {file = "furo-2024.8.6-py3-none-any.whl", hash = "sha256:6cd97c58b47813d3619e63e9081169880fbe331f0ca883c871ff1f3f11814f5c"}, + {file = "furo-2024.8.6.tar.gz", hash = "sha256:b63e4cee8abfc3136d3bc03a3d45a76a850bada4d6374d24c1716b0e01394a01"}, ] [package.dependencies] beautifulsoup4 = "*" pygments = ">=2.7" -sphinx = ">=6.0,<8.0" +sphinx = ">=6.0,<9.0" sphinx-basic-ng = ">=1.0.0.beta2" [[package]] @@ -1322,29 +1322,29 @@ use-chardet-on-py3 = ["chardet (>=3.0.2,<6)"] [[package]] name = "ruff" -version = "0.5.6" +version = "0.5.7" description = "An extremely fast Python linter and code formatter, written in Rust." optional = false python-versions = ">=3.7" files = [ - {file = "ruff-0.5.6-py3-none-linux_armv6l.whl", hash = "sha256:a0ef5930799a05522985b9cec8290b185952f3fcd86c1772c3bdbd732667fdcd"}, - {file = "ruff-0.5.6-py3-none-macosx_10_12_x86_64.whl", hash = "sha256:b652dc14f6ef5d1552821e006f747802cc32d98d5509349e168f6bf0ee9f8f42"}, - {file = "ruff-0.5.6-py3-none-macosx_11_0_arm64.whl", hash = "sha256:80521b88d26a45e871f31e4b88938fd87db7011bb961d8afd2664982dfc3641a"}, - {file = "ruff-0.5.6-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d9bc8f328a9f1309ae80e4d392836e7dbc77303b38ed4a7112699e63d3b066ab"}, - {file = "ruff-0.5.6-py3-none-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:4d394940f61f7720ad371ddedf14722ee1d6250fd8d020f5ea5a86e7be217daf"}, - {file = "ruff-0.5.6-py3-none-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:111a99cdb02f69ddb2571e2756e017a1496c2c3a2aeefe7b988ddab38b416d36"}, - {file = "ruff-0.5.6-py3-none-manylinux_2_17_ppc64.manylinux2014_ppc64.whl", hash = "sha256:e395daba77a79f6dc0d07311f94cc0560375ca20c06f354c7c99af3bf4560c5d"}, - {file = "ruff-0.5.6-py3-none-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:c476acb43c3c51e3c614a2e878ee1589655fa02dab19fe2db0423a06d6a5b1b6"}, - {file = "ruff-0.5.6-py3-none-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:e2ff8003f5252fd68425fd53d27c1f08b201d7ed714bb31a55c9ac1d4c13e2eb"}, - {file = "ruff-0.5.6-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c94e084ba3eaa80c2172918c2ca2eb2230c3f15925f4ed8b6297260c6ef179ad"}, - {file = "ruff-0.5.6-py3-none-musllinux_1_2_aarch64.whl", hash = "sha256:1f77c1c3aa0669fb230b06fb24ffa3e879391a3ba3f15e3d633a752da5a3e670"}, - {file = "ruff-0.5.6-py3-none-musllinux_1_2_armv7l.whl", hash = "sha256:f908148c93c02873210a52cad75a6eda856b2cbb72250370ce3afef6fb99b1ed"}, - {file = "ruff-0.5.6-py3-none-musllinux_1_2_i686.whl", hash = "sha256:563a7ae61ad284187d3071d9041c08019975693ff655438d8d4be26e492760bd"}, - {file = "ruff-0.5.6-py3-none-musllinux_1_2_x86_64.whl", hash = "sha256:94fe60869bfbf0521e04fd62b74cbca21cbc5beb67cbb75ab33fe8c174f54414"}, - {file = "ruff-0.5.6-py3-none-win32.whl", hash = "sha256:e6a584c1de6f8591c2570e171cc7ce482bb983d49c70ddf014393cd39e9dfaed"}, - {file = "ruff-0.5.6-py3-none-win_amd64.whl", hash = "sha256:d7fe7dccb1a89dc66785d7aa0ac283b2269712d8ed19c63af908fdccca5ccc1a"}, - {file = "ruff-0.5.6-py3-none-win_arm64.whl", hash = "sha256:57c6c0dd997b31b536bff49b9eee5ed3194d60605a4427f735eeb1f9c1b8d264"}, - {file = "ruff-0.5.6.tar.gz", hash = "sha256:07c9e3c2a8e1fe377dd460371c3462671a728c981c3205a5217291422209f642"}, + {file = "ruff-0.5.7-py3-none-linux_armv6l.whl", hash = "sha256:548992d342fc404ee2e15a242cdbea4f8e39a52f2e7752d0e4cbe88d2d2f416a"}, + {file = "ruff-0.5.7-py3-none-macosx_10_12_x86_64.whl", hash = "sha256:00cc8872331055ee017c4f1071a8a31ca0809ccc0657da1d154a1d2abac5c0be"}, + {file = "ruff-0.5.7-py3-none-macosx_11_0_arm64.whl", hash = "sha256:eaf3d86a1fdac1aec8a3417a63587d93f906c678bb9ed0b796da7b59c1114a1e"}, + {file = "ruff-0.5.7-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a01c34400097b06cf8a6e61b35d6d456d5bd1ae6961542de18ec81eaf33b4cb8"}, + {file = "ruff-0.5.7-py3-none-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:fcc8054f1a717e2213500edaddcf1dbb0abad40d98e1bd9d0ad364f75c763eea"}, + {file = "ruff-0.5.7-py3-none-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:7f70284e73f36558ef51602254451e50dd6cc479f8b6f8413a95fcb5db4a55fc"}, + {file = "ruff-0.5.7-py3-none-manylinux_2_17_ppc64.manylinux2014_ppc64.whl", hash = "sha256:a78ad870ae3c460394fc95437d43deb5c04b5c29297815a2a1de028903f19692"}, + {file = "ruff-0.5.7-py3-none-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:9ccd078c66a8e419475174bfe60a69adb36ce04f8d4e91b006f1329d5cd44bcf"}, + {file = "ruff-0.5.7-py3-none-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:7e31c9bad4ebf8fdb77b59cae75814440731060a09a0e0077d559a556453acbb"}, + {file = "ruff-0.5.7-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8d796327eed8e168164346b769dd9a27a70e0298d667b4ecee6877ce8095ec8e"}, + {file = "ruff-0.5.7-py3-none-musllinux_1_2_aarch64.whl", hash = "sha256:4a09ea2c3f7778cc635e7f6edf57d566a8ee8f485f3c4454db7771efb692c499"}, + {file = "ruff-0.5.7-py3-none-musllinux_1_2_armv7l.whl", hash = "sha256:a36d8dcf55b3a3bc353270d544fb170d75d2dff41eba5df57b4e0b67a95bb64e"}, + {file = "ruff-0.5.7-py3-none-musllinux_1_2_i686.whl", hash = "sha256:9369c218f789eefbd1b8d82a8cf25017b523ac47d96b2f531eba73770971c9e5"}, + {file = "ruff-0.5.7-py3-none-musllinux_1_2_x86_64.whl", hash = "sha256:b88ca3db7eb377eb24fb7c82840546fb7acef75af4a74bd36e9ceb37a890257e"}, + {file = "ruff-0.5.7-py3-none-win32.whl", hash = "sha256:33d61fc0e902198a3e55719f4be6b375b28f860b09c281e4bdbf783c0566576a"}, + {file = "ruff-0.5.7-py3-none-win_amd64.whl", hash = "sha256:083bbcbe6fadb93cd86709037acc510f86eed5a314203079df174c40bbbca6b3"}, + {file = "ruff-0.5.7-py3-none-win_arm64.whl", hash = "sha256:2dca26154ff9571995107221d0aeaad0e75a77b5a682d6236cf89a58c70b76f4"}, + {file = "ruff-0.5.7.tar.gz", hash = "sha256:8dfc0a458797f5d9fb622dd0efc52d796f23f0a1493a9527f4e49a550ae9a7e5"}, ] [[package]] @@ -1512,13 +1512,13 @@ rtd = ["ipython", "myst-nb", "sphinx", "sphinx-book-theme", "sphinx-examples"] [[package]] name = "sphinx-github-changelog" -version = "1.3.0" +version = "1.4.0" description = "Build a sphinx changelog from GitHub Releases" optional = false -python-versions = ">=3.8,<4.0" +python-versions = "<4.0,>=3.8" files = [ - {file = "sphinx_github_changelog-1.3.0-py3-none-any.whl", hash = "sha256:eb5424d590ae7866e77b8db7eecf283678cba76b74d90b17bc4f3872976407eb"}, - {file = "sphinx_github_changelog-1.3.0.tar.gz", hash = "sha256:b898adc52131147305b9cb893c2a4cad0ba2912178ed8f88b62bf6f43a2baaa4"}, + {file = "sphinx_github_changelog-1.4.0-py3-none-any.whl", hash = "sha256:cdf2099ea3e4587ae8637be7ba609738bfdeca4bd80c5df6fc45046735ae5c2f"}, + {file = "sphinx_github_changelog-1.4.0.tar.gz", hash = "sha256:204745e93a1f280e4664977b5fee526b0a011c92ca19c304bd01fd641ddb6393"}, ] [package.dependencies] @@ -1631,60 +1631,60 @@ test = ["pytest"] [[package]] name = "sqlalchemy" -version = "2.0.31" +version = "2.0.32" description = "Database Abstraction Library" optional = false python-versions = ">=3.7" files = [ - {file = "SQLAlchemy-2.0.31-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:f2a213c1b699d3f5768a7272de720387ae0122f1becf0901ed6eaa1abd1baf6c"}, - {file = "SQLAlchemy-2.0.31-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:9fea3d0884e82d1e33226935dac990b967bef21315cbcc894605db3441347443"}, - {file = "SQLAlchemy-2.0.31-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f3ad7f221d8a69d32d197e5968d798217a4feebe30144986af71ada8c548e9fa"}, - {file = "SQLAlchemy-2.0.31-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9f2bee229715b6366f86a95d497c347c22ddffa2c7c96143b59a2aa5cc9eebbc"}, - {file = "SQLAlchemy-2.0.31-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:cd5b94d4819c0c89280b7c6109c7b788a576084bf0a480ae17c227b0bc41e109"}, - {file = "SQLAlchemy-2.0.31-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:750900a471d39a7eeba57580b11983030517a1f512c2cb287d5ad0fcf3aebd58"}, - {file = "SQLAlchemy-2.0.31-cp310-cp310-win32.whl", hash = "sha256:7bd112be780928c7f493c1a192cd8c5fc2a2a7b52b790bc5a84203fb4381c6be"}, - {file = "SQLAlchemy-2.0.31-cp310-cp310-win_amd64.whl", hash = "sha256:5a48ac4d359f058474fadc2115f78a5cdac9988d4f99eae44917f36aa1476327"}, - {file = "SQLAlchemy-2.0.31-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:f68470edd70c3ac3b6cd5c2a22a8daf18415203ca1b036aaeb9b0fb6f54e8298"}, - {file = "SQLAlchemy-2.0.31-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:2e2c38c2a4c5c634fe6c3c58a789712719fa1bf9b9d6ff5ebfce9a9e5b89c1ca"}, - {file = "SQLAlchemy-2.0.31-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:bd15026f77420eb2b324dcb93551ad9c5f22fab2c150c286ef1dc1160f110203"}, - {file = "SQLAlchemy-2.0.31-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:2196208432deebdfe3b22185d46b08f00ac9d7b01284e168c212919891289396"}, - {file = "SQLAlchemy-2.0.31-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:352b2770097f41bff6029b280c0e03b217c2dcaddc40726f8f53ed58d8a85da4"}, - {file = "SQLAlchemy-2.0.31-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:56d51ae825d20d604583f82c9527d285e9e6d14f9a5516463d9705dab20c3740"}, - {file = "SQLAlchemy-2.0.31-cp311-cp311-win32.whl", hash = "sha256:6e2622844551945db81c26a02f27d94145b561f9d4b0c39ce7bfd2fda5776dac"}, - {file = "SQLAlchemy-2.0.31-cp311-cp311-win_amd64.whl", hash = "sha256:ccaf1b0c90435b6e430f5dd30a5aede4764942a695552eb3a4ab74ed63c5b8d3"}, - {file = "SQLAlchemy-2.0.31-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:3b74570d99126992d4b0f91fb87c586a574a5872651185de8297c6f90055ae42"}, - {file = "SQLAlchemy-2.0.31-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:6f77c4f042ad493cb8595e2f503c7a4fe44cd7bd59c7582fd6d78d7e7b8ec52c"}, - {file = "SQLAlchemy-2.0.31-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:cd1591329333daf94467e699e11015d9c944f44c94d2091f4ac493ced0119449"}, - {file = "SQLAlchemy-2.0.31-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:74afabeeff415e35525bf7a4ecdab015f00e06456166a2eba7590e49f8db940e"}, - {file = "SQLAlchemy-2.0.31-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:b9c01990d9015df2c6f818aa8f4297d42ee71c9502026bb074e713d496e26b67"}, - {file = "SQLAlchemy-2.0.31-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:66f63278db425838b3c2b1c596654b31939427016ba030e951b292e32b99553e"}, - {file = "SQLAlchemy-2.0.31-cp312-cp312-win32.whl", hash = "sha256:0b0f658414ee4e4b8cbcd4a9bb0fd743c5eeb81fc858ca517217a8013d282c96"}, - {file = "SQLAlchemy-2.0.31-cp312-cp312-win_amd64.whl", hash = "sha256:fa4b1af3e619b5b0b435e333f3967612db06351217c58bfb50cee5f003db2a5a"}, - {file = "SQLAlchemy-2.0.31-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:f43e93057cf52a227eda401251c72b6fbe4756f35fa6bfebb5d73b86881e59b0"}, - {file = "SQLAlchemy-2.0.31-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d337bf94052856d1b330d5fcad44582a30c532a2463776e1651bd3294ee7e58b"}, - {file = "SQLAlchemy-2.0.31-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c06fb43a51ccdff3b4006aafee9fcf15f63f23c580675f7734245ceb6b6a9e05"}, - {file = "SQLAlchemy-2.0.31-cp37-cp37m-musllinux_1_2_aarch64.whl", hash = "sha256:b6e22630e89f0e8c12332b2b4c282cb01cf4da0d26795b7eae16702a608e7ca1"}, - {file = "SQLAlchemy-2.0.31-cp37-cp37m-musllinux_1_2_x86_64.whl", hash = "sha256:79a40771363c5e9f3a77f0e28b3302801db08040928146e6808b5b7a40749c88"}, - {file = "SQLAlchemy-2.0.31-cp37-cp37m-win32.whl", hash = "sha256:501ff052229cb79dd4c49c402f6cb03b5a40ae4771efc8bb2bfac9f6c3d3508f"}, - {file = "SQLAlchemy-2.0.31-cp37-cp37m-win_amd64.whl", hash = "sha256:597fec37c382a5442ffd471f66ce12d07d91b281fd474289356b1a0041bdf31d"}, - {file = "SQLAlchemy-2.0.31-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:dc6d69f8829712a4fd799d2ac8d79bdeff651c2301b081fd5d3fe697bd5b4ab9"}, - {file = "SQLAlchemy-2.0.31-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:23b9fbb2f5dd9e630db70fbe47d963c7779e9c81830869bd7d137c2dc1ad05fb"}, - {file = "SQLAlchemy-2.0.31-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2a21c97efcbb9f255d5c12a96ae14da873233597dfd00a3a0c4ce5b3e5e79704"}, - {file = "SQLAlchemy-2.0.31-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:26a6a9837589c42b16693cf7bf836f5d42218f44d198f9343dd71d3164ceeeac"}, - {file = "SQLAlchemy-2.0.31-cp38-cp38-musllinux_1_2_aarch64.whl", hash = "sha256:dc251477eae03c20fae8db9c1c23ea2ebc47331bcd73927cdcaecd02af98d3c3"}, - {file = "SQLAlchemy-2.0.31-cp38-cp38-musllinux_1_2_x86_64.whl", hash = "sha256:2fd17e3bb8058359fa61248c52c7b09a97cf3c820e54207a50af529876451808"}, - {file = "SQLAlchemy-2.0.31-cp38-cp38-win32.whl", hash = "sha256:c76c81c52e1e08f12f4b6a07af2b96b9b15ea67ccdd40ae17019f1c373faa227"}, - {file = "SQLAlchemy-2.0.31-cp38-cp38-win_amd64.whl", hash = "sha256:4b600e9a212ed59355813becbcf282cfda5c93678e15c25a0ef896b354423238"}, - {file = "SQLAlchemy-2.0.31-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:5b6cf796d9fcc9b37011d3f9936189b3c8074a02a4ed0c0fbbc126772c31a6d4"}, - {file = "SQLAlchemy-2.0.31-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:78fe11dbe37d92667c2c6e74379f75746dc947ee505555a0197cfba9a6d4f1a4"}, - {file = "SQLAlchemy-2.0.31-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2fc47dc6185a83c8100b37acda27658fe4dbd33b7d5e7324111f6521008ab4fe"}, - {file = "SQLAlchemy-2.0.31-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8a41514c1a779e2aa9a19f67aaadeb5cbddf0b2b508843fcd7bafdf4c6864005"}, - {file = "SQLAlchemy-2.0.31-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:afb6dde6c11ea4525318e279cd93c8734b795ac8bb5dda0eedd9ebaca7fa23f1"}, - {file = "SQLAlchemy-2.0.31-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:3f9faef422cfbb8fd53716cd14ba95e2ef655400235c3dfad1b5f467ba179c8c"}, - {file = "SQLAlchemy-2.0.31-cp39-cp39-win32.whl", hash = "sha256:fc6b14e8602f59c6ba893980bea96571dd0ed83d8ebb9c4479d9ed5425d562e9"}, - {file = "SQLAlchemy-2.0.31-cp39-cp39-win_amd64.whl", hash = "sha256:3cb8a66b167b033ec72c3812ffc8441d4e9f5f78f5e31e54dcd4c90a4ca5bebc"}, - {file = "SQLAlchemy-2.0.31-py3-none-any.whl", hash = "sha256:69f3e3c08867a8e4856e92d7afb618b95cdee18e0bc1647b77599722c9a28911"}, - {file = "SQLAlchemy-2.0.31.tar.gz", hash = "sha256:b607489dd4a54de56984a0c7656247504bd5523d9d0ba799aef59d4add009484"}, + {file = "SQLAlchemy-2.0.32-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:0c9045ecc2e4db59bfc97b20516dfdf8e41d910ac6fb667ebd3a79ea54084619"}, + {file = "SQLAlchemy-2.0.32-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:1467940318e4a860afd546ef61fefb98a14d935cd6817ed07a228c7f7c62f389"}, + {file = "SQLAlchemy-2.0.32-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5954463675cb15db8d4b521f3566a017c8789222b8316b1e6934c811018ee08b"}, + {file = "SQLAlchemy-2.0.32-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:167e7497035c303ae50651b351c28dc22a40bb98fbdb8468cdc971821b1ae533"}, + {file = "SQLAlchemy-2.0.32-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:b27dfb676ac02529fb6e343b3a482303f16e6bc3a4d868b73935b8792edb52d0"}, + {file = "SQLAlchemy-2.0.32-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:bf2360a5e0f7bd75fa80431bf8ebcfb920c9f885e7956c7efde89031695cafb8"}, + {file = "SQLAlchemy-2.0.32-cp310-cp310-win32.whl", hash = "sha256:306fe44e754a91cd9d600a6b070c1f2fadbb4a1a257b8781ccf33c7067fd3e4d"}, + {file = "SQLAlchemy-2.0.32-cp310-cp310-win_amd64.whl", hash = "sha256:99db65e6f3ab42e06c318f15c98f59a436f1c78179e6a6f40f529c8cc7100b22"}, + {file = "SQLAlchemy-2.0.32-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:21b053be28a8a414f2ddd401f1be8361e41032d2ef5884b2f31d31cb723e559f"}, + {file = "SQLAlchemy-2.0.32-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:b178e875a7a25b5938b53b006598ee7645172fccafe1c291a706e93f48499ff5"}, + {file = "SQLAlchemy-2.0.32-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:723a40ee2cc7ea653645bd4cf024326dea2076673fc9d3d33f20f6c81db83e1d"}, + {file = "SQLAlchemy-2.0.32-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:295ff8689544f7ee7e819529633d058bd458c1fd7f7e3eebd0f9268ebc56c2a0"}, + {file = "SQLAlchemy-2.0.32-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:49496b68cd190a147118af585173ee624114dfb2e0297558c460ad7495f9dfe2"}, + {file = "SQLAlchemy-2.0.32-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:acd9b73c5c15f0ec5ce18128b1fe9157ddd0044abc373e6ecd5ba376a7e5d961"}, + {file = "SQLAlchemy-2.0.32-cp311-cp311-win32.whl", hash = "sha256:9365a3da32dabd3e69e06b972b1ffb0c89668994c7e8e75ce21d3e5e69ddef28"}, + {file = "SQLAlchemy-2.0.32-cp311-cp311-win_amd64.whl", hash = "sha256:8bd63d051f4f313b102a2af1cbc8b80f061bf78f3d5bd0843ff70b5859e27924"}, + {file = "SQLAlchemy-2.0.32-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:6bab3db192a0c35e3c9d1560eb8332463e29e5507dbd822e29a0a3c48c0a8d92"}, + {file = "SQLAlchemy-2.0.32-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:19d98f4f58b13900d8dec4ed09dd09ef292208ee44cc9c2fe01c1f0a2fe440e9"}, + {file = "SQLAlchemy-2.0.32-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3cd33c61513cb1b7371fd40cf221256456d26a56284e7d19d1f0b9f1eb7dd7e8"}, + {file = "SQLAlchemy-2.0.32-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7d6ba0497c1d066dd004e0f02a92426ca2df20fac08728d03f67f6960271feec"}, + {file = "SQLAlchemy-2.0.32-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:2b6be53e4fde0065524f1a0a7929b10e9280987b320716c1509478b712a7688c"}, + {file = "SQLAlchemy-2.0.32-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:916a798f62f410c0b80b63683c8061f5ebe237b0f4ad778739304253353bc1cb"}, + {file = "SQLAlchemy-2.0.32-cp312-cp312-win32.whl", hash = "sha256:31983018b74908ebc6c996a16ad3690301a23befb643093fcfe85efd292e384d"}, + {file = "SQLAlchemy-2.0.32-cp312-cp312-win_amd64.whl", hash = "sha256:4363ed245a6231f2e2957cccdda3c776265a75851f4753c60f3004b90e69bfeb"}, + {file = "SQLAlchemy-2.0.32-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:b8afd5b26570bf41c35c0121801479958b4446751a3971fb9a480c1afd85558e"}, + {file = "SQLAlchemy-2.0.32-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c750987fc876813f27b60d619b987b057eb4896b81117f73bb8d9918c14f1cad"}, + {file = "SQLAlchemy-2.0.32-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ada0102afff4890f651ed91120c1120065663506b760da4e7823913ebd3258be"}, + {file = "SQLAlchemy-2.0.32-cp37-cp37m-musllinux_1_2_aarch64.whl", hash = "sha256:78c03d0f8a5ab4f3034c0e8482cfcc415a3ec6193491cfa1c643ed707d476f16"}, + {file = "SQLAlchemy-2.0.32-cp37-cp37m-musllinux_1_2_x86_64.whl", hash = "sha256:3bd1cae7519283ff525e64645ebd7a3e0283f3c038f461ecc1c7b040a0c932a1"}, + {file = "SQLAlchemy-2.0.32-cp37-cp37m-win32.whl", hash = "sha256:01438ebcdc566d58c93af0171c74ec28efe6a29184b773e378a385e6215389da"}, + {file = "SQLAlchemy-2.0.32-cp37-cp37m-win_amd64.whl", hash = "sha256:4979dc80fbbc9d2ef569e71e0896990bc94df2b9fdbd878290bd129b65ab579c"}, + {file = "SQLAlchemy-2.0.32-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:6c742be912f57586ac43af38b3848f7688863a403dfb220193a882ea60e1ec3a"}, + {file = "SQLAlchemy-2.0.32-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:62e23d0ac103bcf1c5555b6c88c114089587bc64d048fef5bbdb58dfd26f96da"}, + {file = "SQLAlchemy-2.0.32-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:251f0d1108aab8ea7b9aadbd07fb47fb8e3a5838dde34aa95a3349876b5a1f1d"}, + {file = "SQLAlchemy-2.0.32-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0ef18a84e5116340e38eca3e7f9eeaaef62738891422e7c2a0b80feab165905f"}, + {file = "SQLAlchemy-2.0.32-cp38-cp38-musllinux_1_2_aarch64.whl", hash = "sha256:3eb6a97a1d39976f360b10ff208c73afb6a4de86dd2a6212ddf65c4a6a2347d5"}, + {file = "SQLAlchemy-2.0.32-cp38-cp38-musllinux_1_2_x86_64.whl", hash = "sha256:0c1c9b673d21477cec17ab10bc4decb1322843ba35b481585facd88203754fc5"}, + {file = "SQLAlchemy-2.0.32-cp38-cp38-win32.whl", hash = "sha256:c41a2b9ca80ee555decc605bd3c4520cc6fef9abde8fd66b1cf65126a6922d65"}, + {file = "SQLAlchemy-2.0.32-cp38-cp38-win_amd64.whl", hash = "sha256:8a37e4d265033c897892279e8adf505c8b6b4075f2b40d77afb31f7185cd6ecd"}, + {file = "SQLAlchemy-2.0.32-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:52fec964fba2ef46476312a03ec8c425956b05c20220a1a03703537824b5e8e1"}, + {file = "SQLAlchemy-2.0.32-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:328429aecaba2aee3d71e11f2477c14eec5990fb6d0e884107935f7fb6001632"}, + {file = "SQLAlchemy-2.0.32-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:85a01b5599e790e76ac3fe3aa2f26e1feba56270023d6afd5550ed63c68552b3"}, + {file = "SQLAlchemy-2.0.32-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:aaf04784797dcdf4c0aa952c8d234fa01974c4729db55c45732520ce12dd95b4"}, + {file = "SQLAlchemy-2.0.32-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:4488120becf9b71b3ac718f4138269a6be99a42fe023ec457896ba4f80749525"}, + {file = "SQLAlchemy-2.0.32-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:14e09e083a5796d513918a66f3d6aedbc131e39e80875afe81d98a03312889e6"}, + {file = "SQLAlchemy-2.0.32-cp39-cp39-win32.whl", hash = "sha256:0d322cc9c9b2154ba7e82f7bf25ecc7c36fbe2d82e2933b3642fc095a52cfc78"}, + {file = "SQLAlchemy-2.0.32-cp39-cp39-win_amd64.whl", hash = "sha256:7dd8583df2f98dea28b5cd53a1beac963f4f9d087888d75f22fcc93a07cf8d84"}, + {file = "SQLAlchemy-2.0.32-py3-none-any.whl", hash = "sha256:e567a8793a692451f706b363ccf3c45e056b67d90ead58c3bc9471af5d212202"}, + {file = "SQLAlchemy-2.0.32.tar.gz", hash = "sha256:c1b88cc8b02b6a5f0efb0345a03672d4c897dc7d92585176f88c67346f565ea8"}, ] [package.dependencies] From 5153f86ed006ca0ba8d552936fbd6345bb861a86 Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Sat, 10 Aug 2024 01:02:12 +0000 Subject: [PATCH 18/59] [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci --- .pre-commit-config.yaml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 21b6bebef..07b837005 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -36,7 +36,7 @@ repos: - aiopg==1.4.0 - anyio==4.4.0 - asgiref==3.8.1 - - attrs==24.1.0 + - attrs==24.2.0 - contextlib2==21.6.0 - croniter==3.0.3 - django-stubs==5.0.4 @@ -46,7 +46,7 @@ repos: - psycopg2-binary==2.9.9 - psycopg[pool]==3.2.1 - python-dateutil==2.9.0.post0 - - sqlalchemy==2.0.31 + - sqlalchemy==2.0.32 - typing-extensions==4.12.2 - repo: https://github.com/astral-sh/ruff-pre-commit rev: v0.5.7 From b2d40a07f5b8f65fcab4f03e64d0923a3fa3b658 Mon Sep 17 00:00:00 2001 From: Joachim Jablon Date: Sun, 11 Aug 2024 00:10:34 +0200 Subject: [PATCH 19/59] Add sphinx extension --- .pre-commit-config.yaml | 1 + procrastinate/contrib/sphinx/__init__.py | 35 ++++++++++++++++++++++++ pyproject.toml | 16 +++++++++-- 3 files changed, 49 insertions(+), 3 deletions(-) create mode 100644 procrastinate/contrib/sphinx/__init__.py diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 07b837005..6b3966db5 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -47,6 +47,7 @@ repos: - psycopg[pool]==3.2.1 - python-dateutil==2.9.0.post0 - sqlalchemy==2.0.32 + - sphinx==7.1.2 - typing-extensions==4.12.2 - repo: https://github.com/astral-sh/ruff-pre-commit rev: v0.5.7 diff --git a/procrastinate/contrib/sphinx/__init__.py b/procrastinate/contrib/sphinx/__init__.py new file mode 100644 index 000000000..e3b84398e --- /dev/null +++ b/procrastinate/contrib/sphinx/__init__.py @@ -0,0 +1,35 @@ +from __future__ import annotations + +from typing import Any + +from sphinx.application import Sphinx +from sphinx.ext.autodoc import FunctionDocumenter + +from procrastinate import tasks + + +class ProcrastinateTaskDocumenter(FunctionDocumenter): + objtype = "procrastinate_task" + directivetype = "function" + member_order = 40 + + @classmethod + def can_document_member( + cls, + member: Any, + membername: str, + isattr: bool, + parent: Any, + ) -> bool: + return isinstance(member, tasks.Task) + + +def setup(app: Sphinx): + app.setup_extension("sphinx.ext.autodoc") # Require autodoc extension + + app.add_autodocumenter(ProcrastinateTaskDocumenter) + + return { + "version": "1", + "parallel_read_safe": True, + } diff --git a/pyproject.toml b/pyproject.toml index 1ff26d963..1a90c8a6c 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -38,12 +38,14 @@ psycopg2-binary = { version = "*", optional = true } python-dateutil = "*" sqlalchemy = { version = "^2.0", optional = true } typing-extensions = { version = "*", python = "<3.8" } +sphinx = { version = "*", optional = true } [tool.poetry.extras] django = ["django"] sqlalchemy = ["sqlalchemy"] aiopg = ["aiopg", "psycopg2-binary"] psycopg2 = ["psycopg2-binary"] +sphinx = ["sphinx"] [tool.poetry.group.types] optional = true @@ -62,9 +64,17 @@ aiopg = "*" sqlalchemy = { extras = ["mypy"], version = "*" } psycopg2-binary = "*" psycopg = [ - { version = "^3.1.13", extras = ["binary", "pool"], markers = "sys_platform != 'darwin' or platform_machine != 'arm64'"}, - { version = "^3.1.13", extras = ["binary", "pool"], markers = "sys_platform == 'darwin' and platform_machine == 'arm64'", python = ">=3.10"}, - { version = "^3.1.13", extras = ["pool"], markers = "sys_platform == 'darwin' and platform_machine == 'arm64'", python = "<3.10" } + { version = "^3.1.13", extras = [ + "binary", + "pool", + ], markers = "sys_platform != 'darwin' or platform_machine != 'arm64'" }, + { version = "^3.1.13", extras = [ + "binary", + "pool", + ], markers = "sys_platform == 'darwin' and platform_machine == 'arm64'", python = ">=3.10" }, + { version = "^3.1.13", extras = [ + "pool", + ], markers = "sys_platform == 'darwin' and platform_machine == 'arm64'", python = "<3.10" }, ] [tool.poetry.group.django.dependencies] From b8e4869044e3c62f0e5f54d9d6f0ccc1411bf3c7 Mon Sep 17 00:00:00 2001 From: Joachim Jablon Date: Sun, 11 Aug 2024 00:08:06 +0200 Subject: [PATCH 20/59] Document the new extension --- docs/howto/advanced/sphinx.md | 30 ++++++++++++++++++++++++++++++ 1 file changed, 30 insertions(+) create mode 100644 docs/howto/advanced/sphinx.md diff --git a/docs/howto/advanced/sphinx.md b/docs/howto/advanced/sphinx.md new file mode 100644 index 000000000..452bf8d37 --- /dev/null +++ b/docs/howto/advanced/sphinx.md @@ -0,0 +1,30 @@ +# Document my tasks with Sphinx & Autodoc + +If you use Sphinx's `autodoc` extension to document your project, you might +have noticed that your tasks are absent from the documentation. This is because +when you apply the `@app.task` decorator, you're actually replacing the +function with a Procrastinate Task object, which `autodoc` doesn't know how to +process. + +Procrastinate provides a small Sphinx extension to fix that. You may want to +ensure procrastinate is installed with the `sphinx` extra in the environment +where you build your doc. This is not mandatory, as it only adds sphinx itself +as a dependency, but if the extension ever needs other dependencies in the +future, they will be installed through the `sphinx` extra as well. + +```bash +$ pip install procrastinate[sphinx] +``` + +Then, add the following to your `conf.py`: + +```python +extensions = [ + # ... + "procrastinate.contrib.sphinx", + # ... +] +``` + +That's it. Your tasks will now be picked up by `autodoc` and included in your +documentation. From 98e02c26aaf9ffe83f6e9070abb045f6a008dafd Mon Sep 17 00:00:00 2001 From: Joachim Jablon Date: Sun, 11 Aug 2024 00:09:07 +0200 Subject: [PATCH 21/59] Drink our own champagne: use our new extension This is the reason why the builtin ask didn't appear in the doc --- docs/conf.py | 1 + 1 file changed, 1 insertion(+) diff --git a/docs/conf.py b/docs/conf.py index 749c801f8..07f38d9dd 100644 --- a/docs/conf.py +++ b/docs/conf.py @@ -42,6 +42,7 @@ "sphinxcontrib.programoutput", "sphinx_github_changelog", "sphinx_copybutton", + "procrastinate.contrib.sphinx", ] myst_enable_extensions = [ From cbb58fb04fc302846544ba2e897ff4f831da6eba Mon Sep 17 00:00:00 2001 From: Joachim Jablon Date: Sun, 11 Aug 2024 00:10:58 +0200 Subject: [PATCH 22/59] Add docstrings to tasks in the demo so that autodoc considers them --- procrastinate_demos/demo_async/tasks.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/procrastinate_demos/demo_async/tasks.py b/procrastinate_demos/demo_async/tasks.py index 2b7e54cf7..437ab3f3d 100644 --- a/procrastinate_demos/demo_async/tasks.py +++ b/procrastinate_demos/demo_async/tasks.py @@ -5,9 +5,11 @@ @app.task(queue="sums") async def sum(a, b): + """Sum two numbers.""" return a + b @app.task(queue="defer") async def defer(): + """Defer a nother task.""" await sum.defer_async(a=1, b=2) From 31eb95b0dd4a2004404745d73cd0c1c5e3ad9216 Mon Sep 17 00:00:00 2001 From: Joachim Jablon Date: Sun, 11 Aug 2024 00:11:12 +0200 Subject: [PATCH 23/59] Add integration test --- tests/integration/contrib/sphinx/__init__.py | 0 tests/integration/contrib/sphinx/conftest.py | 20 +++++++++++++++++++ .../contrib/sphinx/test-root/conf.py | 8 ++++++++ .../contrib/sphinx/test-root/index.rst | 5 +++++ .../contrib/sphinx/test_autodoc.py | 11 ++++++++++ 5 files changed, 44 insertions(+) create mode 100644 tests/integration/contrib/sphinx/__init__.py create mode 100644 tests/integration/contrib/sphinx/conftest.py create mode 100644 tests/integration/contrib/sphinx/test-root/conf.py create mode 100644 tests/integration/contrib/sphinx/test-root/index.rst create mode 100644 tests/integration/contrib/sphinx/test_autodoc.py diff --git a/tests/integration/contrib/sphinx/__init__.py b/tests/integration/contrib/sphinx/__init__.py new file mode 100644 index 000000000..e69de29bb diff --git a/tests/integration/contrib/sphinx/conftest.py b/tests/integration/contrib/sphinx/conftest.py new file mode 100644 index 000000000..7398f5bc9 --- /dev/null +++ b/tests/integration/contrib/sphinx/conftest.py @@ -0,0 +1,20 @@ +from __future__ import annotations + +import pytest +from sphinx.testing.path import path + +pytest_plugins = ["sphinx.testing.fixtures"] + + +@pytest.fixture(scope="session") +def rootdir(): + return path(__file__).parent + + +@pytest.fixture +def sphinx_app(app_params, make_app): + """ + Provides the 'sphinx.application.Sphinx' object + """ + args, kwargs = app_params + return make_app(*args, **kwargs) diff --git a/tests/integration/contrib/sphinx/test-root/conf.py b/tests/integration/contrib/sphinx/test-root/conf.py new file mode 100644 index 000000000..abbececb4 --- /dev/null +++ b/tests/integration/contrib/sphinx/test-root/conf.py @@ -0,0 +1,8 @@ +from __future__ import annotations + +extensions = [ + "sphinx.ext.autodoc", + "procrastinate.contrib.sphinx", +] + +buildername = "html" diff --git a/tests/integration/contrib/sphinx/test-root/index.rst b/tests/integration/contrib/sphinx/test-root/index.rst new file mode 100644 index 000000000..0f287a494 --- /dev/null +++ b/tests/integration/contrib/sphinx/test-root/index.rst @@ -0,0 +1,5 @@ +Tasks +===== + +.. automodule:: procrastinate_demos.demo_async.tasks + :members: diff --git a/tests/integration/contrib/sphinx/test_autodoc.py b/tests/integration/contrib/sphinx/test_autodoc.py new file mode 100644 index 000000000..20c84a3d0 --- /dev/null +++ b/tests/integration/contrib/sphinx/test_autodoc.py @@ -0,0 +1,11 @@ +from __future__ import annotations + +import pytest + + +@pytest.mark.sphinx(buildername="html", testroot="root") +def test_autodoc_task(sphinx_app): + sphinx_app.build() + content = (sphinx_app.outdir / "index.html").read_text() + # Check that the docstring of one of the task appears in the generated documentation + assert "Sum two numbers." in content From af31ab352882bf0abae5cd01aa753004964ecaf9 Mon Sep 17 00:00:00 2001 From: Joachim Jablon Date: Sun, 11 Aug 2024 00:18:58 +0200 Subject: [PATCH 24/59] Poetry lock --- .pre-commit-config.yaml | 2 +- poetry.lock | 5 +++-- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 6b3966db5..146c7dd95 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -46,8 +46,8 @@ repos: - psycopg2-binary==2.9.9 - psycopg[pool]==3.2.1 - python-dateutil==2.9.0.post0 - - sqlalchemy==2.0.32 - sphinx==7.1.2 + - sqlalchemy==2.0.32 - typing-extensions==4.12.2 - repo: https://github.com/astral-sh/ruff-pre-commit rev: v0.5.7 diff --git a/poetry.lock b/poetry.lock index e148c3715..4371a31cf 100644 --- a/poetry.lock +++ b/poetry.lock @@ -1,4 +1,4 @@ -# This file is automatically @generated by Poetry 1.8.3 and should not be changed by hand. +# This file is automatically @generated by Poetry 1.8.2 and should not be changed by hand. [[package]] name = "aiopg" @@ -1833,9 +1833,10 @@ test = ["big-O", "importlib-resources", "jaraco.functools", "jaraco.itertools", aiopg = ["aiopg", "psycopg2-binary"] django = ["django"] psycopg2 = ["psycopg2-binary"] +sphinx = ["sphinx"] sqlalchemy = ["sqlalchemy"] [metadata] lock-version = "2.0" python-versions = "^3.8" -content-hash = "4c0b8b8ffde08064ffd59f6cf47bffff22f08479bfeba08fa9592672cf9f7659" +content-hash = "6c0aeb48705cf04301eaf320ef5df2399eae7fae612cdfad816b785c1623a715" From 2d23861eb9de42a4ff1d03fcd6b9c1d4858f1dc6 Mon Sep 17 00:00:00 2001 From: Joachim Jablon Date: Sun, 11 Aug 2024 00:29:12 +0200 Subject: [PATCH 25/59] Add doc to toctree --- docs/howto/advanced.md | 1 + 1 file changed, 1 insertion(+) diff --git a/docs/howto/advanced.md b/docs/howto/advanced.md index aee8516a6..dd810e5c3 100644 --- a/docs/howto/advanced.md +++ b/docs/howto/advanced.md @@ -17,4 +17,5 @@ advanced/events advanced/sync_defer advanced/custom_json_encoder_decoder advanced/blueprints +advanced/sphinx ::: From 1b8b33ae107595ad17d1e2928faa94bcab358ad4 Mon Sep 17 00:00:00 2001 From: Joachim Jablon Date: Sun, 11 Aug 2024 00:34:25 +0200 Subject: [PATCH 26/59] define pytest_plugins in the top-level conftest --- tests/conftest.py | 4 ++++ tests/integration/contrib/sphinx/conftest.py | 20 ------------------- .../contrib/sphinx/test_autodoc.py | 15 ++++++++++++++ 3 files changed, 19 insertions(+), 20 deletions(-) diff --git a/tests/conftest.py b/tests/conftest.py index 6e4ab323d..965b70aee 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -25,6 +25,10 @@ if key.startswith("PROCRASTINATE_"): os.environ.pop(key) +# Infortunately, we need the sphinx fixtures even though they generate an "app" fixture +# that conflicts with our own "app" fixture +pytest_plugins = ["sphinx.testing.fixtures"] + def cursor_execute(cursor, query, *identifiers): if identifiers: diff --git a/tests/integration/contrib/sphinx/conftest.py b/tests/integration/contrib/sphinx/conftest.py index 7398f5bc9..e69de29bb 100644 --- a/tests/integration/contrib/sphinx/conftest.py +++ b/tests/integration/contrib/sphinx/conftest.py @@ -1,20 +0,0 @@ -from __future__ import annotations - -import pytest -from sphinx.testing.path import path - -pytest_plugins = ["sphinx.testing.fixtures"] - - -@pytest.fixture(scope="session") -def rootdir(): - return path(__file__).parent - - -@pytest.fixture -def sphinx_app(app_params, make_app): - """ - Provides the 'sphinx.application.Sphinx' object - """ - args, kwargs = app_params - return make_app(*args, **kwargs) diff --git a/tests/integration/contrib/sphinx/test_autodoc.py b/tests/integration/contrib/sphinx/test_autodoc.py index 20c84a3d0..30b191355 100644 --- a/tests/integration/contrib/sphinx/test_autodoc.py +++ b/tests/integration/contrib/sphinx/test_autodoc.py @@ -1,6 +1,21 @@ from __future__ import annotations import pytest +from sphinx.testing.path import path + + +@pytest.fixture +def rootdir(): + return path(__file__).parent + + +@pytest.fixture +def sphinx_app(app_params, make_app): + """ + Provides the 'sphinx.application.Sphinx' object + """ + args, kwargs = app_params + return make_app(*args, **kwargs) @pytest.mark.sphinx(buildername="html", testroot="root") From 4633dcef3588da5310b2c825fb8946d0c104ce40 Mon Sep 17 00:00:00 2001 From: Joachim Jablon Date: Sun, 11 Aug 2024 22:17:55 +0200 Subject: [PATCH 27/59] Update procrastinate_demos/demo_async/tasks.py --- procrastinate_demos/demo_async/tasks.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/procrastinate_demos/demo_async/tasks.py b/procrastinate_demos/demo_async/tasks.py index 437ab3f3d..49f6be684 100644 --- a/procrastinate_demos/demo_async/tasks.py +++ b/procrastinate_demos/demo_async/tasks.py @@ -11,5 +11,5 @@ async def sum(a, b): @app.task(queue="defer") async def defer(): - """Defer a nother task.""" + """Defer a another task.""" await sum.defer_async(a=1, b=2) From 86ea2a2411b55c3495c0031c9b28368811674b19 Mon Sep 17 00:00:00 2001 From: Joachim Jablon Date: Sun, 11 Aug 2024 22:18:10 +0200 Subject: [PATCH 28/59] Update tests/conftest.py --- tests/conftest.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/conftest.py b/tests/conftest.py index 965b70aee..836c610a7 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -25,7 +25,7 @@ if key.startswith("PROCRASTINATE_"): os.environ.pop(key) -# Infortunately, we need the sphinx fixtures even though they generate an "app" fixture +# Unfortunately, we need the sphinx fixtures even though they generate an "app" fixture # that conflicts with our own "app" fixture pytest_plugins = ["sphinx.testing.fixtures"] From c789eef2e5f962cbdc56fa038f4d28da587dc160 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Mon, 12 Aug 2024 02:08:36 +0000 Subject: [PATCH 29/59] chore(deps): lock file maintenance --- poetry.lock | 126 ++++++++++++++++++++++++++-------------------------- 1 file changed, 64 insertions(+), 62 deletions(-) diff --git a/poetry.lock b/poetry.lock index 4371a31cf..cfdfe7a6f 100644 --- a/poetry.lock +++ b/poetry.lock @@ -100,13 +100,13 @@ tests-mypy = ["mypy (>=1.11.1)", "pytest-mypy-plugins"] [[package]] name = "babel" -version = "2.15.0" +version = "2.16.0" description = "Internationalization utilities" optional = false python-versions = ">=3.8" files = [ - {file = "Babel-2.15.0-py3-none-any.whl", hash = "sha256:08706bdad8d0a3413266ab61bd6c34d0c28d6e1e7badf40a2cebe67644e2e1fb"}, - {file = "babel-2.15.0.tar.gz", hash = "sha256:8daf0e265d05768bc6c7a314cf1321e9a123afc328cc635c18622a2f30a04413"}, + {file = "babel-2.16.0-py3-none-any.whl", hash = "sha256:368b5b98b37c06b7daf6696391c3240c938b37767d4584413e8438c5c435fa8b"}, + {file = "babel-2.16.0.tar.gz", hash = "sha256:d1f3554ca26605fe173f3de0c65f750f5a42f924499bf134de6423582298e316"}, ] [package.dependencies] @@ -1241,62 +1241,64 @@ files = [ [[package]] name = "pyyaml" -version = "6.0.1" +version = "6.0.2" description = "YAML parser and emitter for Python" optional = false -python-versions = ">=3.6" +python-versions = ">=3.8" files = [ - {file = "PyYAML-6.0.1-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:d858aa552c999bc8a8d57426ed01e40bef403cd8ccdd0fc5f6f04a00414cac2a"}, - {file = "PyYAML-6.0.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:fd66fc5d0da6d9815ba2cebeb4205f95818ff4b79c3ebe268e75d961704af52f"}, - {file = "PyYAML-6.0.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:69b023b2b4daa7548bcfbd4aa3da05b3a74b772db9e23b982788168117739938"}, - {file = "PyYAML-6.0.1-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:81e0b275a9ecc9c0c0c07b4b90ba548307583c125f54d5b6946cfee6360c733d"}, - {file = "PyYAML-6.0.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ba336e390cd8e4d1739f42dfe9bb83a3cc2e80f567d8805e11b46f4a943f5515"}, - {file = "PyYAML-6.0.1-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:326c013efe8048858a6d312ddd31d56e468118ad4cdeda36c719bf5bb6192290"}, - {file = "PyYAML-6.0.1-cp310-cp310-win32.whl", hash = "sha256:bd4af7373a854424dabd882decdc5579653d7868b8fb26dc7d0e99f823aa5924"}, - {file = "PyYAML-6.0.1-cp310-cp310-win_amd64.whl", hash = "sha256:fd1592b3fdf65fff2ad0004b5e363300ef59ced41c2e6b3a99d4089fa8c5435d"}, - {file = "PyYAML-6.0.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:6965a7bc3cf88e5a1c3bd2e0b5c22f8d677dc88a455344035f03399034eb3007"}, - {file = "PyYAML-6.0.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:f003ed9ad21d6a4713f0a9b5a7a0a79e08dd0f221aff4525a2be4c346ee60aab"}, - {file = "PyYAML-6.0.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:42f8152b8dbc4fe7d96729ec2b99c7097d656dc1213a3229ca5383f973a5ed6d"}, - {file = "PyYAML-6.0.1-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:062582fca9fabdd2c8b54a3ef1c978d786e0f6b3a1510e0ac93ef59e0ddae2bc"}, - {file = "PyYAML-6.0.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d2b04aac4d386b172d5b9692e2d2da8de7bfb6c387fa4f801fbf6fb2e6ba4673"}, - {file = "PyYAML-6.0.1-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:e7d73685e87afe9f3b36c799222440d6cf362062f78be1013661b00c5c6f678b"}, - {file = "PyYAML-6.0.1-cp311-cp311-win32.whl", hash = "sha256:1635fd110e8d85d55237ab316b5b011de701ea0f29d07611174a1b42f1444741"}, - {file = "PyYAML-6.0.1-cp311-cp311-win_amd64.whl", hash = "sha256:bf07ee2fef7014951eeb99f56f39c9bb4af143d8aa3c21b1677805985307da34"}, - {file = "PyYAML-6.0.1-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:855fb52b0dc35af121542a76b9a84f8d1cd886ea97c84703eaa6d88e37a2ad28"}, - {file = "PyYAML-6.0.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:40df9b996c2b73138957fe23a16a4f0ba614f4c0efce1e9406a184b6d07fa3a9"}, - {file = "PyYAML-6.0.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a08c6f0fe150303c1c6b71ebcd7213c2858041a7e01975da3a99aed1e7a378ef"}, - {file = "PyYAML-6.0.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6c22bec3fbe2524cde73d7ada88f6566758a8f7227bfbf93a408a9d86bcc12a0"}, - {file = "PyYAML-6.0.1-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:8d4e9c88387b0f5c7d5f281e55304de64cf7f9c0021a3525bd3b1c542da3b0e4"}, - {file = "PyYAML-6.0.1-cp312-cp312-win32.whl", hash = "sha256:d483d2cdf104e7c9fa60c544d92981f12ad66a457afae824d146093b8c294c54"}, - {file = "PyYAML-6.0.1-cp312-cp312-win_amd64.whl", hash = "sha256:0d3304d8c0adc42be59c5f8a4d9e3d7379e6955ad754aa9d6ab7a398b59dd1df"}, - {file = "PyYAML-6.0.1-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:50550eb667afee136e9a77d6dc71ae76a44df8b3e51e41b77f6de2932bfe0f47"}, - {file = "PyYAML-6.0.1-cp36-cp36m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1fe35611261b29bd1de0070f0b2f47cb6ff71fa6595c077e42bd0c419fa27b98"}, - {file = "PyYAML-6.0.1-cp36-cp36m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:704219a11b772aea0d8ecd7058d0082713c3562b4e271b849ad7dc4a5c90c13c"}, - {file = "PyYAML-6.0.1-cp36-cp36m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:afd7e57eddb1a54f0f1a974bc4391af8bcce0b444685d936840f125cf046d5bd"}, - {file = "PyYAML-6.0.1-cp36-cp36m-win32.whl", hash = "sha256:fca0e3a251908a499833aa292323f32437106001d436eca0e6e7833256674585"}, - {file = "PyYAML-6.0.1-cp36-cp36m-win_amd64.whl", hash = "sha256:f22ac1c3cac4dbc50079e965eba2c1058622631e526bd9afd45fedd49ba781fa"}, - {file = "PyYAML-6.0.1-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:b1275ad35a5d18c62a7220633c913e1b42d44b46ee12554e5fd39c70a243d6a3"}, - {file = "PyYAML-6.0.1-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:18aeb1bf9a78867dc38b259769503436b7c72f7a1f1f4c93ff9a17de54319b27"}, - {file = "PyYAML-6.0.1-cp37-cp37m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:596106435fa6ad000c2991a98fa58eeb8656ef2325d7e158344fb33864ed87e3"}, - {file = "PyYAML-6.0.1-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:baa90d3f661d43131ca170712d903e6295d1f7a0f595074f151c0aed377c9b9c"}, - {file = "PyYAML-6.0.1-cp37-cp37m-win32.whl", hash = "sha256:9046c58c4395dff28dd494285c82ba00b546adfc7ef001486fbf0324bc174fba"}, - {file = "PyYAML-6.0.1-cp37-cp37m-win_amd64.whl", hash = "sha256:4fb147e7a67ef577a588a0e2c17b6db51dda102c71de36f8549b6816a96e1867"}, - {file = "PyYAML-6.0.1-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:1d4c7e777c441b20e32f52bd377e0c409713e8bb1386e1099c2415f26e479595"}, - {file = "PyYAML-6.0.1-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a0cd17c15d3bb3fa06978b4e8958dcdc6e0174ccea823003a106c7d4d7899ac5"}, - {file = "PyYAML-6.0.1-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:28c119d996beec18c05208a8bd78cbe4007878c6dd15091efb73a30e90539696"}, - {file = "PyYAML-6.0.1-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7e07cbde391ba96ab58e532ff4803f79c4129397514e1413a7dc761ccd755735"}, - {file = "PyYAML-6.0.1-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:49a183be227561de579b4a36efbb21b3eab9651dd81b1858589f796549873dd6"}, - {file = "PyYAML-6.0.1-cp38-cp38-win32.whl", hash = "sha256:184c5108a2aca3c5b3d3bf9395d50893a7ab82a38004c8f61c258d4428e80206"}, - {file = "PyYAML-6.0.1-cp38-cp38-win_amd64.whl", hash = "sha256:1e2722cc9fbb45d9b87631ac70924c11d3a401b2d7f410cc0e3bbf249f2dca62"}, - {file = "PyYAML-6.0.1-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:9eb6caa9a297fc2c2fb8862bc5370d0303ddba53ba97e71f08023b6cd73d16a8"}, - {file = "PyYAML-6.0.1-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:c8098ddcc2a85b61647b2590f825f3db38891662cfc2fc776415143f599bb859"}, - {file = "PyYAML-6.0.1-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5773183b6446b2c99bb77e77595dd486303b4faab2b086e7b17bc6bef28865f6"}, - {file = "PyYAML-6.0.1-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:b786eecbdf8499b9ca1d697215862083bd6d2a99965554781d0d8d1ad31e13a0"}, - {file = "PyYAML-6.0.1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bc1bf2925a1ecd43da378f4db9e4f799775d6367bdb94671027b73b393a7c42c"}, - {file = "PyYAML-6.0.1-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:04ac92ad1925b2cff1db0cfebffb6ffc43457495c9b3c39d3fcae417d7125dc5"}, - {file = "PyYAML-6.0.1-cp39-cp39-win32.whl", hash = "sha256:faca3bdcf85b2fc05d06ff3fbc1f83e1391b3e724afa3feba7d13eeab355484c"}, - {file = "PyYAML-6.0.1-cp39-cp39-win_amd64.whl", hash = "sha256:510c9deebc5c0225e8c96813043e62b680ba2f9c50a08d3724c7f28a747d1486"}, - {file = "PyYAML-6.0.1.tar.gz", hash = "sha256:bfdf460b1736c775f2ba9f6a92bca30bc2095067b8a9d77876d1fad6cc3b4a43"}, + {file = "PyYAML-6.0.2-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:0a9a2848a5b7feac301353437eb7d5957887edbf81d56e903999a75a3d743086"}, + {file = "PyYAML-6.0.2-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:29717114e51c84ddfba879543fb232a6ed60086602313ca38cce623c1d62cfbf"}, + {file = "PyYAML-6.0.2-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8824b5a04a04a047e72eea5cec3bc266db09e35de6bdfe34c9436ac5ee27d237"}, + {file = "PyYAML-6.0.2-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:7c36280e6fb8385e520936c3cb3b8042851904eba0e58d277dca80a5cfed590b"}, + {file = "PyYAML-6.0.2-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ec031d5d2feb36d1d1a24380e4db6d43695f3748343d99434e6f5f9156aaa2ed"}, + {file = "PyYAML-6.0.2-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:936d68689298c36b53b29f23c6dbb74de12b4ac12ca6cfe0e047bedceea56180"}, + {file = "PyYAML-6.0.2-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:23502f431948090f597378482b4812b0caae32c22213aecf3b55325e049a6c68"}, + {file = "PyYAML-6.0.2-cp310-cp310-win32.whl", hash = "sha256:2e99c6826ffa974fe6e27cdb5ed0021786b03fc98e5ee3c5bfe1fd5015f42b99"}, + {file = "PyYAML-6.0.2-cp310-cp310-win_amd64.whl", hash = "sha256:a4d3091415f010369ae4ed1fc6b79def9416358877534caf6a0fdd2146c87a3e"}, + {file = "PyYAML-6.0.2-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:cc1c1159b3d456576af7a3e4d1ba7e6924cb39de8f67111c735f6fc832082774"}, + {file = "PyYAML-6.0.2-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:1e2120ef853f59c7419231f3bf4e7021f1b936f6ebd222406c3b60212205d2ee"}, + {file = "PyYAML-6.0.2-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5d225db5a45f21e78dd9358e58a98702a0302f2659a3c6cd320564b75b86f47c"}, + {file = "PyYAML-6.0.2-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:5ac9328ec4831237bec75defaf839f7d4564be1e6b25ac710bd1a96321cc8317"}, + {file = "PyYAML-6.0.2-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3ad2a3decf9aaba3d29c8f537ac4b243e36bef957511b4766cb0057d32b0be85"}, + {file = "PyYAML-6.0.2-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:ff3824dc5261f50c9b0dfb3be22b4567a6f938ccce4587b38952d85fd9e9afe4"}, + {file = "PyYAML-6.0.2-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:797b4f722ffa07cc8d62053e4cff1486fa6dc094105d13fea7b1de7d8bf71c9e"}, + {file = "PyYAML-6.0.2-cp311-cp311-win32.whl", hash = "sha256:11d8f3dd2b9c1207dcaf2ee0bbbfd5991f571186ec9cc78427ba5bd32afae4b5"}, + {file = "PyYAML-6.0.2-cp311-cp311-win_amd64.whl", hash = "sha256:e10ce637b18caea04431ce14fabcf5c64a1c61ec9c56b071a4b7ca131ca52d44"}, + {file = "PyYAML-6.0.2-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:c70c95198c015b85feafc136515252a261a84561b7b1d51e3384e0655ddf25ab"}, + {file = "PyYAML-6.0.2-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:ce826d6ef20b1bc864f0a68340c8b3287705cae2f8b4b1d932177dcc76721725"}, + {file = "PyYAML-6.0.2-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1f71ea527786de97d1a0cc0eacd1defc0985dcf6b3f17bb77dcfc8c34bec4dc5"}, + {file = "PyYAML-6.0.2-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:9b22676e8097e9e22e36d6b7bda33190d0d400f345f23d4065d48f4ca7ae0425"}, + {file = "PyYAML-6.0.2-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:80bab7bfc629882493af4aa31a4cfa43a4c57c83813253626916b8c7ada83476"}, + {file = "PyYAML-6.0.2-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:0833f8694549e586547b576dcfaba4a6b55b9e96098b36cdc7ebefe667dfed48"}, + {file = "PyYAML-6.0.2-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:8b9c7197f7cb2738065c481a0461e50ad02f18c78cd75775628afb4d7137fb3b"}, + {file = "PyYAML-6.0.2-cp312-cp312-win32.whl", hash = "sha256:ef6107725bd54b262d6dedcc2af448a266975032bc85ef0172c5f059da6325b4"}, + {file = "PyYAML-6.0.2-cp312-cp312-win_amd64.whl", hash = "sha256:7e7401d0de89a9a855c839bc697c079a4af81cf878373abd7dc625847d25cbd8"}, + {file = "PyYAML-6.0.2-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:efdca5630322a10774e8e98e1af481aad470dd62c3170801852d752aa7a783ba"}, + {file = "PyYAML-6.0.2-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:50187695423ffe49e2deacb8cd10510bc361faac997de9efef88badc3bb9e2d1"}, + {file = "PyYAML-6.0.2-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0ffe8360bab4910ef1b9e87fb812d8bc0a308b0d0eef8c8f44e0254ab3b07133"}, + {file = "PyYAML-6.0.2-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:17e311b6c678207928d649faa7cb0d7b4c26a0ba73d41e99c4fff6b6c3276484"}, + {file = "PyYAML-6.0.2-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:70b189594dbe54f75ab3a1acec5f1e3faa7e8cf2f1e08d9b561cb41b845f69d5"}, + {file = "PyYAML-6.0.2-cp313-cp313-musllinux_1_1_aarch64.whl", hash = "sha256:41e4e3953a79407c794916fa277a82531dd93aad34e29c2a514c2c0c5fe971cc"}, + {file = "PyYAML-6.0.2-cp313-cp313-musllinux_1_1_x86_64.whl", hash = "sha256:68ccc6023a3400877818152ad9a1033e3db8625d899c72eacb5a668902e4d652"}, + {file = "PyYAML-6.0.2-cp313-cp313-win32.whl", hash = "sha256:bc2fa7c6b47d6bc618dd7fb02ef6fdedb1090ec036abab80d4681424b84c1183"}, + {file = "PyYAML-6.0.2-cp313-cp313-win_amd64.whl", hash = "sha256:8388ee1976c416731879ac16da0aff3f63b286ffdd57cdeb95f3f2e085687563"}, + {file = "PyYAML-6.0.2-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:24471b829b3bf607e04e88d79542a9d48bb037c2267d7927a874e6c205ca7e9a"}, + {file = "PyYAML-6.0.2-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d7fded462629cfa4b685c5416b949ebad6cec74af5e2d42905d41e257e0869f5"}, + {file = "PyYAML-6.0.2-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:d84a1718ee396f54f3a086ea0a66d8e552b2ab2017ef8b420e92edbc841c352d"}, + {file = "PyYAML-6.0.2-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9056c1ecd25795207ad294bcf39f2db3d845767be0ea6e6a34d856f006006083"}, + {file = "PyYAML-6.0.2-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:82d09873e40955485746739bcb8b4586983670466c23382c19cffecbf1fd8706"}, + {file = "PyYAML-6.0.2-cp38-cp38-win32.whl", hash = "sha256:43fa96a3ca0d6b1812e01ced1044a003533c47f6ee8aca31724f78e93ccc089a"}, + {file = "PyYAML-6.0.2-cp38-cp38-win_amd64.whl", hash = "sha256:01179a4a8559ab5de078078f37e5c1a30d76bb88519906844fd7bdea1b7729ff"}, + {file = "PyYAML-6.0.2-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:688ba32a1cffef67fd2e9398a2efebaea461578b0923624778664cc1c914db5d"}, + {file = "PyYAML-6.0.2-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:a8786accb172bd8afb8be14490a16625cbc387036876ab6ba70912730faf8e1f"}, + {file = "PyYAML-6.0.2-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d8e03406cac8513435335dbab54c0d385e4a49e4945d2909a581c83647ca0290"}, + {file = "PyYAML-6.0.2-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:f753120cb8181e736c57ef7636e83f31b9c0d1722c516f7e86cf15b7aa57ff12"}, + {file = "PyYAML-6.0.2-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3b1fdb9dc17f5a7677423d508ab4f243a726dea51fa5e70992e59a7411c89d19"}, + {file = "PyYAML-6.0.2-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:0b69e4ce7a131fe56b7e4d770c67429700908fc0752af059838b1cfb41960e4e"}, + {file = "PyYAML-6.0.2-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:a9f8c2e67970f13b16084e04f134610fd1d374bf477b17ec1599185cf611d725"}, + {file = "PyYAML-6.0.2-cp39-cp39-win32.whl", hash = "sha256:6395c297d42274772abc367baaa79683958044e5d3835486c16da75d2a694631"}, + {file = "PyYAML-6.0.2-cp39-cp39-win_amd64.whl", hash = "sha256:39693e1f8320ae4f43943590b49779ffb98acb81f788220ea932a6b6c51004d8"}, + {file = "pyyaml-6.0.2.tar.gz", hash = "sha256:d584d9ec91ad65861cc08d42e834324ef890a082e591037abe114850ff7bbc3e"}, ] [[package]] @@ -1766,13 +1768,13 @@ files = [ [[package]] name = "types-pyyaml" -version = "6.0.12.20240724" +version = "6.0.12.20240808" description = "Typing stubs for PyYAML" optional = false python-versions = ">=3.8" files = [ - {file = "types-PyYAML-6.0.12.20240724.tar.gz", hash = "sha256:cf7b31ae67e0c5b2919c703d2affc415485099d3fe6666a6912f040fd05cb67f"}, - {file = "types_PyYAML-6.0.12.20240724-py3-none-any.whl", hash = "sha256:e5becec598f3aa3a2ddf671de4a75fa1c6856fbf73b2840286c9d50fae2d5d48"}, + {file = "types-PyYAML-6.0.12.20240808.tar.gz", hash = "sha256:b8f76ddbd7f65440a8bda5526a9607e4c7a322dc2f8e1a8c405644f9a6f4b9af"}, + {file = "types_PyYAML-6.0.12.20240808-py3-none-any.whl", hash = "sha256:deda34c5c655265fc517b546c902aa6eed2ef8d3e921e4765fe606fe2afe8d35"}, ] [[package]] @@ -1816,13 +1818,13 @@ zstd = ["zstandard (>=0.18.0)"] [[package]] name = "zipp" -version = "3.19.2" +version = "3.20.0" description = "Backport of pathlib-compatible object wrapper for zip files" optional = false python-versions = ">=3.8" files = [ - {file = "zipp-3.19.2-py3-none-any.whl", hash = "sha256:f091755f667055f2d02b32c53771a7a6c8b47e1fdbc4b72a8b9072b3eef8015c"}, - {file = "zipp-3.19.2.tar.gz", hash = "sha256:bf1dcf6450f873a13e952a29504887c89e6de7506209e5b1bcc3460135d4de19"}, + {file = "zipp-3.20.0-py3-none-any.whl", hash = "sha256:58da6168be89f0be59beb194da1250516fdaa062ccebd30127ac65d30045e10d"}, + {file = "zipp-3.20.0.tar.gz", hash = "sha256:0145e43d89664cfe1a2e533adc75adafed82fe2da404b4bbb6b026c0157bdb31"}, ] [package.extras] From 6521243d2688ae092d9d3d480848c2b83870f5dd Mon Sep 17 00:00:00 2001 From: Kai Schlamp Date: Thu, 15 Aug 2024 12:20:47 +0000 Subject: [PATCH 30/59] Run sync task in its own thread --- procrastinate/utils.py | 2 +- tests/acceptance/test_sync.py | 51 +++++++++++++++++++++++++++++++++++ 2 files changed, 52 insertions(+), 1 deletion(-) diff --git a/procrastinate/utils.py b/procrastinate/utils.py index 2d6e7afc2..9e28dc5b6 100644 --- a/procrastinate/utils.py +++ b/procrastinate/utils.py @@ -105,7 +105,7 @@ async def sync_to_async(func: Callable[..., T], *args, **kwargs) -> T: Given a callable, return a callable that will call the original one in an async context. """ - return await sync.sync_to_async(func)(*args, **kwargs) + return await sync.sync_to_async(func, thread_sensitive=False)(*args, **kwargs) def causes(exc: BaseException | None): diff --git a/tests/acceptance/test_sync.py b/tests/acceptance/test_sync.py index f856db2b5..1de3be071 100644 --- a/tests/acceptance/test_sync.py +++ b/tests/acceptance/test_sync.py @@ -1,6 +1,10 @@ from __future__ import annotations +import asyncio +import time + import pytest +from asgiref.sync import sync_to_async import procrastinate from procrastinate.contrib import psycopg2 @@ -54,6 +58,53 @@ async def product_task(a, b): assert product_results == [12] +async def test_nested_sync_to_async(sync_app, async_app): + sum_results = [] + + @sync_app.task(queue="default", name="sum_task") + def sum_task_sync(a, b): + async def _sum_task_async(a, b): + def _inner_sum_task_sync(a, b): + sum_results.append(a + b) + + # Only works if the worker runs the sync task in a separate thread + await sync_to_async(_inner_sum_task_sync)(a, b) + + asyncio.run(_sum_task_async(a, b)) + + sum_task_sync.defer(a=1, b=2) + + # We need to run the async app to execute the tasks + async_app.tasks = sync_app.tasks + await async_app.run_worker_async(queues=["default"], wait=False) + + assert sum_results == [3] + + +async def test_sync_task_runs_in_parallel(sync_app, async_app): + results = [] + + @sync_app.task(queue="default", name="sync_task_1") + def sync_task_1(): + for i in range(3): + time.sleep(0.1) + results.append(i) + + @sync_app.task(queue="default", name="sync_task_2") + def sync_task_2(): + for i in range(3): + time.sleep(0.1) + results.append(i) + + sync_task_1.defer() + sync_task_2.defer() + + async_app.tasks = sync_app.tasks + await async_app.run_worker_async(queues=["default"], concurrency=2, wait=False) + + assert results == [0, 0, 1, 1, 2, 2] + + async def test_cancel(sync_app, async_app): sum_results = [] From 52947ec9b61296119c6712773a3925984c5ea273 Mon Sep 17 00:00:00 2001 From: Joachim Jablon Date: Fri, 16 Aug 2024 00:06:18 +0200 Subject: [PATCH 31/59] Wrap Django exceptions correctly --- .../contrib/django/django_connector.py | 10 ++++++++- .../contrib/django/test_django_connector.py | 21 ++++++++++++++----- .../contrib/django/test_django_connector.py | 20 ++++++++++++++++++ 3 files changed, 45 insertions(+), 6 deletions(-) create mode 100644 tests/unit/contrib/django/test_django_connector.py diff --git a/procrastinate/contrib/django/django_connector.py b/procrastinate/contrib/django/django_connector.py index cf54515c0..42564d5cf 100644 --- a/procrastinate/contrib/django/django_connector.py +++ b/procrastinate/contrib/django/django_connector.py @@ -10,6 +10,7 @@ ) import asgiref.sync +from django import db as django_db from django.core import exceptions as django_exceptions from django.db import connections from django.db.backends.base.base import BaseDatabaseWrapper @@ -41,7 +42,14 @@ def wrap_exceptions() -> Generator[None, None, None]: ) with wrap(): - yield + try: + yield + except django_db.DatabaseError as exc: + # __cause__ is always defined but might be None, it's set by Django + # (using `raise x from y) to the original db driver exception + if exc.__cause__: + raise exc.__cause__ + raise exc class DjangoConnector(connector.BaseAsyncConnector): diff --git a/tests/integration/contrib/django/test_django_connector.py b/tests/integration/contrib/django/test_django_connector.py index 59c5cfd15..f523f6613 100644 --- a/tests/integration/contrib/django/test_django_connector.py +++ b/tests/integration/contrib/django/test_django_connector.py @@ -1,9 +1,10 @@ from __future__ import annotations import pytest -from django.core import exceptions +from django.core import exceptions as django_exceptions -from procrastinate import psycopg_connector +import procrastinate.contrib.django +from procrastinate import exceptions, psycopg_connector from procrastinate.contrib.aiopg import aiopg_connector from procrastinate.contrib.django import django_connector as django_connector_module @@ -13,6 +14,16 @@ def django_connector(db): return django_connector_module.DjangoConnector(alias="default") +def test_wrap_exceptions__integrity_error(db): + @procrastinate.contrib.django.app.task(queueing_lock="foo") + def foo(): + pass + + with pytest.raises(exceptions.AlreadyEnqueued): + foo.defer() + foo.defer() + + def test_get_sync_connector(django_connector): assert django_connector.get_sync_connector() is django_connector @@ -22,7 +33,7 @@ def test_open(django_connector): def test_open_pool(django_connector): - with pytest.raises(exceptions.ImproperlyConfigured): + with pytest.raises(django_exceptions.ImproperlyConfigured): django_connector.open(pool=object()) @@ -35,7 +46,7 @@ async def test_open_async(django_connector): async def test_open_pool_async(django_connector): - with pytest.raises(exceptions.ImproperlyConfigured): + with pytest.raises(django_exceptions.ImproperlyConfigured): await django_connector.open_async(pool=object()) @@ -112,5 +123,5 @@ async def test_get_worker_connector__error(django_connector, mocker): return_value=False, ) - with pytest.raises(exceptions.ImproperlyConfigured): + with pytest.raises(django_exceptions.ImproperlyConfigured): django_connector.get_worker_connector() diff --git a/tests/unit/contrib/django/test_django_connector.py b/tests/unit/contrib/django/test_django_connector.py new file mode 100644 index 000000000..40c8e32e3 --- /dev/null +++ b/tests/unit/contrib/django/test_django_connector.py @@ -0,0 +1,20 @@ +from __future__ import annotations + +import pytest +from django import db as django_db +from psycopg import errors as psycopg_errors + +from procrastinate import exceptions +from procrastinate.contrib.django import django_connector as django_connector_module + + +def test_wrap_exceptions__no_cause(): + with pytest.raises(django_db.DatabaseError): + with django_connector_module.wrap_exceptions(): + raise django_db.DatabaseError + + +def test_wrap_exceptions__with_cause(): + with pytest.raises(exceptions.ConnectorException): + with django_connector_module.wrap_exceptions(): + raise django_db.DatabaseError from psycopg_errors.Error() From fee2e94c3574f721e6a96803d5da39f060570b07 Mon Sep 17 00:00:00 2001 From: Joachim Jablon Date: Fri, 16 Aug 2024 00:06:53 +0200 Subject: [PATCH 32/59] Seems we now need setuptools everywhere. I don't get it. --- .pre-commit-config.yaml | 4 +-- poetry.lock | 64 ++++++++++++++++++++--------------------- pyproject.toml | 2 +- 3 files changed, 35 insertions(+), 35 deletions(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 146c7dd95..9a132c5c3 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -42,7 +42,7 @@ repos: - django-stubs==5.0.4 - django==4.2.15 - importlib-metadata==8.2.0 - - importlib-resources==6.4.0 + - importlib-resources==6.4.2 - psycopg2-binary==2.9.9 - psycopg[pool]==3.2.1 - python-dateutil==2.9.0.post0 @@ -50,7 +50,7 @@ repos: - sqlalchemy==2.0.32 - typing-extensions==4.12.2 - repo: https://github.com/astral-sh/ruff-pre-commit - rev: v0.5.7 + rev: v0.6.0 hooks: - id: ruff args: [--fix, --unsafe-fixes] diff --git a/poetry.lock b/poetry.lock index cfdfe7a6f..f79cc5100 100644 --- a/poetry.lock +++ b/poetry.lock @@ -628,21 +628,21 @@ test = ["flufl.flake8", "importlib-resources (>=1.3)", "jaraco.test (>=5.4)", "p [[package]] name = "importlib-resources" -version = "6.4.0" +version = "6.4.2" description = "Read resources from Python packages" optional = false python-versions = ">=3.8" files = [ - {file = "importlib_resources-6.4.0-py3-none-any.whl", hash = "sha256:50d10f043df931902d4194ea07ec57960f66a80449ff867bfe782b4c486ba78c"}, - {file = "importlib_resources-6.4.0.tar.gz", hash = "sha256:cdb2b453b8046ca4e3798eb1d84f3cce1446a0e8e7b5ef4efb600f19fc398145"}, + {file = "importlib_resources-6.4.2-py3-none-any.whl", hash = "sha256:8bba8c54a8a3afaa1419910845fa26ebd706dc716dd208d9b158b4b6966f5c5c"}, + {file = "importlib_resources-6.4.2.tar.gz", hash = "sha256:6cbfbefc449cc6e2095dd184691b7a12a04f40bc75dd4c55d31c34f174cdf57a"}, ] [package.dependencies] zipp = {version = ">=3.1.0", markers = "python_version < \"3.10\""} [package.extras] -docs = ["furo", "jaraco.packaging (>=9.3)", "jaraco.tidelift (>=1.4)", "rst.linker (>=1.9)", "sphinx (<7.2.5)", "sphinx (>=3.5)", "sphinx-lint"] -testing = ["jaraco.test (>=5.4)", "pytest (>=6)", "pytest-checkdocs (>=2.4)", "pytest-cov", "pytest-enabler (>=2.2)", "pytest-mypy", "pytest-ruff (>=0.2.1)", "zipp (>=3.17)"] +doc = ["furo", "jaraco.packaging (>=9.3)", "jaraco.tidelift (>=1.4)", "rst.linker (>=1.9)", "sphinx (>=3.5)", "sphinx-lint"] +test = ["jaraco.test (>=5.4)", "pytest (>=6,!=8.1.*)", "pytest-checkdocs (>=2.4)", "pytest-cov", "pytest-enabler (>=2.2)", "pytest-mypy", "pytest-ruff (>=0.2.1)", "zipp (>=3.17)"] [[package]] name = "iniconfig" @@ -1324,29 +1324,29 @@ use-chardet-on-py3 = ["chardet (>=3.0.2,<6)"] [[package]] name = "ruff" -version = "0.5.7" +version = "0.6.0" description = "An extremely fast Python linter and code formatter, written in Rust." optional = false python-versions = ">=3.7" files = [ - {file = "ruff-0.5.7-py3-none-linux_armv6l.whl", hash = "sha256:548992d342fc404ee2e15a242cdbea4f8e39a52f2e7752d0e4cbe88d2d2f416a"}, - {file = "ruff-0.5.7-py3-none-macosx_10_12_x86_64.whl", hash = "sha256:00cc8872331055ee017c4f1071a8a31ca0809ccc0657da1d154a1d2abac5c0be"}, - {file = "ruff-0.5.7-py3-none-macosx_11_0_arm64.whl", hash = "sha256:eaf3d86a1fdac1aec8a3417a63587d93f906c678bb9ed0b796da7b59c1114a1e"}, - {file = "ruff-0.5.7-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a01c34400097b06cf8a6e61b35d6d456d5bd1ae6961542de18ec81eaf33b4cb8"}, - {file = "ruff-0.5.7-py3-none-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:fcc8054f1a717e2213500edaddcf1dbb0abad40d98e1bd9d0ad364f75c763eea"}, - {file = "ruff-0.5.7-py3-none-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:7f70284e73f36558ef51602254451e50dd6cc479f8b6f8413a95fcb5db4a55fc"}, - {file = "ruff-0.5.7-py3-none-manylinux_2_17_ppc64.manylinux2014_ppc64.whl", hash = "sha256:a78ad870ae3c460394fc95437d43deb5c04b5c29297815a2a1de028903f19692"}, - {file = "ruff-0.5.7-py3-none-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:9ccd078c66a8e419475174bfe60a69adb36ce04f8d4e91b006f1329d5cd44bcf"}, - {file = "ruff-0.5.7-py3-none-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:7e31c9bad4ebf8fdb77b59cae75814440731060a09a0e0077d559a556453acbb"}, - {file = "ruff-0.5.7-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8d796327eed8e168164346b769dd9a27a70e0298d667b4ecee6877ce8095ec8e"}, - {file = "ruff-0.5.7-py3-none-musllinux_1_2_aarch64.whl", hash = "sha256:4a09ea2c3f7778cc635e7f6edf57d566a8ee8f485f3c4454db7771efb692c499"}, - {file = "ruff-0.5.7-py3-none-musllinux_1_2_armv7l.whl", hash = "sha256:a36d8dcf55b3a3bc353270d544fb170d75d2dff41eba5df57b4e0b67a95bb64e"}, - {file = "ruff-0.5.7-py3-none-musllinux_1_2_i686.whl", hash = "sha256:9369c218f789eefbd1b8d82a8cf25017b523ac47d96b2f531eba73770971c9e5"}, - {file = "ruff-0.5.7-py3-none-musllinux_1_2_x86_64.whl", hash = "sha256:b88ca3db7eb377eb24fb7c82840546fb7acef75af4a74bd36e9ceb37a890257e"}, - {file = "ruff-0.5.7-py3-none-win32.whl", hash = "sha256:33d61fc0e902198a3e55719f4be6b375b28f860b09c281e4bdbf783c0566576a"}, - {file = "ruff-0.5.7-py3-none-win_amd64.whl", hash = "sha256:083bbcbe6fadb93cd86709037acc510f86eed5a314203079df174c40bbbca6b3"}, - {file = "ruff-0.5.7-py3-none-win_arm64.whl", hash = "sha256:2dca26154ff9571995107221d0aeaad0e75a77b5a682d6236cf89a58c70b76f4"}, - {file = "ruff-0.5.7.tar.gz", hash = "sha256:8dfc0a458797f5d9fb622dd0efc52d796f23f0a1493a9527f4e49a550ae9a7e5"}, + {file = "ruff-0.6.0-py3-none-linux_armv6l.whl", hash = "sha256:92dcce923e5df265781e5fc76f9a1edad52201a7aafe56e586b90988d5239013"}, + {file = "ruff-0.6.0-py3-none-macosx_10_12_x86_64.whl", hash = "sha256:31b90ff9dc79ed476c04e957ba7e2b95c3fceb76148f2079d0d68a908d2cfae7"}, + {file = "ruff-0.6.0-py3-none-macosx_11_0_arm64.whl", hash = "sha256:6d834a9ec9f8287dd6c3297058b3a265ed6b59233db22593379ee38ebc4b9768"}, + {file = "ruff-0.6.0-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f2089267692696aba342179471831a085043f218706e642564812145df8b8d0d"}, + {file = "ruff-0.6.0-py3-none-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:aa62b423ee4bbd8765f2c1dbe8f6aac203e0583993a91453dc0a449d465c84da"}, + {file = "ruff-0.6.0-py3-none-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:7344e1a964b16b1137ea361d6516ce4ee61a0403fa94252a1913ecc1311adcae"}, + {file = "ruff-0.6.0-py3-none-manylinux_2_17_ppc64.manylinux2014_ppc64.whl", hash = "sha256:487f3a35c3f33bf82be212ce15dc6278ea854e35573a3f809442f73bec8b2760"}, + {file = "ruff-0.6.0-py3-none-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:75db409984077a793cf344d499165298a6f65449e905747ac65983b12e3e64b1"}, + {file = "ruff-0.6.0-py3-none-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:84908bd603533ecf1db456d8fc2665d1f4335d722e84bc871d3bbd2d1116c272"}, + {file = "ruff-0.6.0-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0f1749a0aef3ec41ed91a0e2127a6ae97d2e2853af16dbd4f3c00d7a3af726c5"}, + {file = "ruff-0.6.0-py3-none-musllinux_1_2_aarch64.whl", hash = "sha256:016fea751e2bcfbbd2f8cb19b97b37b3fd33148e4df45b526e87096f4e17354f"}, + {file = "ruff-0.6.0-py3-none-musllinux_1_2_armv7l.whl", hash = "sha256:6ae80f141b53b2e36e230017e64f5ea2def18fac14334ffceaae1b780d70c4f7"}, + {file = "ruff-0.6.0-py3-none-musllinux_1_2_i686.whl", hash = "sha256:eaaaf33ea4b3f63fd264d6a6f4a73fa224bbfda4b438ffea59a5340f4afa2bb5"}, + {file = "ruff-0.6.0-py3-none-musllinux_1_2_x86_64.whl", hash = "sha256:7667ddd1fc688150a7ca4137140867584c63309695a30016880caf20831503a0"}, + {file = "ruff-0.6.0-py3-none-win32.whl", hash = "sha256:ae48365aae60d40865a412356f8c6f2c0be1c928591168111eaf07eaefa6bea3"}, + {file = "ruff-0.6.0-py3-none-win_amd64.whl", hash = "sha256:774032b507c96f0c803c8237ce7d2ef3934df208a09c40fa809c2931f957fe5e"}, + {file = "ruff-0.6.0-py3-none-win_arm64.whl", hash = "sha256:a5366e8c3ae6b2dc32821749b532606c42e609a99b0ae1472cf601da931a048c"}, + {file = "ruff-0.6.0.tar.gz", hash = "sha256:272a81830f68f9bd19d49eaf7fa01a5545c5a2e86f32a9935bb0e4bb9a1db5b8"}, ] [[package]] @@ -1365,18 +1365,18 @@ sqlalchemy = "*" [[package]] name = "setuptools" -version = "72.1.0" +version = "72.2.0" description = "Easily download, build, install, upgrade, and uninstall Python packages" optional = false python-versions = ">=3.8" files = [ - {file = "setuptools-72.1.0-py3-none-any.whl", hash = "sha256:5a03e1860cf56bb6ef48ce186b0e557fdba433237481a9a625176c2831be15d1"}, - {file = "setuptools-72.1.0.tar.gz", hash = "sha256:8d243eff56d095e5817f796ede6ae32941278f542e0f941867cc05ae52b162ec"}, + {file = "setuptools-72.2.0-py3-none-any.whl", hash = "sha256:f11dd94b7bae3a156a95ec151f24e4637fb4fa19c878e4d191bfb8b2d82728c4"}, + {file = "setuptools-72.2.0.tar.gz", hash = "sha256:80aacbf633704e9c8bfa1d99fa5dd4dc59573efcf9e4042c13d3bcef91ac2ef9"}, ] [package.extras] core = ["importlib-metadata (>=6)", "importlib-resources (>=5.10.2)", "jaraco.text (>=3.7)", "more-itertools (>=8.8)", "ordered-set (>=3.1.1)", "packaging (>=24)", "platformdirs (>=2.6.2)", "tomli (>=2.0.1)", "wheel (>=0.43.0)"] -doc = ["furo", "jaraco.packaging (>=9.3)", "jaraco.tidelift (>=1.4)", "pygments-github-lexers (==0.0.5)", "pyproject-hooks (!=1.1)", "rst.linker (>=1.9)", "sphinx (>=3.5)", "sphinx-favicon", "sphinx-inline-tabs", "sphinx-lint", "sphinx-notfound-page (>=1,<2)", "sphinx-reredirects", "sphinxcontrib-towncrier"] +doc = ["furo", "jaraco.packaging (>=9.3)", "jaraco.tidelift (>=1.4)", "pygments-github-lexers (==0.0.5)", "pyproject-hooks (!=1.1)", "rst.linker (>=1.9)", "sphinx (>=3.5)", "sphinx-favicon", "sphinx-inline-tabs", "sphinx-lint", "sphinx-notfound-page (>=1,<2)", "sphinx-reredirects", "sphinxcontrib-towncrier", "towncrier (<24.7)"] test = ["build[virtualenv] (>=1.0.3)", "filelock (>=3.4.0)", "importlib-metadata", "ini2toml[lite] (>=0.14)", "jaraco.develop (>=7.21)", "jaraco.envs (>=2.2)", "jaraco.path (>=3.2.0)", "jaraco.test", "mypy (==1.11.*)", "packaging (>=23.2)", "pip (>=19.1)", "pyproject-hooks (!=1.1)", "pytest (>=6,!=8.1.*)", "pytest-checkdocs (>=2.4)", "pytest-cov", "pytest-enabler (>=2.2)", "pytest-home (>=0.5)", "pytest-mypy", "pytest-perf", "pytest-ruff (<0.4)", "pytest-ruff (>=0.2.1)", "pytest-ruff (>=0.3.2)", "pytest-subprocess", "pytest-timeout", "pytest-xdist (>=3)", "tomli", "tomli-w (>=1.0.0)", "virtualenv (>=13.0.0)", "wheel"] [[package]] @@ -1414,13 +1414,13 @@ files = [ [[package]] name = "soupsieve" -version = "2.5" +version = "2.6" description = "A modern CSS selector implementation for Beautiful Soup." optional = false python-versions = ">=3.8" files = [ - {file = "soupsieve-2.5-py3-none-any.whl", hash = "sha256:eaa337ff55a1579b6549dc679565eac1e3d000563bcb1c8ab0d0fefbc0c2cdc7"}, - {file = "soupsieve-2.5.tar.gz", hash = "sha256:5663d5a7b3bfaeee0bc4372e7fc48f9cff4940b3eec54a6451cc5299f1097690"}, + {file = "soupsieve-2.6-py3-none-any.whl", hash = "sha256:e72c4ff06e4fb6e4b5a9f0f55fe6e81514581fca1515028625d0f299c602ccc9"}, + {file = "soupsieve-2.6.tar.gz", hash = "sha256:e2e68417777af359ec65daac1057404a3c8a5455bb8abc36f1a9866ab1a51abb"}, ] [[package]] @@ -1841,4 +1841,4 @@ sqlalchemy = ["sqlalchemy"] [metadata] lock-version = "2.0" python-versions = "^3.8" -content-hash = "6c0aeb48705cf04301eaf320ef5df2399eae7fae612cdfad816b785c1623a715" +content-hash = "19c0fde5a638a2fad417755825b0925a1252d3ff052255b9f212829b567e456c" diff --git a/pyproject.toml b/pyproject.toml index 1a90c8a6c..57977e8a6 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -88,7 +88,7 @@ pytest-mock = "*" migra = "*" # migra depends on schemainspect, which has an implicit dependency on setuptools # (pkg_resources). -setuptools = { version = "*", python = ">=3.12" } +setuptools = { version = "*" } [tool.poetry.group.docs.dependencies] django = ">=2.2" From ec499dee582496a47e42b5deeff1e0ddb6cd9565 Mon Sep 17 00:00:00 2001 From: Joachim Jablon Date: Fri, 16 Aug 2024 00:36:45 +0200 Subject: [PATCH 33/59] Add Kai Schlamp as an author --- docs/conf.py | 5 +++-- pyproject.toml | 2 +- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/docs/conf.py b/docs/conf.py index 07f38d9dd..397deceb2 100644 --- a/docs/conf.py +++ b/docs/conf.py @@ -24,9 +24,10 @@ project = "Procrastinate" copyright = ( - f"""2019-{datetime.datetime.now().year}, Joachim Jablon, Eric Lemoine, PeopleDoc""" + f"2019-{datetime.datetime.now().year}, " + "Joachim Jablon, Eric Lemoine, Kai Schlamp, PeopleDoc" ) -author = "Joachim Jablon" +author = "Joachim Jablon, Eric Lemoine, Kai Schlamp" # -- General configuration --------------------------------------------------- diff --git a/pyproject.toml b/pyproject.toml index 57977e8a6..d193c6295 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -6,7 +6,7 @@ build-backend = "poetry_dynamic_versioning.backend" name = "procrastinate" version = "0.0.0" description = "Postgres-based distributed task processing library" -authors = ["Joachim Jablon", "Eric Lemoine"] +authors = ["Joachim Jablon", "Eric Lemoine", "Kai Schlamp"] license = "MIT License" classifiers = [ "Development Status :: 4 - Beta", From 0e0638518f762cb5932bc0ea530666b27fdf8381 Mon Sep 17 00:00:00 2001 From: Joachim Jablon Date: Fri, 16 Aug 2024 15:15:52 +0200 Subject: [PATCH 34/59] Update licence --- LICENSE.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/LICENSE.md b/LICENSE.md index 1634ad10c..355e6e8dc 100644 --- a/LICENSE.md +++ b/LICENSE.md @@ -1,7 +1,8 @@ MIT License Copyright (c) 2019-2021, PeopleDoc -Copyright (c) 2021-, Joachim Jablon, Eric Lemoine +Copyright (c) 2021-2023, Joachim Jablon, Eric Lemoine +Copyright (c) 2024-, Joachim Jablon, Kai Schlamp Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software From 6b39bac831ff66ed0d54175c2cd5d3312126538a Mon Sep 17 00:00:00 2001 From: Joachim Jablon Date: Sun, 11 Aug 2024 12:30:13 +0200 Subject: [PATCH 35/59] Remove sphinx-autodoc-typehints, upgrade Myst & Sphinx --- .pre-commit-config.yaml | 3 +- .readthedocs.yml | 2 +- docs/conf.py | 1 - poetry.lock | 150 ++++++++++++++++++++++++++++++++++------ pyproject.toml | 14 ++-- 5 files changed, 135 insertions(+), 35 deletions(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 9a132c5c3..28acbc2fb 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -41,12 +41,11 @@ repos: - croniter==3.0.3 - django-stubs==5.0.4 - django==4.2.15 - - importlib-metadata==8.2.0 - importlib-resources==6.4.2 - psycopg2-binary==2.9.9 - psycopg[pool]==3.2.1 - python-dateutil==2.9.0.post0 - - sphinx==7.1.2 + - sphinx==8.0.2 - sqlalchemy==2.0.32 - typing-extensions==4.12.2 - repo: https://github.com/astral-sh/ruff-pre-commit diff --git a/.readthedocs.yml b/.readthedocs.yml index 75c91a136..7bb20f908 100644 --- a/.readthedocs.yml +++ b/.readthedocs.yml @@ -8,7 +8,7 @@ version: 2 build: os: "ubuntu-22.04" tools: - python: "3.10" + python: "3" jobs: post_create_environment: - python -m pip install poetry diff --git a/docs/conf.py b/docs/conf.py index 397deceb2..51f40afc2 100644 --- a/docs/conf.py +++ b/docs/conf.py @@ -39,7 +39,6 @@ "myst_parser", "sphinx.ext.napoleon", "sphinx.ext.autodoc", - "sphinx_autodoc_typehints", "sphinxcontrib.programoutput", "sphinx_github_changelog", "sphinx_copybutton", diff --git a/poetry.lock b/poetry.lock index f79cc5100..8e50fec49 100644 --- a/poetry.lock +++ b/poetry.lock @@ -29,6 +29,17 @@ files = [ {file = "alabaster-0.7.13.tar.gz", hash = "sha256:a27a4a084d5e690e16e01e03ad2b2e552c61a65469419b907243193de1a84ae2"}, ] +[[package]] +name = "alabaster" +version = "1.0.0" +description = "A light, configurable Sphinx theme" +optional = false +python-versions = ">=3.10" +files = [ + {file = "alabaster-1.0.0-py3-none-any.whl", hash = "sha256:fc6786402dc3fcb2de3cabd5fe455a2db534b371124f1f21de8731783dec828b"}, + {file = "alabaster-1.0.0.tar.gz", hash = "sha256:c00dca57bca26fa62a6d7d0a9fcce65f3e026e9bfe33e9c538fd3fbb2144fd9e"}, +] + [[package]] name = "anyio" version = "4.4.0" @@ -463,11 +474,8 @@ name = "docutils" version = "0.20.1" description = "Docutils -- Python Documentation Utilities" optional = false -python-versions = ">=3.7" -files = [ - {file = "docutils-0.20.1-py3-none-any.whl", hash = "sha256:96f387a2c5562db4476f09f13bbab2192e764cac08ebbf3a34a95d9b1e4a59d6"}, - {file = "docutils-0.20.1.tar.gz", hash = "sha256:f08a4e276c3a1583a86dce3e34aba3fe04d02bba2dd51ed16106244e8a923e3b"}, -] +python-versions = "*" +files = [] [[package]] name = "dunamai" @@ -874,22 +882,22 @@ files = [ [[package]] name = "myst-parser" -version = "3.0.1" +version = "4.0.0" description = "An extended [CommonMark](https://spec.commonmark.org/) compliant parser," optional = false -python-versions = ">=3.8" +python-versions = ">=3.10" files = [ - {file = "myst_parser-3.0.1-py3-none-any.whl", hash = "sha256:6457aaa33a5d474aca678b8ead9b3dc298e89c68e67012e73146ea6fd54babf1"}, - {file = "myst_parser-3.0.1.tar.gz", hash = "sha256:88f0cb406cb363b077d176b51c476f62d60604d68a8dcdf4832e080441301a87"}, + {file = "myst_parser-4.0.0-py3-none-any.whl", hash = "sha256:b9317997552424448c6096c2558872fdb6f81d3ecb3a40ce84a7518798f3f28d"}, + {file = "myst_parser-4.0.0.tar.gz", hash = "sha256:851c9dfb44e36e56d15d05e72f02b80da21a9e0d07cba96baf5e2d476bb91531"}, ] [package.dependencies] -docutils = ">=0.18,<0.22" +docutils = ">=0.19,<0.22" jinja2 = "*" markdown-it-py = ">=3.0,<4.0" -mdit-py-plugins = ">=0.4,<1.0" +mdit-py-plugins = ">=0.4.1,<1.0" pyyaml = "*" -sphinx = ">=6,<8" +sphinx = ">=7,<9" [package.extras] code-style = ["pre-commit (>=3.0,<4.0)"] @@ -1459,23 +1467,39 @@ lint = ["docutils-stubs", "flake8 (>=3.5.0)", "flake8-simplify", "isort", "mypy test = ["cython", "filelock", "html5lib", "pytest (>=4.6)"] [[package]] -name = "sphinx-autodoc-typehints" -version = "2.0.1" -description = "Type hints (PEP 484) support for the Sphinx autodoc extension" +name = "sphinx" +version = "8.0.2" +description = "Python documentation generator" optional = false -python-versions = ">=3.8" +python-versions = ">=3.10" files = [ - {file = "sphinx_autodoc_typehints-2.0.1-py3-none-any.whl", hash = "sha256:f73ae89b43a799e587e39266672c1075b2ef783aeb382d3ebed77c38a3fc0149"}, - {file = "sphinx_autodoc_typehints-2.0.1.tar.gz", hash = "sha256:60ed1e3b2c970acc0aa6e877be42d48029a9faec7378a17838716cacd8c10b12"}, + {file = "sphinx-8.0.2-py3-none-any.whl", hash = "sha256:56173572ae6c1b9a38911786e206a110c9749116745873feae4f9ce88e59391d"}, + {file = "sphinx-8.0.2.tar.gz", hash = "sha256:0cce1ddcc4fd3532cf1dd283bc7d886758362c5c1de6598696579ce96d8ffa5b"}, ] [package.dependencies] -sphinx = ">=7.1.2" +alabaster = ">=0.7.14" +babel = ">=2.13" +colorama = {version = ">=0.4.6", markers = "sys_platform == \"win32\""} +docutils = ">=0.20,<0.22" +imagesize = ">=1.3" +Jinja2 = ">=3.1" +packaging = ">=23.0" +Pygments = ">=2.17" +requests = ">=2.30.0" +snowballstemmer = ">=2.2" +sphinxcontrib-applehelp = "*" +sphinxcontrib-devhelp = "*" +sphinxcontrib-htmlhelp = ">=2.0.0" +sphinxcontrib-jsmath = "*" +sphinxcontrib-qthelp = "*" +sphinxcontrib-serializinghtml = ">=1.1.9" +tomli = {version = ">=2", markers = "python_version < \"3.11\""} [package.extras] -docs = ["furo (>=2024.1.29)"] -numpy = ["nptyping (>=2.5)"] -testing = ["covdefaults (>=2.3)", "coverage (>=7.4.2)", "diff-cover (>=8.0.3)", "pytest (>=8.0.1)", "pytest-cov (>=4.1)", "sphobjinv (>=2.3.1)", "typing-extensions (>=4.9)"] +docs = ["sphinxcontrib-websupport"] +lint = ["flake8 (>=6.0)", "mypy (==1.11.0)", "pytest (>=6.0)", "ruff (==0.5.5)", "sphinx-lint (>=0.9)", "tomli (>=2)", "types-Pillow (==10.2.0.20240520)", "types-Pygments (==2.18.0.20240506)", "types-colorama (==0.4.15.20240311)", "types-defusedxml (==0.7.0.20240218)", "types-docutils (==0.21.0.20240724)", "types-requests (>=2.30.0)"] +test = ["cython (>=3.0)", "defusedxml (>=0.7.1)", "pytest (>=8.0)", "setuptools (>=70.0)", "typing_extensions (>=4.9)"] [[package]] name = "sphinx-basic-ng" @@ -1543,6 +1567,22 @@ files = [ lint = ["docutils-stubs", "flake8", "mypy"] test = ["pytest"] +[[package]] +name = "sphinxcontrib-applehelp" +version = "2.0.0" +description = "sphinxcontrib-applehelp is a Sphinx extension which outputs Apple help books" +optional = false +python-versions = ">=3.9" +files = [ + {file = "sphinxcontrib_applehelp-2.0.0-py3-none-any.whl", hash = "sha256:4cd3f0ec4ac5dd9c17ec65e9ab272c9b867ea77425228e68ecf08d6b28ddbdb5"}, + {file = "sphinxcontrib_applehelp-2.0.0.tar.gz", hash = "sha256:2f29ef331735ce958efa4734873f084941970894c6090408b079c61b2e1c06d1"}, +] + +[package.extras] +lint = ["mypy", "ruff (==0.5.5)", "types-docutils"] +standalone = ["Sphinx (>=5)"] +test = ["pytest"] + [[package]] name = "sphinxcontrib-devhelp" version = "1.0.2" @@ -1558,6 +1598,22 @@ files = [ lint = ["docutils-stubs", "flake8", "mypy"] test = ["pytest"] +[[package]] +name = "sphinxcontrib-devhelp" +version = "2.0.0" +description = "sphinxcontrib-devhelp is a sphinx extension which outputs Devhelp documents" +optional = false +python-versions = ">=3.9" +files = [ + {file = "sphinxcontrib_devhelp-2.0.0-py3-none-any.whl", hash = "sha256:aefb8b83854e4b0998877524d1029fd3e6879210422ee3780459e28a1f03a8a2"}, + {file = "sphinxcontrib_devhelp-2.0.0.tar.gz", hash = "sha256:411f5d96d445d1d73bb5d52133377b4248ec79db5c793ce7dbe59e074b4dd1ad"}, +] + +[package.extras] +lint = ["mypy", "ruff (==0.5.5)", "types-docutils"] +standalone = ["Sphinx (>=5)"] +test = ["pytest"] + [[package]] name = "sphinxcontrib-htmlhelp" version = "2.0.1" @@ -1573,6 +1629,22 @@ files = [ lint = ["docutils-stubs", "flake8", "mypy"] test = ["html5lib", "pytest"] +[[package]] +name = "sphinxcontrib-htmlhelp" +version = "2.1.0" +description = "sphinxcontrib-htmlhelp is a sphinx extension which renders HTML help files" +optional = false +python-versions = ">=3.9" +files = [ + {file = "sphinxcontrib_htmlhelp-2.1.0-py3-none-any.whl", hash = "sha256:166759820b47002d22914d64a075ce08f4c46818e17cfc9470a9786b759b19f8"}, + {file = "sphinxcontrib_htmlhelp-2.1.0.tar.gz", hash = "sha256:c9e2916ace8aad64cc13a0d233ee22317f2b9025b9cf3295249fa985cc7082e9"}, +] + +[package.extras] +lint = ["mypy", "ruff (==0.5.5)", "types-docutils"] +standalone = ["Sphinx (>=5)"] +test = ["html5lib", "pytest"] + [[package]] name = "sphinxcontrib-jsmath" version = "1.0.1" @@ -1616,6 +1688,22 @@ files = [ lint = ["docutils-stubs", "flake8", "mypy"] test = ["pytest"] +[[package]] +name = "sphinxcontrib-qthelp" +version = "2.0.0" +description = "sphinxcontrib-qthelp is a sphinx extension which outputs QtHelp documents" +optional = false +python-versions = ">=3.9" +files = [ + {file = "sphinxcontrib_qthelp-2.0.0-py3-none-any.whl", hash = "sha256:b18a828cdba941ccd6ee8445dbe72ffa3ef8cbe7505d8cd1fa0d42d3f2d5f3eb"}, + {file = "sphinxcontrib_qthelp-2.0.0.tar.gz", hash = "sha256:4fe7d0ac8fc171045be623aba3e2a8f613f8682731f9153bb2e40ece16b9bbab"}, +] + +[package.extras] +lint = ["mypy", "ruff (==0.5.5)", "types-docutils"] +standalone = ["Sphinx (>=5)"] +test = ["defusedxml (>=0.7.1)", "pytest"] + [[package]] name = "sphinxcontrib-serializinghtml" version = "1.1.5" @@ -1631,6 +1719,22 @@ files = [ lint = ["docutils-stubs", "flake8", "mypy"] test = ["pytest"] +[[package]] +name = "sphinxcontrib-serializinghtml" +version = "2.0.0" +description = "sphinxcontrib-serializinghtml is a sphinx extension which outputs \"serialized\" HTML files (json and pickle)" +optional = false +python-versions = ">=3.9" +files = [ + {file = "sphinxcontrib_serializinghtml-2.0.0-py3-none-any.whl", hash = "sha256:6e2cb0eef194e10c27ec0023bfeb25badbbb5868244cf5bc5bdc04e4464bf331"}, + {file = "sphinxcontrib_serializinghtml-2.0.0.tar.gz", hash = "sha256:e9d912827f872c029017a53f0ef2180b327c3f7fd23c87229f7a8e8b70031d4d"}, +] + +[package.extras] +lint = ["mypy", "ruff (==0.5.5)", "types-docutils"] +standalone = ["Sphinx (>=5)"] +test = ["pytest"] + [[package]] name = "sqlalchemy" version = "2.0.32" @@ -1841,4 +1945,4 @@ sqlalchemy = ["sqlalchemy"] [metadata] lock-version = "2.0" python-versions = "^3.8" -content-hash = "19c0fde5a638a2fad417755825b0925a1252d3ff052255b9f212829b567e456c" +content-hash = "c4354f07b502aa8452ed2d5779abb298bdd112daf7c11625480c2d556ea5aaf2" diff --git a/pyproject.toml b/pyproject.toml index d193c6295..856bfdb13 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -31,9 +31,8 @@ attrs = "*" contextlib2 = { version = "*", python = "<3.10" } croniter = "*" django = { version = ">=2.2", optional = true } -importlib-metadata = { version = "*", python = "<3.8" } importlib-resources = { version = ">=1.4", python = "<3.9" } -psycopg = { extras = ["pool"], version = "^3.1.13" } +psycopg = { extras = ["pool"], version = "*" } psycopg2-binary = { version = "*", optional = true } python-dateutil = "*" sqlalchemy = { version = "^2.0", optional = true } @@ -64,15 +63,15 @@ aiopg = "*" sqlalchemy = { extras = ["mypy"], version = "*" } psycopg2-binary = "*" psycopg = [ - { version = "^3.1.13", extras = [ + { version = "*", extras = [ "binary", "pool", ], markers = "sys_platform != 'darwin' or platform_machine != 'arm64'" }, - { version = "^3.1.13", extras = [ + { version = "*", extras = [ "binary", "pool", ], markers = "sys_platform == 'darwin' and platform_machine == 'arm64'", python = ">=3.10" }, - { version = "^3.1.13", extras = [ + { version = "*", extras = [ "pool", ], markers = "sys_platform == 'darwin' and platform_machine == 'arm64'", python = "<3.10" }, ] @@ -93,12 +92,11 @@ setuptools = { version = "*" } [tool.poetry.group.docs.dependencies] django = ">=2.2" furo = "*" -Sphinx = "*" -sphinx-autodoc-typehints = "*" +Sphinx = { version = ">=8", python = ">=3.10" } sphinx-copybutton = "*" sphinx-github-changelog = "*" sphinxcontrib-programoutput = "*" -myst-parser = "*" +myst-parser = { version = ">=4", python = ">=3.10" } [tool.poetry-dynamic-versioning] enable = true From ab995efa2cb621cb39d2df32d111f70ee0bbed24 Mon Sep 17 00:00:00 2001 From: Joachim Jablon Date: Sun, 11 Aug 2024 12:33:42 +0200 Subject: [PATCH 36/59] Fix docstrings --- procrastinate/app.py | 35 +++-- procrastinate/blueprints.py | 2 + procrastinate/builtin_tasks.py | 6 +- .../contrib/aiopg/aiopg_connector.py | 16 +-- .../contrib/django/django_connector.py | 2 +- procrastinate/contrib/django/utils.py | 2 +- .../contrib/psycopg2/psycopg2_connector.py | 12 +- procrastinate/job_context.py | 21 +-- procrastinate/jobs.py | 33 ++--- procrastinate/manager.py | 127 +++++++++--------- procrastinate/retry.py | 12 +- procrastinate/tasks.py | 60 ++++----- procrastinate/testing.py | 8 +- 13 files changed, 148 insertions(+), 188 deletions(-) diff --git a/procrastinate/app.py b/procrastinate/app.py index 13955a957..a29ee6880 100644 --- a/procrastinate/app.py +++ b/procrastinate/app.py @@ -23,14 +23,6 @@ class App(blueprints.Blueprint): and use it to decorate your tasks with `App.task`. You can run a worker with `App.run_worker`. - - Attributes - ---------- - tasks : ``Dict[str, tasks.Task]`` - The mapping of all tasks known by the app. Only procrastinate is expected to - make changes to this mapping. - job_manager : `manager.JobManager` - The `JobManager` linked to the application """ @classmethod @@ -95,7 +87,10 @@ def __init__( self.worker_defaults = worker_defaults or {} self.periodic_defaults = periodic_defaults or {} - self.job_manager = manager.JobManager(connector=self.connector) + #: The :py:class:`~manager.JobManager` linked to the application + self.job_manager: manager.JobManager = manager.JobManager( + connector=self.connector + ) self._register_builtin_tasks() @@ -113,7 +108,7 @@ def with_connector(self, connector: connector_module.BaseConnector) -> App: Returns ------- - `App` + : A new compatible app. """ app = App( @@ -137,7 +132,7 @@ def replace_connector( connector : The new connector to use. - Returns + Yields ------- `App` A new compatible app. @@ -174,7 +169,7 @@ def configure_task( Parameters ---------- - name : str + name: Name of the task. If not explicitly defined, this will be the dotted path to the task (``my.module.my_task``) @@ -183,7 +178,7 @@ def configure_task( Returns ------- - ``jobs.JobDeferrer`` + : Launch ``.defer(**task_kwargs)`` on this object to defer your job. """ from procrastinate import tasks @@ -227,32 +222,32 @@ async def run_worker_async(self, **kwargs) -> None: Parameters ---------- - queues : ``Optional[Iterable[str]]`` + queues: ``Optional[Iterable[str]]`` List of queues to listen to, or None to listen to every queue (defaults to ``None``). - wait : ``bool`` + wait: ``bool`` If False, the worker will terminate as soon as it has caught up with the queues. If True, the worker will work until it is stopped by a signal (``ctrl+c``, ``SIGINT``, ``SIGTERM``) (defaults to ``True``). - concurrency : ``int`` + concurrency: ``int`` Indicates how many asynchronous jobs the worker can run in parallel. Do not use concurrency if you have synchronous blocking tasks. See `howto/production/concurrency` (defaults to ``1``). - name : ``Optional[str]`` + name: ``Optional[str]`` Name of the worker. Will be passed in the `JobContext` and used in the logs (defaults to ``None`` which will result in the worker named ``worker``). - timeout : ``float`` + timeout: ``float`` Indicates the maximum duration (in seconds) the worker waits between each database job poll. Raising this parameter can lower the rate at which the worker makes queries to the database for requesting jobs. (defaults to 5.0) - listen_notify : ``bool`` + listen_notify: ``bool`` If ``True``, the worker will dedicate a connection from the pool to listening to database events, notifying of newly available jobs. If ``False``, the worker will just poll the database periodically (see ``timeout``). (defaults to ``True``) - delete_jobs : ``str`` + delete_jobs: ``str`` If ``always``, the worker will automatically delete all jobs on completion. If ``successful`` the worker will only delete successful jobs. If ``never``, the worker will keep the jobs in the database. diff --git a/procrastinate/blueprints.py b/procrastinate/blueprints.py index 0304cb42e..5f737d3b4 100644 --- a/procrastinate/blueprints.py +++ b/procrastinate/blueprints.py @@ -69,6 +69,8 @@ def my_task(): """ def __init__(self) -> None: + #: The mapping of all tasks known by the app. Only procrastinate is + #: expected to make changes to this mapping. self.tasks: dict[str, Task] = {} self.periodic_registry = periodic.PeriodicRegistry() self._check_stack() diff --git a/procrastinate/builtin_tasks.py b/procrastinate/builtin_tasks.py index c31afd5ef..422cc37c4 100644 --- a/procrastinate/builtin_tasks.py +++ b/procrastinate/builtin_tasks.py @@ -26,13 +26,13 @@ async def remove_old_jobs( queue : The name of the queue in which jobs will be deleted. If not specified, the task will delete jobs from all queues. - remove_error : ``Optional[bool]`` + remove_error: By default only successful jobs will be removed. When this parameter is True failed jobs will also be deleted. - remove_cancelled : ``Optional[bool]`` + remove_cancelled: By default only successful jobs will be removed. When this parameter is True cancelled jobs will also be deleted. - remove_aborted : ``Optional[bool]`` + remove_aborted: By default only successful jobs will be removed. When this parameter is True aborted jobs will also be deleted. """ diff --git a/procrastinate/contrib/aiopg/aiopg_connector.py b/procrastinate/contrib/aiopg/aiopg_connector.py index 40d4b8a22..c3ef93976 100644 --- a/procrastinate/contrib/aiopg/aiopg_connector.py +++ b/procrastinate/contrib/aiopg/aiopg_connector.py @@ -98,35 +98,35 @@ def __init__( Parameters ---------- - json_dumps : + json_dumps: The JSON dumps function to use for serializing job arguments. Defaults to the function used by psycopg2. See the `psycopg2 doc`_. - json_loads : + json_loads: The JSON loads function to use for deserializing job arguments. Defaults to the function used by psycopg2. See the `psycopg2 doc`_. Unused if the pool is externally created and set into the connector through the ``App.open_async`` method. - dsn : ``Optional[str]`` + dsn: ``Optional[str]`` Passed to aiopg. Default is "" instead of None, which means if no argument is passed, it will connect to localhost:5432 instead of a Unix-domain local socket file. - enable_json : ``bool`` + enable_json: ``bool`` Passed to aiopg. Default is False instead of True to avoid messing with the global state. enable_hstore: ``bool`` Passed to aiopg. Default is False instead of True to avoid messing with the global state. - enable_uuid : ``bool`` + enable_uuid: ``bool`` Passed to aiopg. Default is False instead of True to avoid messing with the global state. - cursor_factory : ``psycopg2.extensions.cursor`` + cursor_factory: ``psycopg2.extensions.cursor`` Passed to aiopg. Default is ``psycopg2.extras.RealDictCursor`` instead of standard cursor. There is no identified use case for changing this. - maxsize : ``int`` + maxsize: ``int`` Passed to aiopg. If value is 1, then listen/notify feature will be deactivated. - minsize : ``int`` + minsize: ``int`` Passed to aiopg. Initial connections are not opened when the connector is created, but at first use of the pool. """ diff --git a/procrastinate/contrib/django/django_connector.py b/procrastinate/contrib/django/django_connector.py index 42564d5cf..909c7ac8b 100644 --- a/procrastinate/contrib/django/django_connector.py +++ b/procrastinate/contrib/django/django_connector.py @@ -156,7 +156,7 @@ def get_worker_connector(self) -> connector.BaseAsyncConnector: Returns ------- - ``procrastinate.contrib.aiopg.AiopgConnector`` or ``procrastinate.contrib.psycopg3.PsycopgConnector`` + : A connector that can be used in a worker """ alias = settings.settings.DATABASE_ALIAS diff --git a/procrastinate/contrib/django/utils.py b/procrastinate/contrib/django/utils.py index c7b279f0a..9def57551 100644 --- a/procrastinate/contrib/django/utils.py +++ b/procrastinate/contrib/django/utils.py @@ -20,7 +20,7 @@ def connector_params(alias: str = "default") -> dict[str, Any]: Returns ------- - ``Dict[str, Any]`` + : Provide these keyword arguments when instantiating your connector """ wrapper = connections[alias] diff --git a/procrastinate/contrib/psycopg2/psycopg2_connector.py b/procrastinate/contrib/psycopg2/psycopg2_connector.py index 5c6e6b64f..bb847e95d 100644 --- a/procrastinate/contrib/psycopg2/psycopg2_connector.py +++ b/procrastinate/contrib/psycopg2/psycopg2_connector.py @@ -83,23 +83,23 @@ def __init__( Parameters ---------- - json_dumps : + json_dumps: The JSON dumps function to use for serializing job arguments. Defaults to the function used by psycopg2. See the `psycopg2 doc`_. - json_loads : + json_loads: The JSON loads function to use for deserializing job arguments. Defaults to the function used by psycopg2. See the `psycopg2 doc`_. Unused if the pool is externally created and set into the connector through the ``App.open`` method. - minconn : int + minconn: int Passed to psycopg2, default set to 1 (same as aiopg). - maxconn : int + maxconn: int Passed to psycopg2, default set to 10 (same as aiopg). - dsn : ``Optional[str]`` + dsn: ``Optional[str]`` Passed to psycopg2. Default is "" instead of None, which means if no argument is passed, it will connect to localhost:5432 instead of a Unix-domain local socket file. - cursor_factory : ``psycopg2.extensions.cursor`` + cursor_factory: ``psycopg2.extensions.cursor`` Passed to psycopg2. Default is ``psycopg2.extras.RealDictCursor`` instead of standard cursor. There is no identified use case for changing this. diff --git a/procrastinate/job_context.py b/procrastinate/job_context.py index a35fe5582..ad93f4425 100644 --- a/procrastinate/job_context.py +++ b/procrastinate/job_context.py @@ -40,28 +40,19 @@ class JobContext: Execution context of a running job. In theory, all attributes are optional. In practice, in a task, they will always be set to their proper value. - - Attributes - ---------- - app : `App` - Procrastinate `App` running this job - worker_name : ``str`` - Name of the worker (may be useful for logging) - worker_queues : ``Optional[Iterable[str]]`` - Queues listened by this worker - worker_id : ``int``` - In case there are multiple async sub-workers, this is the id of the sub-worker. - job : `Job` - Current `Job` instance - task : `Task` - Current `Task` instance """ + #: Procrastinate `App` running this job app: app_module.App | None = None + #: Name of the worker (may be useful for logging) worker_name: str | None = None + #: Queues listened by this worker worker_queues: Iterable[str] | None = None + #: In case there are multiple async sub-workers, this is the id of the sub-worker. worker_id: int | None = None + #: Corresponding :py:class:`~jobs.Job` job: jobs.Job | None = None + #: Corresponding :py:class:`~tasks.Task` task: tasks.Task | None = None job_result: JobResult = attr.ib(factory=JobResult) additional_context: dict = attr.ib(factory=dict) diff --git a/procrastinate/jobs.py b/procrastinate/jobs.py index bcd55a6d5..6a2560c01 100644 --- a/procrastinate/jobs.py +++ b/procrastinate/jobs.py @@ -48,42 +48,29 @@ class Job: """ A job is the launching of a specific task with specific values for the keyword arguments. - - Attributes - ---------- - id : - Internal id uniquely identifying the job. - status : - Status of the job. - priority : - Priority of the job. - queue : - Queue name the job will be run in. - lock : - No two jobs with the same lock string can run simultaneously - queueing_lock : - No two jobs with the same queueing lock can be waiting in the queue. - task_name : - Name of the associated task. - task_kwargs : - Arguments used to call the task. - scheduled_at : - Date and time after which the job is expected to run. - attempts : - Number of times the job has been tried. """ + #: Internal id uniquely identifying the job. id: int | None = None + #: Status of the job. status: str | None = None + #: Queue name the job will be run in. queue: str + #: Priority of the job. priority: int = DEFAULT_PRIORITY + #: No two jobs with the same lock string can run simultaneously lock: str | None + #: No two jobs with the same queueing lock can be waiting in the queue. queueing_lock: str | None + #: Name of the associated task. task_name: str + #: Arguments used to call the task. task_kwargs: types.JSONDict = attr.ib(factory=dict) + #: Date and time after which the job is expected to run. scheduled_at: datetime.datetime | None = attr.ib( default=None, validator=check_aware ) + #: Number of times the job has been tried. attempts: int = 0 @classmethod diff --git a/procrastinate/manager.py b/procrastinate/manager.py index 129b50962..d77261f17 100644 --- a/procrastinate/manager.py +++ b/procrastinate/manager.py @@ -29,11 +29,12 @@ async def defer_job_async(self, job: jobs.Job) -> jobs.Job: Parameters ---------- - job : `jobs.Job` + job: + The job to defer Returns ------- - `jobs.Job` + : A copy of the job instance with the id set. """ # Make sure this code stays synchronized with .defer_job() @@ -125,12 +126,12 @@ async def fetch_job(self, queues: Iterable[str] | None) -> jobs.Job | None: Parameters ---------- - queues : ``Optional[Iterable[str]]`` + queues: Filter by job queue names Returns ------- - ``Optional[jobs.Job]`` + : None if no suitable job was found. The job otherwise. """ @@ -156,17 +157,13 @@ async def get_stalled_jobs( Parameters ---------- - nb_seconds : ``int`` + nb_seconds: Only jobs that have been in ``doing`` state for longer than this will be returned - queue : ``Optional[str]`` + queue: Filter by job queue name - task_name : ``Optional[str]`` + task_name: Filter by job task name - - Returns - ------- - ``Iterable[jobs.Job]`` """ rows = await self.connector.execute_query_all_async( query=sql.queries["select_stalled_jobs"], @@ -191,15 +188,15 @@ async def delete_old_jobs( Parameters ---------- - nb_hours : ``int`` + nb_hours: Consider jobs that been in a final state for more than ``nb_hours`` - queue : ``Optional[str]`` + queue: Filter by job queue name - include_error : ``Optional[bool]`` + include_error: If ``True``, also consider errored jobs. ``False`` by default - include_cancelled : ``Optional[bool]`` + include_cancelled: If ``True``, also consider cancelled jobs. ``False`` by default. - include_aborted : ``Optional[bool]`` + include_aborted: If ``True``, also consider aborted jobs. ``False`` by default. """ # We only consider finished jobs by default @@ -229,8 +226,8 @@ async def finish_job( Parameters ---------- - job : `jobs.Job` - status : `jobs.Status` + job: + status: ``succeeded``, ``failed`` or ``aborted`` """ assert job.id # TODO remove this @@ -259,19 +256,19 @@ def cancel_job_by_id( Parameters ---------- - job_id : ``int`` + job_id: The id of the job to cancel - abort : ``bool`` + abort: If True, a job in ``doing`` state will be marked as ``aborting``, but the task itself has to respect the abortion request. If False, only jobs in ``todo`` state will be set to ``cancelled`` and won't be processed by a worker anymore. - delete_job : ``bool`` + delete_job: If True, the job will be deleted from the database after being cancelled. Does not affect the jobs that should be aborted. Returns ------- - ``bool`` + : If True, the job was cancelled (or its abortion was requested). If False, nothing was done: either there is no job with this id or it's not in a state where it may be cancelled (i.e. `todo` or `doing`) @@ -297,19 +294,19 @@ async def cancel_job_by_id_async( Parameters ---------- - job_id : ``int`` + job_id: The id of the job to cancel - abort : ``bool`` + abort: If True, a job in ``doing`` state will be marked as ``aborting``, but the task itself has to respect the abortion request. If False, only jobs in ``todo`` state will be set to ``cancelled`` and won't be processed by a worker anymore. - delete_job : ``bool`` + delete_job: If True, the job will be deleted from the database after being cancelled. Does not affect the jobs that should be aborted. Returns ------- - ``bool`` + : If True, the job was cancelled (or its abortion was requested). If False, nothing was done: either there is no job with this id or it's not in a state where it may be cancelled (i.e. `todo` or `doing`) @@ -333,12 +330,12 @@ def get_job_status(self, job_id: int) -> jobs.Status: Parameters ---------- - job_id : ``int`` + job_id: The id of the job to get the status of Returns ------- - `jobs.Status` + : """ result = self.connector.get_sync_connector().execute_query_one( query=sql.queries["get_job_status"], job_id=job_id @@ -351,12 +348,12 @@ async def get_job_status_async(self, job_id: int) -> jobs.Status: Parameters ---------- - job_id : ``int`` + job_id: The id of the job to get the status of Returns ------- - `jobs.Status` + : """ result = await self.connector.execute_query_one_async( query=sql.queries["get_job_status"], job_id=job_id @@ -376,18 +373,18 @@ async def retry_job( Parameters ---------- - job : `jobs.Job` - retry_at : ``Optional[datetime.datetime]`` + job: + retry_at: If set at present time or in the past, the job may be retried immediately. Otherwise, the job will be retried no sooner than this date & time. Should be timezone-aware (even if UTC). Defaults to present time. - priority : ``Optional[int]`` + priority: If set, the job will be retried with this priority. If not set, the priority remains unchanged. - queue : ``Optional[int]`` + queue: If set, the job will be retried on this queue. If not set, the queue remains unchanged. - lock : ``Optional[int]`` + lock: If set, the job will be retried with this lock. If not set, the lock remains unchanged. """ @@ -413,18 +410,18 @@ async def retry_job_by_id_async( Parameters ---------- - job_id : ``int`` - retry_at : ``datetime.datetime`` + job_id: + retry_at: If set at present time or in the past, the job may be retried immediately. Otherwise, the job will be retried no sooner than this date & time. Should be timezone-aware (even if UTC). - priority : ``Optional[int]`` + priority: If set, the job will be retried with this priority. If not set, the priority remains unchanged. - queue : ``Optional[int]`` + queue: If set, the job will be retried on this queue. If not set, the queue remains unchanged. - lock : ``Optional[int]`` + lock: If set, the job will be retried with this lock. If not set, the lock remains unchanged. """ @@ -469,9 +466,9 @@ async def listen_for_jobs( Parameters ---------- - event : ``asyncio.Event`` + event: This event will be set each time a defer operation occurs - queues : ``Optional[Iterable[str]]`` + queues: If ``None``, all defer operations will be considered. If an iterable of queue names is passed, only defer operations on those queues will be considered. Defaults to ``None`` @@ -487,7 +484,7 @@ async def check_connection_async(self) -> bool: Returns ------- - ``bool`` + : ``True`` if the table exists, ``False`` otherwise. """ result = await self.connector.execute_query_one_async( @@ -518,22 +515,22 @@ async def list_jobs_async( Parameters ---------- - id : ``int`` + id: Filter by job ID - queue : ``str`` + queue: Filter by job queue name - task : ``str`` + task: Filter by job task name - status : ``str`` + status: Filter by job status (``todo``/``doing``/``succeeded``/``failed``) - lock : ``str`` + lock: Filter by job lock - queueing_lock : ``str`` + queueing_lock: Filter by job queueing_lock Returns ------- - ``Iterable[jobs.Job]`` + : """ rows = await self.connector.execute_query_all_async( query=sql.queries["list_jobs"], @@ -581,18 +578,18 @@ async def list_queues_async( Parameters ---------- - queue : ``str`` + queue: Filter by job queue name - task : ``str`` + task: Filter by job task name - status : ``str`` + status: Filter by job status (``todo``/``doing``/``succeeded``/``failed``) - lock : ``str`` + lock: Filter by job lock Returns ------- - ``List[Dict[str, Any]]`` + : A list of dictionaries representing queues stats (``name``, ``jobs_count``, ``todo``, ``doing``, ``succeeded``, ``failed``, ``cancelled``, ``aborting``, ``aborted``). @@ -661,18 +658,18 @@ async def list_tasks_async( Parameters ---------- - queue : ``str`` + queue: Filter by job queue name - task : ``str`` + task: Filter by job task name - status : ``str`` + status: Filter by job status (``todo``/``doing``/``succeeded``/``failed``) - lock : ``str`` + lock: Filter by job lock Returns ------- - ``List[Dict[str, Any]]`` + : A list of dictionaries representing tasks stats (``name``, ``jobs_count``, ``todo``, ``doing``, ``succeeded``, ``failed``, ``cancelled``, ``aborting``, ``aborted``). @@ -741,18 +738,18 @@ async def list_locks_async( Parameters ---------- - queue : ``str`` + queue: Filter by job queue name - task : ``str`` + task: Filter by job task name - status : ``str`` + status: Filter by job status (``todo``/``doing``/``succeeded``/``failed``) - lock : ``str`` + lock: Filter by job lock Returns ------- - ``List[Dict[str, Any]]`` + : A list of dictionaries representing locks stats (``name``, ``jobs_count``, ``todo``, ``doing``, ``succeeded``, ``failed``, ``cancelled``, ``aborting``, ``aborted``). diff --git a/procrastinate/retry.py b/procrastinate/retry.py index 827a614df..a07341666 100644 --- a/procrastinate/retry.py +++ b/procrastinate/retry.py @@ -53,20 +53,20 @@ def __init__( Parameters ---------- - retry_at : ``Optional[datetime.datetime]`` + retry_at: If set at present time or in the past, the job may be retried immediately. Otherwise, the job will be retried no sooner than this date & time. Should be timezone-aware (even if UTC). Defaults to present time. - retry_in : ``Optional[types.TimeDeltaParams]`` + retry_in: If set, the job will be retried after this duration. If not set, the job will be retried immediately. - priority : ``Optional[int]`` + priority: If set, the job will be retried with this priority. If not set, the priority remains unchanged. - queue : ``Optional[int]`` + queue: If set, the job will be retried on this queue. If not set, the queue remains unchanged. - lock : ``Optional[int]`` + lock: If set, the job will be retried with this lock. If not set, the lock remains unchanged. """ @@ -127,7 +127,7 @@ def get_schedule_in(self, *, exception: BaseException, attempts: int) -> int | N Returns ------- - ``Optional[int]`` + : If a job should not be retried, this function should return None. Otherwise, it should return the duration after which to schedule the new job run, *in seconds*. diff --git a/procrastinate/tasks.py b/procrastinate/tasks.py index 55658a20b..7ae3afb68 100644 --- a/procrastinate/tasks.py +++ b/procrastinate/tasks.py @@ -66,31 +66,6 @@ class Task(Generic[P, Args]): """ A task is a function that should be executed later. It is linked to a default queue, and expects keyword arguments. - - Attributes - ---------- - name : ``str`` - Name of the task, usually the dotted path of the decorated function. - aliases : ``List[str]`` - Additional names for the task. - retry_strategy : `RetryStrategy` - Value indicating the retry conditions in case of - :py:class:`procrastinate.jobs.Job` error. - pass_context : ``bool`` - If ``True``, passes the task execution context as first positional argument on - :py:class:`procrastinate.jobs.Job` execution. - queue : ``str`` - Default queue to send deferred jobs to. The queue can be overridden when a - job is deferred. - priority : - Default priority (an integer) of jobs that are deferred from this task. - Jobs with higher priority are run first. Priority can be positive or negative. - If no default priority is set then the default priority is 0. - lock : ``Optional[str]`` - Default lock. The lock can be overridden when a job is deferred. - queueing_lock : ``Optional[str]`` - Default queueing lock. The queuing lock can be overridden when a job is - deferred. """ def __init__( @@ -110,16 +85,33 @@ def __init__( lock: str | None = None, queueing_lock: str | None = None, ): - self.queue = queue - self.priority = priority - self.blueprint = blueprint + #: Default queue to send deferred jobs to. The queue can be overridden + #: when a job is deferred. + self.queue: str = queue + #: Default priority (an integer) of jobs that are deferred from this + #: task. Jobs with higher priority are run first. Priority can be + #: positive or negative. If no default priority is set then the default + #: priority is 0. + self.priority: int = priority + self.blueprint: blueprints.Blueprint = blueprint self.func: Callable[P] = func - self.aliases = aliases if aliases else [] - self.retry_strategy = retry_module.get_retry_strategy(retry) + #: Additional names for the task. + self.aliases: list[str] = aliases if aliases else [] + #: Value indicating the retry conditions in case of + #: :py:class:`procrastinate.jobs.Job` error. + self.retry_strategy: retry_module.BaseRetryStrategy | None = ( + retry_module.get_retry_strategy(retry) + ) + #: Name of the task, usually the dotted path of the decorated function. self.name: str = name if name else self.full_path - self.pass_context = pass_context - self.lock = lock - self.queueing_lock = queueing_lock + #: If ``True``, passes the task execution context as first positional + #: argument on :py:class:`procrastinate.jobs.Job` execution. + self.pass_context: bool = pass_context + #: Default lock. The lock can be overridden when a job is deferred. + self.lock: str | None = lock + #: Default queueing lock. The queuing lock can be overridden when a job + #: is deferred. + self.queueing_lock: str | None = queueing_lock def add_namespace(self, namespace: str) -> None: """ @@ -190,7 +182,7 @@ def configure(self, **options: Unpack[ConfigureTaskOptions]) -> jobs.JobDeferrer Returns ------- - ``jobs.JobDeferrer`` + : An object with a ``defer`` method, identical to `Task.defer` Raises diff --git a/procrastinate/testing.py b/procrastinate/testing.py index 4af80bd2c..2bf5e864f 100644 --- a/procrastinate/testing.py +++ b/procrastinate/testing.py @@ -22,15 +22,11 @@ class InMemoryConnector(connector.BaseAsyncConnector): """ def __init__(self): - """ - Attributes - ---------- - jobs : ``Dict[int, Dict]`` - Mapping of ``{: }`` - """ self.reset() self.reverse_queries = {value: key for key, value in sql.queries.items()} self.reverse_queries[schema.SchemaManager.get_schema()] = "apply_schema" + #: Mapping of ``{: }`` + self.jobs: dict[int, JobRow] = {} def reset(self) -> None: """ From 54b23828b8873ee608caff3fe58c63d2649bbf64 Mon Sep 17 00:00:00 2001 From: Joachim Jablon Date: Sun, 11 Aug 2024 12:34:00 +0200 Subject: [PATCH 37/59] Fix autodoc configuration --- docs/conf.py | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/docs/conf.py b/docs/conf.py index 51f40afc2..d85b9409e 100644 --- a/docs/conf.py +++ b/docs/conf.py @@ -98,6 +98,13 @@ html_favicon = "favicon.ico" +# -- Options for sphinx.ext.autodoc ------------------------------------------ + +autodoc_typehints = "both" +autodoc_type_aliases = { + "JSONDict": "procrastinate.types.JSONDict", +} + # -- Options for sphinx_github_changelog --------------------------------- sphinx_github_changelog_token = os.environ.get("CHANGELOG_GITHUB_TOKEN") From a80e02559499627ddc0097366621dac05a394411 Mon Sep 17 00:00:00 2001 From: Joachim Jablon Date: Sun, 11 Aug 2024 12:34:09 +0200 Subject: [PATCH 38/59] Fix reference doc --- docs/reference.rst | 16 +++++----------- 1 file changed, 5 insertions(+), 11 deletions(-) diff --git a/docs/reference.rst b/docs/reference.rst index dc6302e0f..a0e9f60f3 100644 --- a/docs/reference.rst +++ b/docs/reference.rst @@ -7,33 +7,26 @@ App .. autoclass:: procrastinate.App :members: open, open_async, task, run_worker, run_worker_async, configure_task, from_path, add_tasks_from, add_task_alias, with_connector, periodic, + tasks, job_manager Connectors ---------- .. autoclass:: procrastinate.PsycopgConnector - :members: - :exclude-members: open_async, close_async .. autoclass:: procrastinate.SyncPsycopgConnector - :members: - :exclude-members: open, close .. autoclass:: procrastinate.contrib.aiopg.AiopgConnector - :members: - :exclude-members: open_async, close_async .. autoclass:: procrastinate.contrib.psycopg2.Psycopg2Connector - :members: - :exclude-members: open, close .. autoclass:: procrastinate.testing.InMemoryConnector - :members: reset - + :members: reset, jobs Tasks ----- .. autoclass:: procrastinate.tasks.Task - :members: defer, defer_async, configure + :members: defer, defer_async, configure, name, aliases, retry_strategy, + pass_context, queue, lock, queueing_lock When tasks are created with argument ``pass_context``, they are provided a `JobContext` argument: @@ -62,6 +55,7 @@ Jobs ---- .. autoclass:: procrastinate.jobs.Job + :members: Retry strategies From 52962b6b366841e16af79c457a73eb4f4857e3ac Mon Sep 17 00:00:00 2001 From: Joachim Jablon Date: Sun, 11 Aug 2024 12:38:03 +0200 Subject: [PATCH 39/59] Don't install docs dependencies in CI, and run pyright with more recent python --- .github/workflows/ci.yml | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 224d0f37b..f0db51ef4 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -48,7 +48,7 @@ jobs: - run: poetry env use "${{ matrix.python-version }}" - - run: poetry install --extras "django sqlalchemy" + - run: poetry install --extras "django sqlalchemy" --without "docs" - name: Run tests run: scripts/tests @@ -75,11 +75,14 @@ jobs: - uses: actions/setup-python@v5 with: - python-version: "3.8" # Important for importlib_metadata + python-version: "3.8" cache: "poetry" + - name: Use selected Python version + run: poetry env use 3.8 + - name: Install dependencies - run: poetry install --all-extras --with=types + run: poetry install --all-extras --with=types --without=docs - name: Activate virtualenv run: echo "$(poetry env info --path)/bin" >> $GITHUB_PATH From 4392aab7f2ab033384e50d960c5b835fdb6c0ed1 Mon Sep 17 00:00:00 2001 From: Joachim Jablon Date: Fri, 16 Aug 2024 15:30:55 +0200 Subject: [PATCH 40/59] Shenanigans to set Sphinx version --- .readthedocs.yml | 2 +- dev-env | 2 +- poetry.lock | 2 +- pyproject.toml | 5 +++++ 4 files changed, 8 insertions(+), 3 deletions(-) diff --git a/.readthedocs.yml b/.readthedocs.yml index 7bb20f908..19de0a4c5 100644 --- a/.readthedocs.yml +++ b/.readthedocs.yml @@ -8,7 +8,7 @@ version: 2 build: os: "ubuntu-22.04" tools: - python: "3" + python: "latest" jobs: post_create_environment: - python -m pip install poetry diff --git a/dev-env b/dev-env index b374a2a74..4543c2ffd 100755 --- a/dev-env +++ b/dev-env @@ -61,6 +61,6 @@ echo "We've gone ahead and set up a few additional commands for you:" echo "- htmlcov: Opens the test coverage results in your browser" echo "- htmldoc: Opens the locally built sphinx documentation in your browser" echo "- lint: Run code formatters & linters" -echo "- docs: Build doc" +echo "- docs: Build doc (note: needs 'poetry install --with docs' which needs a recent Python)" echo "" echo 'Quit the poetry shell with the command `deactivate`' diff --git a/poetry.lock b/poetry.lock index 8e50fec49..d697c51aa 100644 --- a/poetry.lock +++ b/poetry.lock @@ -1945,4 +1945,4 @@ sqlalchemy = ["sqlalchemy"] [metadata] lock-version = "2.0" python-versions = "^3.8" -content-hash = "c4354f07b502aa8452ed2d5779abb298bdd112daf7c11625480c2d556ea5aaf2" +content-hash = "94a265554ef42d9521bda4878cb93069758a2f7e4c52a5f63af06df31c90fe8d" diff --git a/pyproject.toml b/pyproject.toml index 856bfdb13..733d71f01 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -89,7 +89,12 @@ migra = "*" # (pkg_resources). setuptools = { version = "*" } +[tool.poetry.group.docs] +optional = true + [tool.poetry.group.docs.dependencies] +python = "^3.10" + django = ">=2.2" furo = "*" Sphinx = { version = ">=8", python = ">=3.10" } From 267311a1eb01a0ee21d3faaf5024f692560b726f Mon Sep 17 00:00:00 2001 From: Joachim Jablon Date: Fri, 16 Aug 2024 16:20:16 +0200 Subject: [PATCH 41/59] Poetry is not ready to support both Sphinx v8 for py3.10 and v7 for py3.9- --- .pre-commit-config.yaml | 2 +- poetry.lock | 151 ++++------------------------------------ pyproject.toml | 5 +- 3 files changed, 17 insertions(+), 141 deletions(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 28acbc2fb..7051beef2 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -45,7 +45,7 @@ repos: - psycopg2-binary==2.9.9 - psycopg[pool]==3.2.1 - python-dateutil==2.9.0.post0 - - sphinx==8.0.2 + - sphinx==7.1.2 - sqlalchemy==2.0.32 - typing-extensions==4.12.2 - repo: https://github.com/astral-sh/ruff-pre-commit diff --git a/poetry.lock b/poetry.lock index d697c51aa..2abc5d3d4 100644 --- a/poetry.lock +++ b/poetry.lock @@ -1,4 +1,4 @@ -# This file is automatically @generated by Poetry 1.8.2 and should not be changed by hand. +# This file is automatically @generated by Poetry 1.8.3 and should not be changed by hand. [[package]] name = "aiopg" @@ -29,17 +29,6 @@ files = [ {file = "alabaster-0.7.13.tar.gz", hash = "sha256:a27a4a084d5e690e16e01e03ad2b2e552c61a65469419b907243193de1a84ae2"}, ] -[[package]] -name = "alabaster" -version = "1.0.0" -description = "A light, configurable Sphinx theme" -optional = false -python-versions = ">=3.10" -files = [ - {file = "alabaster-1.0.0-py3-none-any.whl", hash = "sha256:fc6786402dc3fcb2de3cabd5fe455a2db534b371124f1f21de8731783dec828b"}, - {file = "alabaster-1.0.0.tar.gz", hash = "sha256:c00dca57bca26fa62a6d7d0a9fcce65f3e026e9bfe33e9c538fd3fbb2144fd9e"}, -] - [[package]] name = "anyio" version = "4.4.0" @@ -474,8 +463,11 @@ name = "docutils" version = "0.20.1" description = "Docutils -- Python Documentation Utilities" optional = false -python-versions = "*" -files = [] +python-versions = ">=3.7" +files = [ + {file = "docutils-0.20.1-py3-none-any.whl", hash = "sha256:96f387a2c5562db4476f09f13bbab2192e764cac08ebbf3a34a95d9b1e4a59d6"}, + {file = "docutils-0.20.1.tar.gz", hash = "sha256:f08a4e276c3a1583a86dce3e34aba3fe04d02bba2dd51ed16106244e8a923e3b"}, +] [[package]] name = "dunamai" @@ -882,22 +874,22 @@ files = [ [[package]] name = "myst-parser" -version = "4.0.0" +version = "3.0.1" description = "An extended [CommonMark](https://spec.commonmark.org/) compliant parser," optional = false -python-versions = ">=3.10" +python-versions = ">=3.8" files = [ - {file = "myst_parser-4.0.0-py3-none-any.whl", hash = "sha256:b9317997552424448c6096c2558872fdb6f81d3ecb3a40ce84a7518798f3f28d"}, - {file = "myst_parser-4.0.0.tar.gz", hash = "sha256:851c9dfb44e36e56d15d05e72f02b80da21a9e0d07cba96baf5e2d476bb91531"}, + {file = "myst_parser-3.0.1-py3-none-any.whl", hash = "sha256:6457aaa33a5d474aca678b8ead9b3dc298e89c68e67012e73146ea6fd54babf1"}, + {file = "myst_parser-3.0.1.tar.gz", hash = "sha256:88f0cb406cb363b077d176b51c476f62d60604d68a8dcdf4832e080441301a87"}, ] [package.dependencies] -docutils = ">=0.19,<0.22" +docutils = ">=0.18,<0.22" jinja2 = "*" markdown-it-py = ">=3.0,<4.0" -mdit-py-plugins = ">=0.4.1,<1.0" +mdit-py-plugins = ">=0.4,<1.0" pyyaml = "*" -sphinx = ">=7,<9" +sphinx = ">=6,<8" [package.extras] code-style = ["pre-commit (>=3.0,<4.0)"] @@ -1466,41 +1458,6 @@ docs = ["sphinxcontrib-websupport"] lint = ["docutils-stubs", "flake8 (>=3.5.0)", "flake8-simplify", "isort", "mypy (>=0.990)", "ruff", "sphinx-lint", "types-requests"] test = ["cython", "filelock", "html5lib", "pytest (>=4.6)"] -[[package]] -name = "sphinx" -version = "8.0.2" -description = "Python documentation generator" -optional = false -python-versions = ">=3.10" -files = [ - {file = "sphinx-8.0.2-py3-none-any.whl", hash = "sha256:56173572ae6c1b9a38911786e206a110c9749116745873feae4f9ce88e59391d"}, - {file = "sphinx-8.0.2.tar.gz", hash = "sha256:0cce1ddcc4fd3532cf1dd283bc7d886758362c5c1de6598696579ce96d8ffa5b"}, -] - -[package.dependencies] -alabaster = ">=0.7.14" -babel = ">=2.13" -colorama = {version = ">=0.4.6", markers = "sys_platform == \"win32\""} -docutils = ">=0.20,<0.22" -imagesize = ">=1.3" -Jinja2 = ">=3.1" -packaging = ">=23.0" -Pygments = ">=2.17" -requests = ">=2.30.0" -snowballstemmer = ">=2.2" -sphinxcontrib-applehelp = "*" -sphinxcontrib-devhelp = "*" -sphinxcontrib-htmlhelp = ">=2.0.0" -sphinxcontrib-jsmath = "*" -sphinxcontrib-qthelp = "*" -sphinxcontrib-serializinghtml = ">=1.1.9" -tomli = {version = ">=2", markers = "python_version < \"3.11\""} - -[package.extras] -docs = ["sphinxcontrib-websupport"] -lint = ["flake8 (>=6.0)", "mypy (==1.11.0)", "pytest (>=6.0)", "ruff (==0.5.5)", "sphinx-lint (>=0.9)", "tomli (>=2)", "types-Pillow (==10.2.0.20240520)", "types-Pygments (==2.18.0.20240506)", "types-colorama (==0.4.15.20240311)", "types-defusedxml (==0.7.0.20240218)", "types-docutils (==0.21.0.20240724)", "types-requests (>=2.30.0)"] -test = ["cython (>=3.0)", "defusedxml (>=0.7.1)", "pytest (>=8.0)", "setuptools (>=70.0)", "typing_extensions (>=4.9)"] - [[package]] name = "sphinx-basic-ng" version = "1.0.0b2" @@ -1567,22 +1524,6 @@ files = [ lint = ["docutils-stubs", "flake8", "mypy"] test = ["pytest"] -[[package]] -name = "sphinxcontrib-applehelp" -version = "2.0.0" -description = "sphinxcontrib-applehelp is a Sphinx extension which outputs Apple help books" -optional = false -python-versions = ">=3.9" -files = [ - {file = "sphinxcontrib_applehelp-2.0.0-py3-none-any.whl", hash = "sha256:4cd3f0ec4ac5dd9c17ec65e9ab272c9b867ea77425228e68ecf08d6b28ddbdb5"}, - {file = "sphinxcontrib_applehelp-2.0.0.tar.gz", hash = "sha256:2f29ef331735ce958efa4734873f084941970894c6090408b079c61b2e1c06d1"}, -] - -[package.extras] -lint = ["mypy", "ruff (==0.5.5)", "types-docutils"] -standalone = ["Sphinx (>=5)"] -test = ["pytest"] - [[package]] name = "sphinxcontrib-devhelp" version = "1.0.2" @@ -1598,22 +1539,6 @@ files = [ lint = ["docutils-stubs", "flake8", "mypy"] test = ["pytest"] -[[package]] -name = "sphinxcontrib-devhelp" -version = "2.0.0" -description = "sphinxcontrib-devhelp is a sphinx extension which outputs Devhelp documents" -optional = false -python-versions = ">=3.9" -files = [ - {file = "sphinxcontrib_devhelp-2.0.0-py3-none-any.whl", hash = "sha256:aefb8b83854e4b0998877524d1029fd3e6879210422ee3780459e28a1f03a8a2"}, - {file = "sphinxcontrib_devhelp-2.0.0.tar.gz", hash = "sha256:411f5d96d445d1d73bb5d52133377b4248ec79db5c793ce7dbe59e074b4dd1ad"}, -] - -[package.extras] -lint = ["mypy", "ruff (==0.5.5)", "types-docutils"] -standalone = ["Sphinx (>=5)"] -test = ["pytest"] - [[package]] name = "sphinxcontrib-htmlhelp" version = "2.0.1" @@ -1629,22 +1554,6 @@ files = [ lint = ["docutils-stubs", "flake8", "mypy"] test = ["html5lib", "pytest"] -[[package]] -name = "sphinxcontrib-htmlhelp" -version = "2.1.0" -description = "sphinxcontrib-htmlhelp is a sphinx extension which renders HTML help files" -optional = false -python-versions = ">=3.9" -files = [ - {file = "sphinxcontrib_htmlhelp-2.1.0-py3-none-any.whl", hash = "sha256:166759820b47002d22914d64a075ce08f4c46818e17cfc9470a9786b759b19f8"}, - {file = "sphinxcontrib_htmlhelp-2.1.0.tar.gz", hash = "sha256:c9e2916ace8aad64cc13a0d233ee22317f2b9025b9cf3295249fa985cc7082e9"}, -] - -[package.extras] -lint = ["mypy", "ruff (==0.5.5)", "types-docutils"] -standalone = ["Sphinx (>=5)"] -test = ["html5lib", "pytest"] - [[package]] name = "sphinxcontrib-jsmath" version = "1.0.1" @@ -1688,22 +1597,6 @@ files = [ lint = ["docutils-stubs", "flake8", "mypy"] test = ["pytest"] -[[package]] -name = "sphinxcontrib-qthelp" -version = "2.0.0" -description = "sphinxcontrib-qthelp is a sphinx extension which outputs QtHelp documents" -optional = false -python-versions = ">=3.9" -files = [ - {file = "sphinxcontrib_qthelp-2.0.0-py3-none-any.whl", hash = "sha256:b18a828cdba941ccd6ee8445dbe72ffa3ef8cbe7505d8cd1fa0d42d3f2d5f3eb"}, - {file = "sphinxcontrib_qthelp-2.0.0.tar.gz", hash = "sha256:4fe7d0ac8fc171045be623aba3e2a8f613f8682731f9153bb2e40ece16b9bbab"}, -] - -[package.extras] -lint = ["mypy", "ruff (==0.5.5)", "types-docutils"] -standalone = ["Sphinx (>=5)"] -test = ["defusedxml (>=0.7.1)", "pytest"] - [[package]] name = "sphinxcontrib-serializinghtml" version = "1.1.5" @@ -1719,22 +1612,6 @@ files = [ lint = ["docutils-stubs", "flake8", "mypy"] test = ["pytest"] -[[package]] -name = "sphinxcontrib-serializinghtml" -version = "2.0.0" -description = "sphinxcontrib-serializinghtml is a sphinx extension which outputs \"serialized\" HTML files (json and pickle)" -optional = false -python-versions = ">=3.9" -files = [ - {file = "sphinxcontrib_serializinghtml-2.0.0-py3-none-any.whl", hash = "sha256:6e2cb0eef194e10c27ec0023bfeb25badbbb5868244cf5bc5bdc04e4464bf331"}, - {file = "sphinxcontrib_serializinghtml-2.0.0.tar.gz", hash = "sha256:e9d912827f872c029017a53f0ef2180b327c3f7fd23c87229f7a8e8b70031d4d"}, -] - -[package.extras] -lint = ["mypy", "ruff (==0.5.5)", "types-docutils"] -standalone = ["Sphinx (>=5)"] -test = ["pytest"] - [[package]] name = "sqlalchemy" version = "2.0.32" @@ -1945,4 +1822,4 @@ sqlalchemy = ["sqlalchemy"] [metadata] lock-version = "2.0" python-versions = "^3.8" -content-hash = "94a265554ef42d9521bda4878cb93069758a2f7e4c52a5f63af06df31c90fe8d" +content-hash = "ac5a99fe7f7c8531669219ac47284b5b483282a953c12d3b997c92a373d241ae" diff --git a/pyproject.toml b/pyproject.toml index 733d71f01..3ac25d99b 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -93,15 +93,14 @@ setuptools = { version = "*" } optional = true [tool.poetry.group.docs.dependencies] -python = "^3.10" django = ">=2.2" furo = "*" -Sphinx = { version = ">=8", python = ">=3.10" } +Sphinx = "*" sphinx-copybutton = "*" sphinx-github-changelog = "*" sphinxcontrib-programoutput = "*" -myst-parser = { version = ">=4", python = ">=3.10" } +myst-parser = "*" [tool.poetry-dynamic-versioning] enable = true From ea08fb3ab009522add257d18029dde0b5edc9103 Mon Sep 17 00:00:00 2001 From: Joachim Jablon Date: Fri, 16 Aug 2024 16:23:19 +0200 Subject: [PATCH 42/59] Include all extras in tests --- .github/workflows/ci.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index f0db51ef4..e0f9bcaea 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -48,7 +48,7 @@ jobs: - run: poetry env use "${{ matrix.python-version }}" - - run: poetry install --extras "django sqlalchemy" --without "docs" + - run: poetry install --all-extras - name: Run tests run: scripts/tests @@ -82,7 +82,7 @@ jobs: run: poetry env use 3.8 - name: Install dependencies - run: poetry install --all-extras --with=types --without=docs + run: poetry install --all-extras --with=types - name: Activate virtualenv run: echo "$(poetry env info --path)/bin" >> $GITHUB_PATH From 643a9ec5e1d3b672ab0849be751346bd66404a17 Mon Sep 17 00:00:00 2001 From: Joachim Jablon Date: Fri, 16 Aug 2024 16:28:42 +0200 Subject: [PATCH 43/59] Remove extraneous "poetry env use": actions/setup-python@v5 does it --- .github/workflows/ci.yml | 5 ----- 1 file changed, 5 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index e0f9bcaea..9f22d8add 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -46,8 +46,6 @@ jobs: python-version: "${{ matrix.python-version }}" cache: "poetry" - - run: poetry env use "${{ matrix.python-version }}" - - run: poetry install --all-extras - name: Run tests @@ -78,9 +76,6 @@ jobs: python-version: "3.8" cache: "poetry" - - name: Use selected Python version - run: poetry env use 3.8 - - name: Install dependencies run: poetry install --all-extras --with=types From 66ac98e0f24f5a6b2531b819533bc63109c34728 Mon Sep 17 00:00:00 2001 From: Joachim Jablon Date: Fri, 16 Aug 2024 17:40:10 +0200 Subject: [PATCH 44/59] Fix Django + cron using the wrong connector --- docs/howto/advanced/sync_defer.md | 18 ------------- docs/howto/django/scripts.md | 4 +-- docs/howto/django/tests.md | 22 ++++++++-------- docs/howto/production/testing.md | 4 +-- procrastinate/app.py | 26 ++++++++++++++----- .../management/commands/procrastinate.py | 10 +++++-- .../integration/contrib/django/test_models.py | 14 +++++----- 7 files changed, 50 insertions(+), 48 deletions(-) diff --git a/docs/howto/advanced/sync_defer.md b/docs/howto/advanced/sync_defer.md index 4f493d1b0..629cfb4b9 100644 --- a/docs/howto/advanced/sync_defer.md +++ b/docs/howto/advanced/sync_defer.md @@ -55,24 +55,6 @@ app = App(connector=SQLAlchemyPsycopg2Connector()) app.open(engine) ``` -## Having multiple apps - -If you need to have multiple connectors interact with the tasks, you can -create multiple synchronized apps with {py:meth}`App.with_connector`: - -``` -import procrastinate - - -app = procrastinate.App( - connector=procrastinate.PsycopgConnector(...), -) - -sync_app = app.with_connector( - connector=procrastinate.SyncPsycopgConnector(...), -) -``` - ## Procrastinate's automatic connector selection Async connectors are able to summon their synchronous counterpart when needed diff --git a/docs/howto/django/scripts.md b/docs/howto/django/scripts.md index 57b0aea04..576d55e12 100644 --- a/docs/howto/django/scripts.md +++ b/docs/howto/django/scripts.md @@ -21,8 +21,8 @@ def main(): django.setup() # By default, the app uses the Django database connection, which is unsuitable # for the worker. - app = app.with_connector(app.connector.get_worker_connector()) - app.run_worker() + with app.replace_connector(app.connector.get_worker_connector()): + app.run_worker() if __name__ == "__main__": main() diff --git a/docs/howto/django/tests.md b/docs/howto/django/tests.md index dd642c366..37dd9e266 100644 --- a/docs/howto/django/tests.md +++ b/docs/howto/django/tests.md @@ -24,8 +24,8 @@ def app(): # Replace the connector in the current app # Note that this fixture gives you the app back for convenience, but it's # the same instance as you'd get with `procrastinate.contrib.django.app`. - with procrastinate_app.current_app.replace_connector(in_memory) as app_with_connector: - yield app_with_connector + with procrastinate_app.current_app.replace_connector(in_memory) as app: + yield app def test_my_task(app): # Run the task @@ -126,8 +126,8 @@ class TestingTaskClass(TransactionTestCase): my_task.defer(a=1, b=2) # Start worker - app = app.with_connector(app.connector.get_worker_connector()) - app.run_worker(wait=False, install_signal_handlers=False, listen_notify=False) + with app.replace_connector(app.connector.get_worker_connector()) + app.run_worker(wait=False, install_signal_handlers=False, listen_notify=False) # Check task has been executed assert ProcrastinateJob.objects.filter(task_name="my_task").status == "succeeded" @@ -144,8 +144,8 @@ def test_task(): my_task.defer(a=1, b=2) # Start worker - app = app.with_connector(app.connector.get_worker_connector()) - app.run_worker(wait=False, install_signal_handlers=False, listen_notify=False) + with app.replace_connector(app.connector.get_worker_connector()) + app.run_worker(wait=False, install_signal_handlers=False, listen_notify=False) # Check task has been executed assert ProcrastinateJob.objects.filter(task_name="my_task").status == "succeeded" @@ -153,11 +153,11 @@ def test_task(): # Or with a fixture @pytest.fixture def worker(transactional_db): - def _(): - app = app.with_connector(app.connector.get_worker_connector()) - app.run_worker(wait=False, install_signal_handlers=False, listen_notify=False) - return app - return _ + with app.replace_connector(app.connector.get_worker_connector()) + def f(): + app.run_worker(wait=False, install_signal_handlers=False, listen_notify=False) + return app + yield f def test_task(worker): # Run tasks diff --git a/docs/howto/production/testing.md b/docs/howto/production/testing.md index d9699ecbf..418735a3d 100644 --- a/docs/howto/production/testing.md +++ b/docs/howto/production/testing.md @@ -17,8 +17,8 @@ def app(): # Replace the connector in the current app # Note that this fixture gives you the app back for covenience, # but it's the same instance as `my_app`. - with my_app.replace_connector(in_memory) as app_with_connector: - yield app_with_connector + with my_app.replace_connector(in_memory) as app: + yield app def test_my_task(app): diff --git a/procrastinate/app.py b/procrastinate/app.py index a29ee6880..072aa5738 100644 --- a/procrastinate/app.py +++ b/procrastinate/app.py @@ -94,12 +94,18 @@ def __init__( self._register_builtin_tasks() - def with_connector(self, connector: connector_module.BaseConnector) -> App: + def with_connector( + self, + connector: connector_module.BaseConnector, + ) -> App: """ Create another app instance sychronized with this one, with a different - connector. For all things regarding periodic tasks, the original app - (and its original connector) will be used, even when the new app's - methods are used. + connector. + + .. deprecated:: 2.14.0 + Use `replace_connector` instead. Because this method creates a new + app that references the same tasks, and the task have a link + back to the app, using this method can lead to unexpected behavior. Parameters ---------- @@ -109,7 +115,7 @@ def with_connector(self, connector: connector_module.BaseConnector) -> App: Returns ------- : - A new compatible app. + A new app with the same tasks. """ app = App( connector=connector, @@ -126,6 +132,12 @@ def replace_connector( ) -> Iterator[App]: """ Replace the connector of the app while in the context block, then restore it. + The context variable is the same app as this method is called on. + + >>> with app.replace_connector(new_connector) as app2: + ... ... + ... # app and app2 are the same object + Parameters ---------- @@ -134,8 +146,8 @@ def replace_connector( Yields ------- - `App` - A new compatible app. + : + A context manager that yields the same app with the new connector. """ old_connector = self.connector self.connector = connector diff --git a/procrastinate/contrib/django/management/commands/procrastinate.py b/procrastinate/contrib/django/management/commands/procrastinate.py index 2a66f2637..22bf59f17 100644 --- a/procrastinate/contrib/django/management/commands/procrastinate.py +++ b/procrastinate/contrib/django/management/commands/procrastinate.py @@ -1,6 +1,7 @@ from __future__ import annotations import asyncio +import contextlib from django.core.management.base import BaseCommand @@ -24,6 +25,11 @@ def add_arguments(self, parser): def handle(self, *args, **kwargs): kwargs = {k: v for k, v in kwargs.items() if k not in self._django_options} + context = contextlib.nullcontext() + if isinstance(app.connector, django_connector.DjangoConnector): - kwargs["app"] = app.with_connector(app.connector.get_worker_connector()) - asyncio.run(cli.execute_command(kwargs)) + kwargs["app"] = app + context = app.replace_connector(app.connector.get_worker_connector()) + + with context: + asyncio.run(cli.execute_command(kwargs)) diff --git a/tests/integration/contrib/django/test_models.py b/tests/integration/contrib/django/test_models.py index 022c81017..49615d51c 100644 --- a/tests/integration/contrib/django/test_models.py +++ b/tests/integration/contrib/django/test_models.py @@ -111,12 +111,14 @@ def my_task(timestamp): pass django_app = procrastinate.contrib.django.app - app = django_app.with_connector(django_app.connector.get_worker_connector()) - async with app.open_async(): - try: - await asyncio.wait_for(app.run_worker_async(), timeout=0.1) - except asyncio.TimeoutError: - pass + with django_app.replace_connector( + django_app.connector.get_worker_connector() + ) as app: + async with app.open_async(): + try: + await asyncio.wait_for(app.run_worker_async(), timeout=0.1) + except asyncio.TimeoutError: + pass periodic_defers = [] async for element in models.ProcrastinatePeriodicDefer.objects.values().all(): From 6c9bb65e9d465a59340fd2c1e73d65bf827c3e61 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Sat, 17 Aug 2024 01:16:52 +0000 Subject: [PATCH 45/59] chore(deps): update all dependencies --- .pre-commit-config.yaml | 6 +++--- poetry.lock | 38 +++++++++++++++++++------------------- 2 files changed, 22 insertions(+), 22 deletions(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 7051beef2..f788fdc18 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -29,7 +29,7 @@ repos: - id: trailing-whitespace - id: mixed-line-ending - repo: https://github.com/RobertCraigie/pyright-python - rev: v1.1.375 + rev: v1.1.376 hooks: - id: pyright additional_dependencies: @@ -49,7 +49,7 @@ repos: - sqlalchemy==2.0.32 - typing-extensions==4.12.2 - repo: https://github.com/astral-sh/ruff-pre-commit - rev: v0.6.0 + rev: v0.6.1 hooks: - id: ruff args: [--fix, --unsafe-fixes] @@ -59,7 +59,7 @@ repos: hooks: - id: doc8 - repo: https://github.com/ewjoachim/poetry-to-pre-commit - rev: 2.1.0 + rev: 2.2.0 hooks: - id: sync-repos args: [--map=pyright-python=pyright, --map=ruff-pre-commit=ruff] diff --git a/poetry.lock b/poetry.lock index 2abc5d3d4..bce5a7cd2 100644 --- a/poetry.lock +++ b/poetry.lock @@ -1324,29 +1324,29 @@ use-chardet-on-py3 = ["chardet (>=3.0.2,<6)"] [[package]] name = "ruff" -version = "0.6.0" +version = "0.6.1" description = "An extremely fast Python linter and code formatter, written in Rust." optional = false python-versions = ">=3.7" files = [ - {file = "ruff-0.6.0-py3-none-linux_armv6l.whl", hash = "sha256:92dcce923e5df265781e5fc76f9a1edad52201a7aafe56e586b90988d5239013"}, - {file = "ruff-0.6.0-py3-none-macosx_10_12_x86_64.whl", hash = "sha256:31b90ff9dc79ed476c04e957ba7e2b95c3fceb76148f2079d0d68a908d2cfae7"}, - {file = "ruff-0.6.0-py3-none-macosx_11_0_arm64.whl", hash = "sha256:6d834a9ec9f8287dd6c3297058b3a265ed6b59233db22593379ee38ebc4b9768"}, - {file = "ruff-0.6.0-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f2089267692696aba342179471831a085043f218706e642564812145df8b8d0d"}, - {file = "ruff-0.6.0-py3-none-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:aa62b423ee4bbd8765f2c1dbe8f6aac203e0583993a91453dc0a449d465c84da"}, - {file = "ruff-0.6.0-py3-none-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:7344e1a964b16b1137ea361d6516ce4ee61a0403fa94252a1913ecc1311adcae"}, - {file = "ruff-0.6.0-py3-none-manylinux_2_17_ppc64.manylinux2014_ppc64.whl", hash = "sha256:487f3a35c3f33bf82be212ce15dc6278ea854e35573a3f809442f73bec8b2760"}, - {file = "ruff-0.6.0-py3-none-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:75db409984077a793cf344d499165298a6f65449e905747ac65983b12e3e64b1"}, - {file = "ruff-0.6.0-py3-none-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:84908bd603533ecf1db456d8fc2665d1f4335d722e84bc871d3bbd2d1116c272"}, - {file = "ruff-0.6.0-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0f1749a0aef3ec41ed91a0e2127a6ae97d2e2853af16dbd4f3c00d7a3af726c5"}, - {file = "ruff-0.6.0-py3-none-musllinux_1_2_aarch64.whl", hash = "sha256:016fea751e2bcfbbd2f8cb19b97b37b3fd33148e4df45b526e87096f4e17354f"}, - {file = "ruff-0.6.0-py3-none-musllinux_1_2_armv7l.whl", hash = "sha256:6ae80f141b53b2e36e230017e64f5ea2def18fac14334ffceaae1b780d70c4f7"}, - {file = "ruff-0.6.0-py3-none-musllinux_1_2_i686.whl", hash = "sha256:eaaaf33ea4b3f63fd264d6a6f4a73fa224bbfda4b438ffea59a5340f4afa2bb5"}, - {file = "ruff-0.6.0-py3-none-musllinux_1_2_x86_64.whl", hash = "sha256:7667ddd1fc688150a7ca4137140867584c63309695a30016880caf20831503a0"}, - {file = "ruff-0.6.0-py3-none-win32.whl", hash = "sha256:ae48365aae60d40865a412356f8c6f2c0be1c928591168111eaf07eaefa6bea3"}, - {file = "ruff-0.6.0-py3-none-win_amd64.whl", hash = "sha256:774032b507c96f0c803c8237ce7d2ef3934df208a09c40fa809c2931f957fe5e"}, - {file = "ruff-0.6.0-py3-none-win_arm64.whl", hash = "sha256:a5366e8c3ae6b2dc32821749b532606c42e609a99b0ae1472cf601da931a048c"}, - {file = "ruff-0.6.0.tar.gz", hash = "sha256:272a81830f68f9bd19d49eaf7fa01a5545c5a2e86f32a9935bb0e4bb9a1db5b8"}, + {file = "ruff-0.6.1-py3-none-linux_armv6l.whl", hash = "sha256:b4bb7de6a24169dc023f992718a9417380301b0c2da0fe85919f47264fb8add9"}, + {file = "ruff-0.6.1-py3-none-macosx_10_12_x86_64.whl", hash = "sha256:45efaae53b360c81043e311cdec8a7696420b3d3e8935202c2846e7a97d4edae"}, + {file = "ruff-0.6.1-py3-none-macosx_11_0_arm64.whl", hash = "sha256:bc60c7d71b732c8fa73cf995efc0c836a2fd8b9810e115be8babb24ae87e0850"}, + {file = "ruff-0.6.1-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2c7477c3b9da822e2db0b4e0b59e61b8a23e87886e727b327e7dcaf06213c5cf"}, + {file = "ruff-0.6.1-py3-none-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:3a0af7ab3f86e3dc9f157a928e08e26c4b40707d0612b01cd577cc84b8905cc9"}, + {file = "ruff-0.6.1-py3-none-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:392688dbb50fecf1bf7126731c90c11a9df1c3a4cdc3f481b53e851da5634fa5"}, + {file = "ruff-0.6.1-py3-none-manylinux_2_17_ppc64.manylinux2014_ppc64.whl", hash = "sha256:5278d3e095ccc8c30430bcc9bc550f778790acc211865520f3041910a28d0024"}, + {file = "ruff-0.6.1-py3-none-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:fe6d5f65d6f276ee7a0fc50a0cecaccb362d30ef98a110f99cac1c7872df2f18"}, + {file = "ruff-0.6.1-py3-none-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:b2e0dd11e2ae553ee5c92a81731d88a9883af8db7408db47fc81887c1f8b672e"}, + {file = "ruff-0.6.1-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d812615525a34ecfc07fd93f906ef5b93656be01dfae9a819e31caa6cfe758a1"}, + {file = "ruff-0.6.1-py3-none-musllinux_1_2_aarch64.whl", hash = "sha256:faaa4060f4064c3b7aaaa27328080c932fa142786f8142aff095b42b6a2eb631"}, + {file = "ruff-0.6.1-py3-none-musllinux_1_2_armv7l.whl", hash = "sha256:99d7ae0df47c62729d58765c593ea54c2546d5de213f2af2a19442d50a10cec9"}, + {file = "ruff-0.6.1-py3-none-musllinux_1_2_i686.whl", hash = "sha256:9eb18dfd7b613eec000e3738b3f0e4398bf0153cb80bfa3e351b3c1c2f6d7b15"}, + {file = "ruff-0.6.1-py3-none-musllinux_1_2_x86_64.whl", hash = "sha256:c62bc04c6723a81e25e71715aa59489f15034d69bf641df88cb38bdc32fd1dbb"}, + {file = "ruff-0.6.1-py3-none-win32.whl", hash = "sha256:9fb4c4e8b83f19c9477a8745e56d2eeef07a7ff50b68a6998f7d9e2e3887bdc4"}, + {file = "ruff-0.6.1-py3-none-win_amd64.whl", hash = "sha256:c2ebfc8f51ef4aca05dad4552bbcf6fe8d1f75b2f6af546cc47cc1c1ca916b5b"}, + {file = "ruff-0.6.1-py3-none-win_arm64.whl", hash = "sha256:3bc81074971b0ffad1bd0c52284b22411f02a11a012082a76ac6da153536e014"}, + {file = "ruff-0.6.1.tar.gz", hash = "sha256:af3ffd8c6563acb8848d33cd19a69b9bfe943667f0419ca083f8ebe4224a3436"}, ] [[package]] From a0b8b43f143fb6b08ee86ee1b207a8e1a1aebd60 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Mon, 19 Aug 2024 00:22:35 +0000 Subject: [PATCH 46/59] chore(deps): lock file maintenance --- poetry.lock | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/poetry.lock b/poetry.lock index bce5a7cd2..c96dd9078 100644 --- a/poetry.lock +++ b/poetry.lock @@ -628,13 +628,13 @@ test = ["flufl.flake8", "importlib-resources (>=1.3)", "jaraco.test (>=5.4)", "p [[package]] name = "importlib-resources" -version = "6.4.2" +version = "6.4.3" description = "Read resources from Python packages" optional = false python-versions = ">=3.8" files = [ - {file = "importlib_resources-6.4.2-py3-none-any.whl", hash = "sha256:8bba8c54a8a3afaa1419910845fa26ebd706dc716dd208d9b158b4b6966f5c5c"}, - {file = "importlib_resources-6.4.2.tar.gz", hash = "sha256:6cbfbefc449cc6e2095dd184691b7a12a04f40bc75dd4c55d31c34f174cdf57a"}, + {file = "importlib_resources-6.4.3-py3-none-any.whl", hash = "sha256:2d6dfe3b9e055f72495c2085890837fc8c758984e209115c8792bddcb762cd93"}, + {file = "importlib_resources-6.4.3.tar.gz", hash = "sha256:4a202b9b9d38563b46da59221d77bb73862ab5d79d461307bcb826d725448b98"}, ] [package.dependencies] From fae19f8346e059422b93dc8e361aa5af2ce326b8 Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Mon, 19 Aug 2024 00:23:19 +0000 Subject: [PATCH 47/59] [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci --- .pre-commit-config.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index f788fdc18..a1f557b6d 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -41,7 +41,7 @@ repos: - croniter==3.0.3 - django-stubs==5.0.4 - django==4.2.15 - - importlib-resources==6.4.2 + - importlib-resources==6.4.3 - psycopg2-binary==2.9.9 - psycopg[pool]==3.2.1 - python-dateutil==2.9.0.post0 From 26b60e64e0815395b979e0a4d69fe87c73461e10 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Sat, 24 Aug 2024 00:55:34 +0000 Subject: [PATCH 48/59] chore(deps): update all dependencies --- .pre-commit-config.yaml | 4 +-- poetry.lock | 58 ++++++++++++++++++++++------------------- 2 files changed, 33 insertions(+), 29 deletions(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index a1f557b6d..a90210f4a 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -29,7 +29,7 @@ repos: - id: trailing-whitespace - id: mixed-line-ending - repo: https://github.com/RobertCraigie/pyright-python - rev: v1.1.376 + rev: v1.1.377 hooks: - id: pyright additional_dependencies: @@ -49,7 +49,7 @@ repos: - sqlalchemy==2.0.32 - typing-extensions==4.12.2 - repo: https://github.com/astral-sh/ruff-pre-commit - rev: v0.6.1 + rev: v0.6.2 hooks: - id: ruff args: [--fix, --unsafe-fixes] diff --git a/poetry.lock b/poetry.lock index c96dd9078..b33b409cd 100644 --- a/poetry.lock +++ b/poetry.lock @@ -628,21 +628,25 @@ test = ["flufl.flake8", "importlib-resources (>=1.3)", "jaraco.test (>=5.4)", "p [[package]] name = "importlib-resources" -version = "6.4.3" +version = "6.4.4" description = "Read resources from Python packages" optional = false python-versions = ">=3.8" files = [ - {file = "importlib_resources-6.4.3-py3-none-any.whl", hash = "sha256:2d6dfe3b9e055f72495c2085890837fc8c758984e209115c8792bddcb762cd93"}, - {file = "importlib_resources-6.4.3.tar.gz", hash = "sha256:4a202b9b9d38563b46da59221d77bb73862ab5d79d461307bcb826d725448b98"}, + {file = "importlib_resources-6.4.4-py3-none-any.whl", hash = "sha256:dda242603d1c9cd836c3368b1174ed74cb4049ecd209e7a1a0104620c18c5c11"}, + {file = "importlib_resources-6.4.4.tar.gz", hash = "sha256:20600c8b7361938dc0bb2d5ec0297802e575df486f5a544fa414da65e13721f7"}, ] [package.dependencies] zipp = {version = ">=3.1.0", markers = "python_version < \"3.10\""} [package.extras] +check = ["pytest-checkdocs (>=2.4)", "pytest-ruff (>=0.2.1)"] +cover = ["pytest-cov"] doc = ["furo", "jaraco.packaging (>=9.3)", "jaraco.tidelift (>=1.4)", "rst.linker (>=1.9)", "sphinx (>=3.5)", "sphinx-lint"] -test = ["jaraco.test (>=5.4)", "pytest (>=6,!=8.1.*)", "pytest-checkdocs (>=2.4)", "pytest-cov", "pytest-enabler (>=2.2)", "pytest-mypy", "pytest-ruff (>=0.2.1)", "zipp (>=3.17)"] +enabler = ["pytest-enabler (>=2.2)"] +test = ["jaraco.test (>=5.4)", "pytest (>=6,!=8.1.*)", "zipp (>=3.17)"] +type = ["pytest-mypy"] [[package]] name = "iniconfig" @@ -1145,17 +1149,17 @@ dev = ["argcomplete", "attrs (>=19.2)", "hypothesis (>=3.56)", "mock", "pygments [[package]] name = "pytest-asyncio" -version = "0.23.8" +version = "0.24.0" description = "Pytest support for asyncio" optional = false python-versions = ">=3.8" files = [ - {file = "pytest_asyncio-0.23.8-py3-none-any.whl", hash = "sha256:50265d892689a5faefb84df80819d1ecef566eb3549cf915dfb33569359d1ce2"}, - {file = "pytest_asyncio-0.23.8.tar.gz", hash = "sha256:759b10b33a6dc61cce40a8bd5205e302978bbbcc00e279a8b61d9a6a3c82e4d3"}, + {file = "pytest_asyncio-0.24.0-py3-none-any.whl", hash = "sha256:a811296ed596b69bf0b6f3dc40f83bcaf341b155a269052d82efa2b25ac7037b"}, + {file = "pytest_asyncio-0.24.0.tar.gz", hash = "sha256:d081d828e576d85f875399194281e92bf8a68d60d72d1a2faf2feddb6c46b276"}, ] [package.dependencies] -pytest = ">=7.0.0,<9" +pytest = ">=8.2,<9" [package.extras] docs = ["sphinx (>=5.3)", "sphinx-rtd-theme (>=1.0)"] @@ -1324,29 +1328,29 @@ use-chardet-on-py3 = ["chardet (>=3.0.2,<6)"] [[package]] name = "ruff" -version = "0.6.1" +version = "0.6.2" description = "An extremely fast Python linter and code formatter, written in Rust." optional = false python-versions = ">=3.7" files = [ - {file = "ruff-0.6.1-py3-none-linux_armv6l.whl", hash = "sha256:b4bb7de6a24169dc023f992718a9417380301b0c2da0fe85919f47264fb8add9"}, - {file = "ruff-0.6.1-py3-none-macosx_10_12_x86_64.whl", hash = "sha256:45efaae53b360c81043e311cdec8a7696420b3d3e8935202c2846e7a97d4edae"}, - {file = "ruff-0.6.1-py3-none-macosx_11_0_arm64.whl", hash = "sha256:bc60c7d71b732c8fa73cf995efc0c836a2fd8b9810e115be8babb24ae87e0850"}, - {file = "ruff-0.6.1-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2c7477c3b9da822e2db0b4e0b59e61b8a23e87886e727b327e7dcaf06213c5cf"}, - {file = "ruff-0.6.1-py3-none-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:3a0af7ab3f86e3dc9f157a928e08e26c4b40707d0612b01cd577cc84b8905cc9"}, - {file = "ruff-0.6.1-py3-none-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:392688dbb50fecf1bf7126731c90c11a9df1c3a4cdc3f481b53e851da5634fa5"}, - {file = "ruff-0.6.1-py3-none-manylinux_2_17_ppc64.manylinux2014_ppc64.whl", hash = "sha256:5278d3e095ccc8c30430bcc9bc550f778790acc211865520f3041910a28d0024"}, - {file = "ruff-0.6.1-py3-none-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:fe6d5f65d6f276ee7a0fc50a0cecaccb362d30ef98a110f99cac1c7872df2f18"}, - {file = "ruff-0.6.1-py3-none-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:b2e0dd11e2ae553ee5c92a81731d88a9883af8db7408db47fc81887c1f8b672e"}, - {file = "ruff-0.6.1-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d812615525a34ecfc07fd93f906ef5b93656be01dfae9a819e31caa6cfe758a1"}, - {file = "ruff-0.6.1-py3-none-musllinux_1_2_aarch64.whl", hash = "sha256:faaa4060f4064c3b7aaaa27328080c932fa142786f8142aff095b42b6a2eb631"}, - {file = "ruff-0.6.1-py3-none-musllinux_1_2_armv7l.whl", hash = "sha256:99d7ae0df47c62729d58765c593ea54c2546d5de213f2af2a19442d50a10cec9"}, - {file = "ruff-0.6.1-py3-none-musllinux_1_2_i686.whl", hash = "sha256:9eb18dfd7b613eec000e3738b3f0e4398bf0153cb80bfa3e351b3c1c2f6d7b15"}, - {file = "ruff-0.6.1-py3-none-musllinux_1_2_x86_64.whl", hash = "sha256:c62bc04c6723a81e25e71715aa59489f15034d69bf641df88cb38bdc32fd1dbb"}, - {file = "ruff-0.6.1-py3-none-win32.whl", hash = "sha256:9fb4c4e8b83f19c9477a8745e56d2eeef07a7ff50b68a6998f7d9e2e3887bdc4"}, - {file = "ruff-0.6.1-py3-none-win_amd64.whl", hash = "sha256:c2ebfc8f51ef4aca05dad4552bbcf6fe8d1f75b2f6af546cc47cc1c1ca916b5b"}, - {file = "ruff-0.6.1-py3-none-win_arm64.whl", hash = "sha256:3bc81074971b0ffad1bd0c52284b22411f02a11a012082a76ac6da153536e014"}, - {file = "ruff-0.6.1.tar.gz", hash = "sha256:af3ffd8c6563acb8848d33cd19a69b9bfe943667f0419ca083f8ebe4224a3436"}, + {file = "ruff-0.6.2-py3-none-linux_armv6l.whl", hash = "sha256:5c8cbc6252deb3ea840ad6a20b0f8583caab0c5ef4f9cca21adc5a92b8f79f3c"}, + {file = "ruff-0.6.2-py3-none-macosx_10_12_x86_64.whl", hash = "sha256:17002fe241e76544448a8e1e6118abecbe8cd10cf68fde635dad480dba594570"}, + {file = "ruff-0.6.2-py3-none-macosx_11_0_arm64.whl", hash = "sha256:3dbeac76ed13456f8158b8f4fe087bf87882e645c8e8b606dd17b0b66c2c1158"}, + {file = "ruff-0.6.2-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:094600ee88cda325988d3f54e3588c46de5c18dae09d683ace278b11f9d4d534"}, + {file = "ruff-0.6.2-py3-none-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:316d418fe258c036ba05fbf7dfc1f7d3d4096db63431546163b472285668132b"}, + {file = "ruff-0.6.2-py3-none-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:d72b8b3abf8a2d51b7b9944a41307d2f442558ccb3859bbd87e6ae9be1694a5d"}, + {file = "ruff-0.6.2-py3-none-manylinux_2_17_ppc64.manylinux2014_ppc64.whl", hash = "sha256:2aed7e243be68487aa8982e91c6e260982d00da3f38955873aecd5a9204b1d66"}, + {file = "ruff-0.6.2-py3-none-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:d371f7fc9cec83497fe7cf5eaf5b76e22a8efce463de5f775a1826197feb9df8"}, + {file = "ruff-0.6.2-py3-none-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:a8f310d63af08f583363dfb844ba8f9417b558199c58a5999215082036d795a1"}, + {file = "ruff-0.6.2-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7db6880c53c56addb8638fe444818183385ec85eeada1d48fc5abe045301b2f1"}, + {file = "ruff-0.6.2-py3-none-musllinux_1_2_aarch64.whl", hash = "sha256:1175d39faadd9a50718f478d23bfc1d4da5743f1ab56af81a2b6caf0a2394f23"}, + {file = "ruff-0.6.2-py3-none-musllinux_1_2_armv7l.whl", hash = "sha256:5b939f9c86d51635fe486585389f54582f0d65b8238e08c327c1534844b3bb9a"}, + {file = "ruff-0.6.2-py3-none-musllinux_1_2_i686.whl", hash = "sha256:d0d62ca91219f906caf9b187dea50d17353f15ec9bb15aae4a606cd697b49b4c"}, + {file = "ruff-0.6.2-py3-none-musllinux_1_2_x86_64.whl", hash = "sha256:7438a7288f9d67ed3c8ce4d059e67f7ed65e9fe3aa2ab6f5b4b3610e57e3cb56"}, + {file = "ruff-0.6.2-py3-none-win32.whl", hash = "sha256:279d5f7d86696df5f9549b56b9b6a7f6c72961b619022b5b7999b15db392a4da"}, + {file = "ruff-0.6.2-py3-none-win_amd64.whl", hash = "sha256:d9f3469c7dd43cd22eb1c3fc16926fb8258d50cb1b216658a07be95dd117b0f2"}, + {file = "ruff-0.6.2-py3-none-win_arm64.whl", hash = "sha256:f28fcd2cd0e02bdf739297516d5643a945cc7caf09bd9bcb4d932540a5ea4fa9"}, + {file = "ruff-0.6.2.tar.gz", hash = "sha256:239ee6beb9e91feb8e0ec384204a763f36cb53fb895a1a364618c6abb076b3be"}, ] [[package]] From 1ba4a43439952b0a704842414d66350408ac05ff Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Sat, 24 Aug 2024 00:55:52 +0000 Subject: [PATCH 49/59] [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci --- .pre-commit-config.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index a90210f4a..18a27b9fd 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -41,7 +41,7 @@ repos: - croniter==3.0.3 - django-stubs==5.0.4 - django==4.2.15 - - importlib-resources==6.4.3 + - importlib-resources==6.4.4 - psycopg2-binary==2.9.9 - psycopg[pool]==3.2.1 - python-dateutil==2.9.0.post0 From e2bd0dd92a2b597477993eba6e415c1d1543d3b1 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Sat, 24 Aug 2024 00:55:59 +0000 Subject: [PATCH 50/59] chore(deps): update all dependencies --- poetry.lock | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/poetry.lock b/poetry.lock index c96dd9078..da37a419a 100644 --- a/poetry.lock +++ b/poetry.lock @@ -1365,19 +1365,19 @@ sqlalchemy = "*" [[package]] name = "setuptools" -version = "72.2.0" +version = "73.0.1" description = "Easily download, build, install, upgrade, and uninstall Python packages" optional = false python-versions = ">=3.8" files = [ - {file = "setuptools-72.2.0-py3-none-any.whl", hash = "sha256:f11dd94b7bae3a156a95ec151f24e4637fb4fa19c878e4d191bfb8b2d82728c4"}, - {file = "setuptools-72.2.0.tar.gz", hash = "sha256:80aacbf633704e9c8bfa1d99fa5dd4dc59573efcf9e4042c13d3bcef91ac2ef9"}, + {file = "setuptools-73.0.1-py3-none-any.whl", hash = "sha256:b208925fcb9f7af924ed2dc04708ea89791e24bde0d3020b27df0e116088b34e"}, + {file = "setuptools-73.0.1.tar.gz", hash = "sha256:d59a3e788ab7e012ab2c4baed1b376da6366883ee20d7a5fc426816e3d7b1193"}, ] [package.extras] -core = ["importlib-metadata (>=6)", "importlib-resources (>=5.10.2)", "jaraco.text (>=3.7)", "more-itertools (>=8.8)", "ordered-set (>=3.1.1)", "packaging (>=24)", "platformdirs (>=2.6.2)", "tomli (>=2.0.1)", "wheel (>=0.43.0)"] +core = ["importlib-metadata (>=6)", "importlib-resources (>=5.10.2)", "jaraco.text (>=3.7)", "more-itertools (>=8.8)", "packaging (>=24)", "platformdirs (>=2.6.2)", "tomli (>=2.0.1)", "wheel (>=0.43.0)"] doc = ["furo", "jaraco.packaging (>=9.3)", "jaraco.tidelift (>=1.4)", "pygments-github-lexers (==0.0.5)", "pyproject-hooks (!=1.1)", "rst.linker (>=1.9)", "sphinx (>=3.5)", "sphinx-favicon", "sphinx-inline-tabs", "sphinx-lint", "sphinx-notfound-page (>=1,<2)", "sphinx-reredirects", "sphinxcontrib-towncrier", "towncrier (<24.7)"] -test = ["build[virtualenv] (>=1.0.3)", "filelock (>=3.4.0)", "importlib-metadata", "ini2toml[lite] (>=0.14)", "jaraco.develop (>=7.21)", "jaraco.envs (>=2.2)", "jaraco.path (>=3.2.0)", "jaraco.test", "mypy (==1.11.*)", "packaging (>=23.2)", "pip (>=19.1)", "pyproject-hooks (!=1.1)", "pytest (>=6,!=8.1.*)", "pytest-checkdocs (>=2.4)", "pytest-cov", "pytest-enabler (>=2.2)", "pytest-home (>=0.5)", "pytest-mypy", "pytest-perf", "pytest-ruff (<0.4)", "pytest-ruff (>=0.2.1)", "pytest-ruff (>=0.3.2)", "pytest-subprocess", "pytest-timeout", "pytest-xdist (>=3)", "tomli", "tomli-w (>=1.0.0)", "virtualenv (>=13.0.0)", "wheel"] +test = ["build[virtualenv] (>=1.0.3)", "filelock (>=3.4.0)", "importlib-metadata", "ini2toml[lite] (>=0.14)", "jaraco.develop (>=7.21)", "jaraco.envs (>=2.2)", "jaraco.path (>=3.2.0)", "jaraco.test", "mypy (==1.11.*)", "packaging (>=23.2)", "pip (>=19.1)", "pyproject-hooks (!=1.1)", "pytest (>=6,!=8.1.*)", "pytest-checkdocs (>=2.4)", "pytest-cov", "pytest-enabler (>=2.2)", "pytest-home (>=0.5)", "pytest-mypy", "pytest-perf", "pytest-ruff (<0.4)", "pytest-ruff (>=0.2.1)", "pytest-ruff (>=0.3.2)", "pytest-subprocess", "pytest-timeout", "pytest-xdist (>=3)", "tomli", "tomli-w (>=1.0.0)", "virtualenv (>=13.0.0)", "wheel (>=0.44.0)"] [[package]] name = "six" From 1a460ac5b99d331dec9986c01360f964b025dddf Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Mon, 26 Aug 2024 01:22:25 +0000 Subject: [PATCH 51/59] chore(deps): lock file maintenance --- poetry.lock | 70 ++++++++++++++++++++++++++--------------------------- 1 file changed, 35 insertions(+), 35 deletions(-) diff --git a/poetry.lock b/poetry.lock index 73aaaae41..2a6a1bed2 100644 --- a/poetry.lock +++ b/poetry.lock @@ -587,13 +587,13 @@ test = ["objgraph", "psutil"] [[package]] name = "idna" -version = "3.7" +version = "3.8" description = "Internationalized Domain Names in Applications (IDNA)" optional = false -python-versions = ">=3.5" +python-versions = ">=3.6" files = [ - {file = "idna-3.7-py3-none-any.whl", hash = "sha256:82fee1fc78add43492d3a1898bfa6d8a904cc97d8427f683ed8e798d07761aa0"}, - {file = "idna-3.7.tar.gz", hash = "sha256:028ff3aadf0609c1fd278d8ea3089299412a7a8b9bd005dd08b9f8285bcb5cfc"}, + {file = "idna-3.8-py3-none-any.whl", hash = "sha256:050b4e5baadcd44d760cedbd2b8e639f2ff89bbc7a5730fcc662954303377aac"}, + {file = "idna-3.8.tar.gz", hash = "sha256:d838c2c0ed6fced7693d5e8ab8e734d5f8fda53a039c0164afb0b82e771e3603"}, ] [[package]] @@ -609,13 +609,13 @@ files = [ [[package]] name = "importlib-metadata" -version = "8.2.0" +version = "8.4.0" description = "Read metadata from Python packages" optional = false python-versions = ">=3.8" files = [ - {file = "importlib_metadata-8.2.0-py3-none-any.whl", hash = "sha256:11901fa0c2f97919b288679932bb64febaeacf289d18ac84dd68cb2e74213369"}, - {file = "importlib_metadata-8.2.0.tar.gz", hash = "sha256:72e8d4399996132204f9a16dcc751af254a48f8d1b20b9ff0f98d4a8f901e73d"}, + {file = "importlib_metadata-8.4.0-py3-none-any.whl", hash = "sha256:66f342cc6ac9818fc6ff340576acd24d65ba0b3efabb2b4ac08b598965a4a2f1"}, + {file = "importlib_metadata-8.4.0.tar.gz", hash = "sha256:9a547d3bc3608b025f93d403fdd1aae741c24fbb8314df4b155675742ce303c5"}, ] [package.dependencies] @@ -820,38 +820,38 @@ pg = ["psycopg2-binary"] [[package]] name = "mypy" -version = "1.11.1" +version = "1.11.2" description = "Optional static typing for Python" optional = false python-versions = ">=3.8" files = [ - {file = "mypy-1.11.1-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:a32fc80b63de4b5b3e65f4be82b4cfa362a46702672aa6a0f443b4689af7008c"}, - {file = "mypy-1.11.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:c1952f5ea8a5a959b05ed5f16452fddadbaae48b5d39235ab4c3fc444d5fd411"}, - {file = "mypy-1.11.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:e1e30dc3bfa4e157e53c1d17a0dad20f89dc433393e7702b813c10e200843b03"}, - {file = "mypy-1.11.1-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:2c63350af88f43a66d3dfeeeb8d77af34a4f07d760b9eb3a8697f0386c7590b4"}, - {file = "mypy-1.11.1-cp310-cp310-win_amd64.whl", hash = "sha256:a831671bad47186603872a3abc19634f3011d7f83b083762c942442d51c58d58"}, - {file = "mypy-1.11.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:7b6343d338390bb946d449677726edf60102a1c96079b4f002dedff375953fc5"}, - {file = "mypy-1.11.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:e4fe9f4e5e521b458d8feb52547f4bade7ef8c93238dfb5bbc790d9ff2d770ca"}, - {file = "mypy-1.11.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:886c9dbecc87b9516eff294541bf7f3655722bf22bb898ee06985cd7269898de"}, - {file = "mypy-1.11.1-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:fca4a60e1dd9fd0193ae0067eaeeb962f2d79e0d9f0f66223a0682f26ffcc809"}, - {file = "mypy-1.11.1-cp311-cp311-win_amd64.whl", hash = "sha256:0bd53faf56de9643336aeea1c925012837432b5faf1701ccca7fde70166ccf72"}, - {file = "mypy-1.11.1-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:f39918a50f74dc5969807dcfaecafa804fa7f90c9d60506835036cc1bc891dc8"}, - {file = "mypy-1.11.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:0bc71d1fb27a428139dd78621953effe0d208aed9857cb08d002280b0422003a"}, - {file = "mypy-1.11.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:b868d3bcff720dd7217c383474008ddabaf048fad8d78ed948bb4b624870a417"}, - {file = "mypy-1.11.1-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:a707ec1527ffcdd1c784d0924bf5cb15cd7f22683b919668a04d2b9c34549d2e"}, - {file = "mypy-1.11.1-cp312-cp312-win_amd64.whl", hash = "sha256:64f4a90e3ea07f590c5bcf9029035cf0efeae5ba8be511a8caada1a4893f5525"}, - {file = "mypy-1.11.1-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:749fd3213916f1751fff995fccf20c6195cae941dc968f3aaadf9bb4e430e5a2"}, - {file = "mypy-1.11.1-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:b639dce63a0b19085213ec5fdd8cffd1d81988f47a2dec7100e93564f3e8fb3b"}, - {file = "mypy-1.11.1-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:4c956b49c5d865394d62941b109728c5c596a415e9c5b2be663dd26a1ff07bc0"}, - {file = "mypy-1.11.1-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:45df906e8b6804ef4b666af29a87ad9f5921aad091c79cc38e12198e220beabd"}, - {file = "mypy-1.11.1-cp38-cp38-win_amd64.whl", hash = "sha256:d44be7551689d9d47b7abc27c71257adfdb53f03880841a5db15ddb22dc63edb"}, - {file = "mypy-1.11.1-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:2684d3f693073ab89d76da8e3921883019ea8a3ec20fa5d8ecca6a2db4c54bbe"}, - {file = "mypy-1.11.1-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:79c07eb282cb457473add5052b63925e5cc97dfab9812ee65a7c7ab5e3cb551c"}, - {file = "mypy-1.11.1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:11965c2f571ded6239977b14deebd3f4c3abd9a92398712d6da3a772974fad69"}, - {file = "mypy-1.11.1-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:a2b43895a0f8154df6519706d9bca8280cda52d3d9d1514b2d9c3e26792a0b74"}, - {file = "mypy-1.11.1-cp39-cp39-win_amd64.whl", hash = "sha256:1a81cf05975fd61aec5ae16501a091cfb9f605dc3e3c878c0da32f250b74760b"}, - {file = "mypy-1.11.1-py3-none-any.whl", hash = "sha256:0624bdb940255d2dd24e829d99a13cfeb72e4e9031f9492148f410ed30bcab54"}, - {file = "mypy-1.11.1.tar.gz", hash = "sha256:f404a0b069709f18bbdb702eb3dcfe51910602995de00bd39cea3050b5772d08"}, + {file = "mypy-1.11.2-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:d42a6dd818ffce7be66cce644f1dff482f1d97c53ca70908dff0b9ddc120b77a"}, + {file = "mypy-1.11.2-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:801780c56d1cdb896eacd5619a83e427ce436d86a3bdf9112527f24a66618fef"}, + {file = "mypy-1.11.2-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:41ea707d036a5307ac674ea172875f40c9d55c5394f888b168033177fce47383"}, + {file = "mypy-1.11.2-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:6e658bd2d20565ea86da7d91331b0eed6d2eee22dc031579e6297f3e12c758c8"}, + {file = "mypy-1.11.2-cp310-cp310-win_amd64.whl", hash = "sha256:478db5f5036817fe45adb7332d927daa62417159d49783041338921dcf646fc7"}, + {file = "mypy-1.11.2-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:75746e06d5fa1e91bfd5432448d00d34593b52e7e91a187d981d08d1f33d4385"}, + {file = "mypy-1.11.2-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:a976775ab2256aadc6add633d44f100a2517d2388906ec4f13231fafbb0eccca"}, + {file = "mypy-1.11.2-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:cd953f221ac1379050a8a646585a29574488974f79d8082cedef62744f0a0104"}, + {file = "mypy-1.11.2-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:57555a7715c0a34421013144a33d280e73c08df70f3a18a552938587ce9274f4"}, + {file = "mypy-1.11.2-cp311-cp311-win_amd64.whl", hash = "sha256:36383a4fcbad95f2657642a07ba22ff797de26277158f1cc7bd234821468b1b6"}, + {file = "mypy-1.11.2-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:e8960dbbbf36906c5c0b7f4fbf2f0c7ffb20f4898e6a879fcf56a41a08b0d318"}, + {file = "mypy-1.11.2-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:06d26c277962f3fb50e13044674aa10553981ae514288cb7d0a738f495550b36"}, + {file = "mypy-1.11.2-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:6e7184632d89d677973a14d00ae4d03214c8bc301ceefcdaf5c474866814c987"}, + {file = "mypy-1.11.2-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:3a66169b92452f72117e2da3a576087025449018afc2d8e9bfe5ffab865709ca"}, + {file = "mypy-1.11.2-cp312-cp312-win_amd64.whl", hash = "sha256:969ea3ef09617aff826885a22ece0ddef69d95852cdad2f60c8bb06bf1f71f70"}, + {file = "mypy-1.11.2-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:37c7fa6121c1cdfcaac97ce3d3b5588e847aa79b580c1e922bb5d5d2902df19b"}, + {file = "mypy-1.11.2-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:4a8a53bc3ffbd161b5b2a4fff2f0f1e23a33b0168f1c0778ec70e1a3d66deb86"}, + {file = "mypy-1.11.2-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:2ff93107f01968ed834f4256bc1fc4475e2fecf6c661260066a985b52741ddce"}, + {file = "mypy-1.11.2-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:edb91dded4df17eae4537668b23f0ff6baf3707683734b6a818d5b9d0c0c31a1"}, + {file = "mypy-1.11.2-cp38-cp38-win_amd64.whl", hash = "sha256:ee23de8530d99b6db0573c4ef4bd8f39a2a6f9b60655bf7a1357e585a3486f2b"}, + {file = "mypy-1.11.2-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:801ca29f43d5acce85f8e999b1e431fb479cb02d0e11deb7d2abb56bdaf24fd6"}, + {file = "mypy-1.11.2-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:af8d155170fcf87a2afb55b35dc1a0ac21df4431e7d96717621962e4b9192e70"}, + {file = "mypy-1.11.2-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:f7821776e5c4286b6a13138cc935e2e9b6fde05e081bdebf5cdb2bb97c9df81d"}, + {file = "mypy-1.11.2-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:539c570477a96a4e6fb718b8d5c3e0c0eba1f485df13f86d2970c91f0673148d"}, + {file = "mypy-1.11.2-cp39-cp39-win_amd64.whl", hash = "sha256:3f14cd3d386ac4d05c5a39a51b84387403dadbd936e17cb35882134d4f8f0d24"}, + {file = "mypy-1.11.2-py3-none-any.whl", hash = "sha256:b499bc07dbdcd3de92b0a8b29fdf592c111276f6a12fe29c30f6c417dd546d12"}, + {file = "mypy-1.11.2.tar.gz", hash = "sha256:7f9993ad3e0ffdc95c2a14b66dee63729f021968bff8ad911867579c65d13a79"}, ] [package.dependencies] From 96d9599c1b08ce5aa8a0c0fd7f7b103348e7115a Mon Sep 17 00:00:00 2001 From: Kai Schlamp Date: Tue, 27 Aug 2024 21:06:13 +0000 Subject: [PATCH 52/59] Show how to add async tasks in docs --- docs/howto/basics/tasks.md | 27 ++++++++++++++++++++++++--- 1 file changed, 24 insertions(+), 3 deletions(-) diff --git a/docs/howto/basics/tasks.md b/docs/howto/basics/tasks.md index 279960f98..2d7115010 100644 --- a/docs/howto/basics/tasks.md +++ b/docs/howto/basics/tasks.md @@ -1,13 +1,29 @@ # Define a task -You can specify a task with: +Specify a sync task with: -``` +```python @app.task(...) def mytask(argument, other_argument): ... ``` +:::{note} +Each sync task runs in its own thread (independently of the worker thread). +::: + +Or an async task with: + +```python +@app.task(...) +async def mytask(argument, other_argument): + ... +``` + +:::{note} +All async tasks run in the same event loop. +::: + See {py:meth}`App.task` for the exact parameters. In particular, you can define values for `queue`, `lock` and `queueing_lock` that will be used as default values when calling {py:meth}`Task.configure` or {py:meth}`Task.defer` on this task. @@ -15,8 +31,13 @@ calling {py:meth}`Task.configure` or {py:meth}`Task.defer` on this task. If you're OK with all the default parameters, you can omit parentheses after `task`: -``` +```python @app.task def mytask(argument, other_argument): ... + +# or +@app.task +async def mytask(argument, other_argument): + ... ``` From 46e81e61441ac353bb38e1243781f17bfae2197a Mon Sep 17 00:00:00 2001 From: Kai Schlamp Date: Tue, 27 Aug 2024 21:06:22 +0000 Subject: [PATCH 53/59] Show how to defer tasks in an async way in docs --- docs/howto/basics/defer.md | 33 ++++++++++++++++++++++++++++----- 1 file changed, 28 insertions(+), 5 deletions(-) diff --git a/docs/howto/basics/defer.md b/docs/howto/basics/defer.md index 842c3c86c..d090e5fca 100644 --- a/docs/howto/basics/defer.md +++ b/docs/howto/basics/defer.md @@ -4,7 +4,7 @@ There are several ways to do this. In the following examples, the task will be: -``` +```python @app.task(queue="some_queue") def my_task(a: int, b:int): pass @@ -14,30 +14,51 @@ Task name is `my_module.my_task`. ## The direct way -``` +By using the sync method: + +```python my_task.defer(a=1, b=2) ``` -## With parameters +Or the async method: +```python +await my_task.defer_async(a=1, b=2) ``` + +## With parameters + +Using the sync defer method: + +```python my_task.configure( lock="the name of my lock", schedule_in={"hours": 1}, queue="not_the_default_queue" ).defer(a=1, b=2) + +# or +await my_task.configure( + lock="the name of my lock", + schedule_in={"hours": 1}, + queue="not_the_default_queue" +).defer_async(a=1, b=2) ``` See details in {py:meth}`Task.configure` ## Create a job pattern, launch multiple jobs -``` +```python pattern = my_task.configure(task_kwargs={"a": 1}) pattern.defer(b=2) pattern.defer(b=3) pattern.defer(b=4) +# or +await pattern.defer_async(b=2) +await pattern.defer_async(b=3) +await pattern.defer_async(b=4) ``` ## Defer a job if you can't access the task @@ -45,8 +66,10 @@ pattern.defer(b=4) This is useful if the code that defers jobs is not in the same code base as the code that runs the jobs. You can defer a job with just the name of its task. -``` +```python app.configure_task(name="my_module.my_task", queue="some_queue").defer(a=1, b=2) +# or +await app.configure_task(name="my_module.my_task", queue="some_queue").defer_async(a=1, b=2) ``` Any parameter you would use for {py:meth}`Task.configure` can be used in From 9f4adf1db6a7a2ecaed0a980b8e9bdc0bb7c38a7 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Sat, 31 Aug 2024 00:09:41 +0000 Subject: [PATCH 54/59] chore(deps): update all dependencies --- .pre-commit-config.yaml | 4 ++-- poetry.lock | 38 +++++++++++++++++++------------------- 2 files changed, 21 insertions(+), 21 deletions(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 18a27b9fd..812550fce 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -29,7 +29,7 @@ repos: - id: trailing-whitespace - id: mixed-line-ending - repo: https://github.com/RobertCraigie/pyright-python - rev: v1.1.377 + rev: v1.1.378 hooks: - id: pyright additional_dependencies: @@ -49,7 +49,7 @@ repos: - sqlalchemy==2.0.32 - typing-extensions==4.12.2 - repo: https://github.com/astral-sh/ruff-pre-commit - rev: v0.6.2 + rev: v0.6.3 hooks: - id: ruff args: [--fix, --unsafe-fixes] diff --git a/poetry.lock b/poetry.lock index 2a6a1bed2..26e52d6b7 100644 --- a/poetry.lock +++ b/poetry.lock @@ -1328,29 +1328,29 @@ use-chardet-on-py3 = ["chardet (>=3.0.2,<6)"] [[package]] name = "ruff" -version = "0.6.2" +version = "0.6.3" description = "An extremely fast Python linter and code formatter, written in Rust." optional = false python-versions = ">=3.7" files = [ - {file = "ruff-0.6.2-py3-none-linux_armv6l.whl", hash = "sha256:5c8cbc6252deb3ea840ad6a20b0f8583caab0c5ef4f9cca21adc5a92b8f79f3c"}, - {file = "ruff-0.6.2-py3-none-macosx_10_12_x86_64.whl", hash = "sha256:17002fe241e76544448a8e1e6118abecbe8cd10cf68fde635dad480dba594570"}, - {file = "ruff-0.6.2-py3-none-macosx_11_0_arm64.whl", hash = "sha256:3dbeac76ed13456f8158b8f4fe087bf87882e645c8e8b606dd17b0b66c2c1158"}, - {file = "ruff-0.6.2-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:094600ee88cda325988d3f54e3588c46de5c18dae09d683ace278b11f9d4d534"}, - {file = "ruff-0.6.2-py3-none-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:316d418fe258c036ba05fbf7dfc1f7d3d4096db63431546163b472285668132b"}, - {file = "ruff-0.6.2-py3-none-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:d72b8b3abf8a2d51b7b9944a41307d2f442558ccb3859bbd87e6ae9be1694a5d"}, - {file = "ruff-0.6.2-py3-none-manylinux_2_17_ppc64.manylinux2014_ppc64.whl", hash = "sha256:2aed7e243be68487aa8982e91c6e260982d00da3f38955873aecd5a9204b1d66"}, - {file = "ruff-0.6.2-py3-none-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:d371f7fc9cec83497fe7cf5eaf5b76e22a8efce463de5f775a1826197feb9df8"}, - {file = "ruff-0.6.2-py3-none-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:a8f310d63af08f583363dfb844ba8f9417b558199c58a5999215082036d795a1"}, - {file = "ruff-0.6.2-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7db6880c53c56addb8638fe444818183385ec85eeada1d48fc5abe045301b2f1"}, - {file = "ruff-0.6.2-py3-none-musllinux_1_2_aarch64.whl", hash = "sha256:1175d39faadd9a50718f478d23bfc1d4da5743f1ab56af81a2b6caf0a2394f23"}, - {file = "ruff-0.6.2-py3-none-musllinux_1_2_armv7l.whl", hash = "sha256:5b939f9c86d51635fe486585389f54582f0d65b8238e08c327c1534844b3bb9a"}, - {file = "ruff-0.6.2-py3-none-musllinux_1_2_i686.whl", hash = "sha256:d0d62ca91219f906caf9b187dea50d17353f15ec9bb15aae4a606cd697b49b4c"}, - {file = "ruff-0.6.2-py3-none-musllinux_1_2_x86_64.whl", hash = "sha256:7438a7288f9d67ed3c8ce4d059e67f7ed65e9fe3aa2ab6f5b4b3610e57e3cb56"}, - {file = "ruff-0.6.2-py3-none-win32.whl", hash = "sha256:279d5f7d86696df5f9549b56b9b6a7f6c72961b619022b5b7999b15db392a4da"}, - {file = "ruff-0.6.2-py3-none-win_amd64.whl", hash = "sha256:d9f3469c7dd43cd22eb1c3fc16926fb8258d50cb1b216658a07be95dd117b0f2"}, - {file = "ruff-0.6.2-py3-none-win_arm64.whl", hash = "sha256:f28fcd2cd0e02bdf739297516d5643a945cc7caf09bd9bcb4d932540a5ea4fa9"}, - {file = "ruff-0.6.2.tar.gz", hash = "sha256:239ee6beb9e91feb8e0ec384204a763f36cb53fb895a1a364618c6abb076b3be"}, + {file = "ruff-0.6.3-py3-none-linux_armv6l.whl", hash = "sha256:97f58fda4e309382ad30ede7f30e2791d70dd29ea17f41970119f55bdb7a45c3"}, + {file = "ruff-0.6.3-py3-none-macosx_10_12_x86_64.whl", hash = "sha256:3b061e49b5cf3a297b4d1c27ac5587954ccb4ff601160d3d6b2f70b1622194dc"}, + {file = "ruff-0.6.3-py3-none-macosx_11_0_arm64.whl", hash = "sha256:34e2824a13bb8c668c71c1760a6ac7d795ccbd8d38ff4a0d8471fdb15de910b1"}, + {file = "ruff-0.6.3-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:bddfbb8d63c460f4b4128b6a506e7052bad4d6f3ff607ebbb41b0aa19c2770d1"}, + {file = "ruff-0.6.3-py3-none-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:ced3eeb44df75353e08ab3b6a9e113b5f3f996bea48d4f7c027bc528ba87b672"}, + {file = "ruff-0.6.3-py3-none-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:47021dff5445d549be954eb275156dfd7c37222acc1e8014311badcb9b4ec8c1"}, + {file = "ruff-0.6.3-py3-none-manylinux_2_17_ppc64.manylinux2014_ppc64.whl", hash = "sha256:7d7bd20dc07cebd68cc8bc7b3f5ada6d637f42d947c85264f94b0d1cd9d87384"}, + {file = "ruff-0.6.3-py3-none-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:500f166d03fc6d0e61c8e40a3ff853fa8a43d938f5d14c183c612df1b0d6c58a"}, + {file = "ruff-0.6.3-py3-none-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:42844ff678f9b976366b262fa2d1d1a3fe76f6e145bd92c84e27d172e3c34500"}, + {file = "ruff-0.6.3-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:70452a10eb2d66549de8e75f89ae82462159855e983ddff91bc0bce6511d0470"}, + {file = "ruff-0.6.3-py3-none-musllinux_1_2_aarch64.whl", hash = "sha256:65a533235ed55f767d1fc62193a21cbf9e3329cf26d427b800fdeacfb77d296f"}, + {file = "ruff-0.6.3-py3-none-musllinux_1_2_armv7l.whl", hash = "sha256:d2e2c23cef30dc3cbe9cc5d04f2899e7f5e478c40d2e0a633513ad081f7361b5"}, + {file = "ruff-0.6.3-py3-none-musllinux_1_2_i686.whl", hash = "sha256:d8a136aa7d228975a6aee3dd8bea9b28e2b43e9444aa678fb62aeb1956ff2351"}, + {file = "ruff-0.6.3-py3-none-musllinux_1_2_x86_64.whl", hash = "sha256:f92fe93bc72e262b7b3f2bba9879897e2d58a989b4714ba6a5a7273e842ad2f8"}, + {file = "ruff-0.6.3-py3-none-win32.whl", hash = "sha256:7a62d3b5b0d7f9143d94893f8ba43aa5a5c51a0ffc4a401aa97a81ed76930521"}, + {file = "ruff-0.6.3-py3-none-win_amd64.whl", hash = "sha256:746af39356fee2b89aada06c7376e1aa274a23493d7016059c3a72e3b296befb"}, + {file = "ruff-0.6.3-py3-none-win_arm64.whl", hash = "sha256:14a9528a8b70ccc7a847637c29e56fd1f9183a9db743bbc5b8e0c4ad60592a82"}, + {file = "ruff-0.6.3.tar.gz", hash = "sha256:183b99e9edd1ef63be34a3b51fee0a9f4ab95add123dbf89a71f7b1f0c991983"}, ] [[package]] From c4ddb3951130574b697aabd21cdbfdab4794828c Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Sat, 31 Aug 2024 00:09:57 +0000 Subject: [PATCH 55/59] chore(deps): update all dependencies --- poetry.lock | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/poetry.lock b/poetry.lock index 2a6a1bed2..cde6cab83 100644 --- a/poetry.lock +++ b/poetry.lock @@ -1369,19 +1369,23 @@ sqlalchemy = "*" [[package]] name = "setuptools" -version = "73.0.1" +version = "74.0.0" description = "Easily download, build, install, upgrade, and uninstall Python packages" optional = false python-versions = ">=3.8" files = [ - {file = "setuptools-73.0.1-py3-none-any.whl", hash = "sha256:b208925fcb9f7af924ed2dc04708ea89791e24bde0d3020b27df0e116088b34e"}, - {file = "setuptools-73.0.1.tar.gz", hash = "sha256:d59a3e788ab7e012ab2c4baed1b376da6366883ee20d7a5fc426816e3d7b1193"}, + {file = "setuptools-74.0.0-py3-none-any.whl", hash = "sha256:0274581a0037b638b9fc1c6883cc71c0210865aaa76073f7882376b641b84e8f"}, + {file = "setuptools-74.0.0.tar.gz", hash = "sha256:a85e96b8be2b906f3e3e789adec6a9323abf79758ecfa3065bd740d81158b11e"}, ] [package.extras] +check = ["pytest-checkdocs (>=2.4)", "pytest-ruff (>=0.2.1)", "ruff (>=0.5.2)"] core = ["importlib-metadata (>=6)", "importlib-resources (>=5.10.2)", "jaraco.text (>=3.7)", "more-itertools (>=8.8)", "packaging (>=24)", "platformdirs (>=2.6.2)", "tomli (>=2.0.1)", "wheel (>=0.43.0)"] +cover = ["pytest-cov"] doc = ["furo", "jaraco.packaging (>=9.3)", "jaraco.tidelift (>=1.4)", "pygments-github-lexers (==0.0.5)", "pyproject-hooks (!=1.1)", "rst.linker (>=1.9)", "sphinx (>=3.5)", "sphinx-favicon", "sphinx-inline-tabs", "sphinx-lint", "sphinx-notfound-page (>=1,<2)", "sphinx-reredirects", "sphinxcontrib-towncrier", "towncrier (<24.7)"] -test = ["build[virtualenv] (>=1.0.3)", "filelock (>=3.4.0)", "importlib-metadata", "ini2toml[lite] (>=0.14)", "jaraco.develop (>=7.21)", "jaraco.envs (>=2.2)", "jaraco.path (>=3.2.0)", "jaraco.test", "mypy (==1.11.*)", "packaging (>=23.2)", "pip (>=19.1)", "pyproject-hooks (!=1.1)", "pytest (>=6,!=8.1.*)", "pytest-checkdocs (>=2.4)", "pytest-cov", "pytest-enabler (>=2.2)", "pytest-home (>=0.5)", "pytest-mypy", "pytest-perf", "pytest-ruff (<0.4)", "pytest-ruff (>=0.2.1)", "pytest-ruff (>=0.3.2)", "pytest-subprocess", "pytest-timeout", "pytest-xdist (>=3)", "tomli", "tomli-w (>=1.0.0)", "virtualenv (>=13.0.0)", "wheel (>=0.44.0)"] +enabler = ["pytest-enabler (>=2.2)"] +test = ["build[virtualenv] (>=1.0.3)", "filelock (>=3.4.0)", "ini2toml[lite] (>=0.14)", "jaraco.develop (>=7.21)", "jaraco.envs (>=2.2)", "jaraco.path (>=3.2.0)", "jaraco.test", "packaging (>=23.2)", "pip (>=19.1)", "pyproject-hooks (!=1.1)", "pytest (>=6,!=8.1.*)", "pytest-home (>=0.5)", "pytest-perf", "pytest-subprocess", "pytest-timeout", "pytest-xdist (>=3)", "tomli-w (>=1.0.0)", "virtualenv (>=13.0.0)", "wheel (>=0.44.0)"] +type = ["importlib-metadata (>=7.0.2)", "jaraco.develop (>=7.21)", "mypy (==1.11.*)", "pytest-mypy"] [[package]] name = "six" From 64c57a736802f09af6aabc050a918b1d83325db1 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Mon, 2 Sep 2024 00:46:53 +0000 Subject: [PATCH 56/59] chore(deps): lock file maintenance --- poetry.lock | 18 +++++++++++------- 1 file changed, 11 insertions(+), 7 deletions(-) diff --git a/poetry.lock b/poetry.lock index 12c735504..3787dc4d1 100644 --- a/poetry.lock +++ b/poetry.lock @@ -166,13 +166,13 @@ lxml = ["lxml"] [[package]] name = "certifi" -version = "2024.7.4" +version = "2024.8.30" description = "Python package for providing Mozilla's CA Bundle." optional = false python-versions = ">=3.6" files = [ - {file = "certifi-2024.7.4-py3-none-any.whl", hash = "sha256:c198e21b1289c2ab85ee4e67bb4b4ef3ead0892059901a8d5b622f24a1101e90"}, - {file = "certifi-2024.7.4.tar.gz", hash = "sha256:5a1e7645bc0ec61a09e26c36f6106dd4cf40c6db3a1fb6352b0244e7fb057c7b"}, + {file = "certifi-2024.8.30-py3-none-any.whl", hash = "sha256:922820b53db7a7257ffbda3f597266d435245903d80737e34f8a45ff3e3230d8"}, + {file = "certifi-2024.8.30.tar.gz", hash = "sha256:bec941d2aa8195e248a60b31ff9f0558284cf01a52591ceda73ea9afffd69fd9"}, ] [[package]] @@ -1807,18 +1807,22 @@ zstd = ["zstandard (>=0.18.0)"] [[package]] name = "zipp" -version = "3.20.0" +version = "3.20.1" description = "Backport of pathlib-compatible object wrapper for zip files" optional = false python-versions = ">=3.8" files = [ - {file = "zipp-3.20.0-py3-none-any.whl", hash = "sha256:58da6168be89f0be59beb194da1250516fdaa062ccebd30127ac65d30045e10d"}, - {file = "zipp-3.20.0.tar.gz", hash = "sha256:0145e43d89664cfe1a2e533adc75adafed82fe2da404b4bbb6b026c0157bdb31"}, + {file = "zipp-3.20.1-py3-none-any.whl", hash = "sha256:9960cd8967c8f85a56f920d5d507274e74f9ff813a0ab8889a5b5be2daf44064"}, + {file = "zipp-3.20.1.tar.gz", hash = "sha256:c22b14cc4763c5a5b04134207736c107db42e9d3ef2d9779d465f5f1bcba572b"}, ] [package.extras] +check = ["pytest-checkdocs (>=2.4)", "pytest-ruff (>=0.2.1)"] +cover = ["pytest-cov"] doc = ["furo", "jaraco.packaging (>=9.3)", "jaraco.tidelift (>=1.4)", "rst.linker (>=1.9)", "sphinx (>=3.5)", "sphinx-lint"] -test = ["big-O", "importlib-resources", "jaraco.functools", "jaraco.itertools", "jaraco.test", "more-itertools", "pytest (>=6,!=8.1.*)", "pytest-checkdocs (>=2.4)", "pytest-cov", "pytest-enabler (>=2.2)", "pytest-ignore-flaky", "pytest-mypy", "pytest-ruff (>=0.2.1)"] +enabler = ["pytest-enabler (>=2.2)"] +test = ["big-O", "importlib-resources", "jaraco.functools", "jaraco.itertools", "jaraco.test", "more-itertools", "pytest (>=6,!=8.1.*)", "pytest-ignore-flaky"] +type = ["pytest-mypy"] [extras] aiopg = ["aiopg", "psycopg2-binary"] From 58eeca2038d60b6bb66a6d1ff23ea5e04f611cda Mon Sep 17 00:00:00 2001 From: Joachim Jablon Date: Wed, 4 Sep 2024 10:50:15 +0200 Subject: [PATCH 57/59] Update ci.yml --- .github/workflows/ci.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 9f22d8add..36e31446b 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -61,6 +61,7 @@ jobs: with: name: coverage-${{ matrix.python-version }} path: .coverage.${{ matrix.python-version }} + include-hidden-files: true static-typing: name: Run Pyright From 2d9d5b337ad07b86a6acaaa1cd14be1de56cd6ad Mon Sep 17 00:00:00 2001 From: Joachim Jablon Date: Fri, 6 Sep 2024 00:38:16 +0200 Subject: [PATCH 58/59] Fix dev-env: use docker compose instead of docker-compose --- CONTRIBUTING.md | 45 ++++++++++++++++++++++----------------------- dev-env | 2 +- 2 files changed, 23 insertions(+), 24 deletions(-) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 1a7f9171d..219664b6f 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -13,13 +13,13 @@ Of course, feel free to read the script before launching it. This script is intended to be a one-liner that sets up everything you need. It makes the following assumptions: -- You're using `MacOS` or `Linux`, and `bash` or `zsh`. -- You already have `python3` available -- You have `poetry` [installed](https://python-poetry.org/docs/#installation) -- Either you've already setup a PostgreSQL database and environment variables (`PG*`) - are set or you have `docker-compose` available and port 5432 is free. -- Either `psql` and other `libpq` executables are available in the `PATH` or they - are located in `usr/local/opt/libpq/bin` (`Homebrew`). +- You're using `MacOS` or `Linux`, and `bash` or `zsh`. +- You already have `python3` available +- You have `poetry` [installed](https://python-poetry.org/docs/#installation) +- Either you've already setup a PostgreSQL database and environment variables (`PG*`) + are set or you have `docker compose` available and port 5432 is free. +- Either `psql` and other `libpq` executables are available in the `PATH` or they + are located in `usr/local/opt/libpq/bin` (`Homebrew`). The `dev-env` script will add the `scripts` folder to your `$PATH` for the current shell, so in the following documentation, if you see `scripts/foo`, you're welcome @@ -46,7 +46,7 @@ The PostgreSQL database we used is a fresh standard out-of-the-box database on the latest stable version. ```console -$ docker-compose up -d postgres +$ docker compose up -d postgres ``` If you want to try out the project locally, it's useful to have `postgresql-client` @@ -129,7 +129,6 @@ In addition, an [editorconfig] file will help your favorite editor to respect procrastinate coding style. It is automatically used by most famous IDEs, such as Pycharm and VS Code. - ### Write the documentation The documentation is written in `Markdown` and built with `Sphinx` and `MyST`. @@ -301,23 +300,23 @@ Python environment on the host system. Alternatively, they can be installed in a image, and Procrastinate and all the development tools can be run in Docker containers. Docker is useful when you can't, or don't want to, install system requirements. -This section shows, through `docker-compose` command examples, how to test and run +This section shows, through `docker compose` command examples, how to test and run Procrastinate in Docker. Build the `procrastinate` Docker image: ```console $ export UID GID -$ docker-compose build procrastinate +$ docker compose build procrastinate ``` Run the automated tests: ```console -$ docker-compose run --rm procrastinate pytest +$ docker compose run --rm procrastinate pytest ``` -Docker Compose is configured (in `docker-compose.yml`) to mount the local directory on +Docker Compose is configured (in `docker compose.yml`) to mount the local directory on the host system onto `/src` in the container. This means that local changes made to the Procrastinate code are visible in Procrastinate containers. @@ -326,7 +325,7 @@ container to be run with the current user id and group id. If not set or exporte Procrastinate container will run as root, and files owned by root may be created in the developer's working directory. -In the definition of the `procrastinate` service in `docker-compose.yml` the +In the definition of the `procrastinate` service in `docker compose.yml` the `PROCRASTINATE_APP` variable is set to `procrastinate_demo.app.app` (the Procrastinate demo application). So `procrastinate` commands run in Procrastinate containers are always run as if they were passed `--app procrastinate_demo.app.app`. @@ -334,55 +333,55 @@ containers are always run as if they were passed `--app procrastinate_demo.app.a Run the `procrastinate` command : ```console -$ docker-compose run --rm procrastinate procrastinate -h +$ docker compose run --rm procrastinate procrastinate -h ``` Apply the Procrastinate database schema: ```console -$ docker-compose run --rm procrastinate procrastinate schema --apply +$ docker compose run --rm procrastinate procrastinate schema --apply ``` Run the Procrastinate healthchecks: ```console -$ docker-compose run --rm procrastinate procrastinate healthchecks +$ docker compose run --rm procrastinate procrastinate healthchecks ``` Start a Procrastinate worker (`-d` used to start the container in detached mode): ```console -$ docker-compose up -d procrastinate +$ docker compose up -d procrastinate ``` Run a command (`bash` here) in the Procrastinate worker container just started: ```console -$ docker-compose exec procrastinate bash +$ docker compose exec procrastinate bash ``` Watch the Procrastinate worker logs: ```console -$ docker-compose logs -ft procrastinate +$ docker compose logs -ft procrastinate ``` Use the `procrastinate defer` command to create a job: ```console -$ docker-compose run --rm procrastinate procrastinate defer procrastinate_demo.tasks.sum '{"a":3, "b": 5}' +$ docker compose run --rm procrastinate procrastinate defer procrastinate_demo.tasks.sum '{"a":3, "b": 5}' ``` Or run the demo main file: ```console -$ docker-compose run --rm procrastinate python -m procrastinate_demo +$ docker compose run --rm procrastinate python -m procrastinate_demo ``` Stop and remove all the containers (including the `postgres` container): ```console -$ docker-compose down +$ docker compose down ``` ## Wait, there are `async` and `await` keywords everywhere!? diff --git a/dev-env b/dev-env index 4543c2ffd..001a86fa0 100755 --- a/dev-env +++ b/dev-env @@ -26,7 +26,7 @@ export GID=$(id -g) if ! pg_isready ; then echo "Starting database" export PGDATABASE=procrastinate PGHOST=127.0.0.1 PGUSER=postgres PGPASSWORD=password - docker-compose up -d postgres || return + docker compose up -d postgres || return sleep 3 fi From 657941e0dec319622c13bc338d150f5afda83cc4 Mon Sep 17 00:00:00 2001 From: Joachim Jablon Date: Fri, 6 Sep 2024 00:44:04 +0200 Subject: [PATCH 59/59] tentative: fix test --- tests/unit/test_worker.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/tests/unit/test_worker.py b/tests/unit/test_worker.py index 030e79a11..24815ce58 100644 --- a/tests/unit/test_worker.py +++ b/tests/unit/test_worker.py @@ -207,9 +207,11 @@ async def test_worker_run_respects_polling(worker, app): await start_worker(worker) connector = cast(InMemoryConnector, app.connector) + await asyncio.sleep(0.01) + assert len([query for query in connector.queries if query[0] == "fetch_job"]) == 1 - await asyncio.sleep(0.05) + await asyncio.sleep(0.07) assert len([query for query in connector.queries if query[0] == "fetch_job"]) == 2