From 65757787d669b2286207d835e07fd67eb2d5c4b8 Mon Sep 17 00:00:00 2001 From: Tomer Nosrati Date: Mon, 4 Mar 2024 19:43:08 +0200 Subject: [PATCH] Refactored Dependecies Management (#225) * Removed "-n auto" from examples CI * Bugfix: Added pytest-celery package to built-in Celery worker Dockerfile * Refactored Dependecies Management * Disabled Memcached automatic detection due to "Experimental Status" --- .github/workflows/examples.yml | 16 +- .github/workflows/parallel-support.yml | 4 +- .github/workflows/python-package.yml | 6 +- .readthedocs.yaml | 2 +- docs/faq.rst | 2 +- docs/getting-started/first-steps.rst | 18 +- docs/getting-started/introduction.rst | 4 +- docs/getting-started/vendors.rst | 5 +- docs/includes/installation.txt | 68 +++++- examples/django/requirements.txt | 2 +- examples/django/tests/DjangoWorker.Dockerfile | 2 +- examples/myutils/requirements.txt | 2 +- examples/myworker/requirements.txt | 2 +- examples/rabbitmq_management/requirements.txt | 2 +- examples/range/requirements.txt | 2 +- poetry.lock | 209 ++++++++++-------- pyproject.toml | 64 +++--- src/pytest_celery/__init__.py | 123 ++++++++--- src/pytest_celery/defaults.py | 26 ++- src/pytest_celery/vendors/__init__.py | 18 ++ src/pytest_celery/vendors/worker/Dockerfile | 4 +- tox.ini | 16 +- 22 files changed, 390 insertions(+), 207 deletions(-) diff --git a/.github/workflows/examples.yml b/.github/workflows/examples.yml index 6985623a..5cfa71d6 100644 --- a/.github/workflows/examples.yml +++ b/.github/workflows/examples.yml @@ -11,12 +11,16 @@ on: - "**.txt" - ".github/workflows/examples.yml" - "**.toml" + - 'src/pytest_celery/vendors/worker/**' + - 'Dockerfile' pull_request: paths: - "**.py" - "**.txt" - "**.toml" - ".github/workflows/examples.yml" + - 'src/pytest_celery/vendors/worker/**' + - 'Dockerfile' permissions: contents: read # to fetch code (actions/checkout) @@ -53,7 +57,7 @@ jobs: working-directory: examples/myworker timeout-minutes: 10 run: | - pytest -vv tests -n auto + pytest -vv tests range: runs-on: ${{ matrix.os }} @@ -84,9 +88,9 @@ jobs: - name: Run tests working-directory: examples/range - timeout-minutes: 10 + timeout-minutes: 30 run: | - pytest -vv tests -n auto + pytest -vv tests rabbitmq_management: runs-on: ${{ matrix.os }} @@ -119,7 +123,7 @@ jobs: working-directory: examples/rabbitmq_management timeout-minutes: 10 run: | - pytest -vv tests -n auto + pytest -vv tests django: runs-on: ${{ matrix.os }} @@ -158,7 +162,7 @@ jobs: timeout-minutes: 10 run: | export DJANGO_SETTINGS_MODULE=proj.settings - pytest -vv tests -n auto + pytest -vv tests myutils: runs-on: ${{ matrix.os }} @@ -191,4 +195,4 @@ jobs: working-directory: examples/myutils timeout-minutes: 10 run: | - pytest -vv tests -n auto + pytest -vv tests diff --git a/.github/workflows/parallel-support.yml b/.github/workflows/parallel-support.yml index 74893c7b..50e81e5b 100644 --- a/.github/workflows/parallel-support.yml +++ b/.github/workflows/parallel-support.yml @@ -62,7 +62,7 @@ jobs: poetry install --only ci - name: Run tox for all environments in parallel - timeout-minutes: 15 + timeout-minutes: 30 run: | tox -e xdist @@ -104,6 +104,6 @@ jobs: poetry install --only ci - name: Run tox for all environments in parallel - timeout-minutes: 15 + timeout-minutes: 30 run: | tox -e parallel diff --git a/.github/workflows/python-package.yml b/.github/workflows/python-package.yml index 5357357d..d145a5b0 100644 --- a/.github/workflows/python-package.yml +++ b/.github/workflows/python-package.yml @@ -12,6 +12,8 @@ on: - ".github/workflows/python-package.yml" - "**.toml" - "tox.ini" + - 'src/pytest_celery/vendors/worker/**' + - 'Dockerfile' pull_request: paths: - "**.py" @@ -19,6 +21,8 @@ on: - "**.toml" - ".github/workflows/python-package.yml" - "tox.ini" + - 'src/pytest_celery/vendors/worker/**' + - 'Dockerfile' permissions: contents: read # to fetch code (actions/checkout) @@ -159,6 +163,6 @@ jobs: poetry install --only ci - name: Run tox for "${{ matrix.python-version }}-smoke" - timeout-minutes: 15 + timeout-minutes: 30 run: | tox --verbose --verbose -e "${{ matrix.python-version }}-smoke" -- -n auto --reruns 2 --rerun-except AssertionError diff --git a/.readthedocs.yaml b/.readthedocs.yaml index dee3c39e..c2325601 100644 --- a/.readthedocs.yaml +++ b/.readthedocs.yaml @@ -17,7 +17,7 @@ build: # Tell poetry to not use a virtual environment - poetry config virtualenvs.create false post_install: - - poetry install --with docs + - poetry install -E "all" --with docs # Build documentation in the "docs/" directory with Sphinx sphinx: diff --git a/docs/faq.rst b/docs/faq.rst index d93f22cf..92d4305f 100644 --- a/docs/faq.rst +++ b/docs/faq.rst @@ -167,7 +167,7 @@ To avoid these, you may: 1. Increase the resources available to Docker. 2. Use the :pypi:`pytest-rerunfailures` pytest plugin to retry failed tests with: -.. code-block:: bash +.. code-block:: console --reruns 5 --reruns-delay 60 --rerun-except AssertionError diff --git a/docs/getting-started/first-steps.rst b/docs/getting-started/first-steps.rst index 303d055e..641d82b2 100644 --- a/docs/getting-started/first-steps.rst +++ b/docs/getting-started/first-steps.rst @@ -148,7 +148,7 @@ This simple test then, Will run against all of the (enabled) possible combinations of the environment matrix. -.. code-block:: bash +.. code-block:: console pytest tests/test_example.py ======================================================================= test session starts =================================== @@ -165,7 +165,7 @@ With each iteration having its own isolated environment. RabbitMQ Broker Iteration Breakdown ################################### -.. code-block:: bash +.. code-block:: console docker ps CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES @@ -175,7 +175,7 @@ RabbitMQ Broker Iteration Breakdown With the worker configured correctly for its broker and backend. -.. code-block:: bash +.. code-block:: console -------------- celery_test_worker@0ffb4e75b5e4 v5.3.6 (emerald-rush) --- ***** ----- @@ -193,7 +193,7 @@ With the worker configured correctly for its broker and backend. With more verbose test logs. -.. code-block:: bash +.. code-block:: console ============================= test session starts ============================== ... @@ -215,7 +215,7 @@ With more verbose test logs. Redis Broker Iteration Breakdown ################################ -.. code-block:: bash +.. code-block:: console docker ps CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES @@ -225,7 +225,7 @@ Redis Broker Iteration Breakdown With the worker configured correctly for its broker and backend. -.. code-block:: bash +.. code-block:: console -------------- celery_test_worker@37e8ea35206f v5.3.6 (emerald-rush) --- ***** ----- @@ -243,7 +243,7 @@ With the worker configured correctly for its broker and backend. With more verbose test logs. -.. code-block:: bash +.. code-block:: console ============================= test session starts ============================== ... @@ -299,7 +299,7 @@ Or, testing the :ref:`default redis broker ` at the node level. Remember, each test case is isolated. This means that both of these tests can run in parallel, and **each will be assigned its own container instance.** -.. code-block:: bash +.. code-block:: console pytest tests/test_example.py -n auto ======================================================================= test session starts =================================== @@ -312,7 +312,7 @@ can run in parallel, and **each will be assigned its own container instance.** ======================================================================== 2 passed in 1.72s ==================================== -.. code-block:: bash +.. code-block:: console docker ps CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES diff --git a/docs/getting-started/introduction.rst b/docs/getting-started/introduction.rst index 1d2cf3f7..0731dfc7 100644 --- a/docs/getting-started/introduction.rst +++ b/docs/getting-started/introduction.rst @@ -9,7 +9,7 @@ .. contents:: :local: - :depth: 1 + :depth: 2 What is Pytest Celery? ====================== @@ -254,4 +254,6 @@ Quick Jump - :ref:`FAQ ` - :ref:`API Reference ` +.. _installation: + .. include:: ../includes/installation.txt diff --git a/docs/getting-started/vendors.rst b/docs/getting-started/vendors.rst index f9e990c2..1c304450 100644 --- a/docs/getting-started/vendors.rst +++ b/docs/getting-started/vendors.rst @@ -43,12 +43,13 @@ Experimental brokers may be functional but are not confirmed to be production ready. Enabled means that it is automatically added to the test setup matrix -when running the test suite. +when running the test suite :ref:`if the vendor dependencies are installed `. .. warning:: Enabling a new vendor will automatically add it globally to every test suite that relies - on the default configurations. Be careful when enabling new vendors. + on the default vendors detection. Be careful when enabling new vendors and make sure they are + stable and production ready. .. _built-in-worker: diff --git a/docs/includes/installation.txt b/docs/includes/installation.txt index 9b726178..3f5e5e61 100644 --- a/docs/includes/installation.txt +++ b/docs/includes/installation.txt @@ -1,20 +1,68 @@ -.. _installation: - Installation ============ -You can install Pytest Celery via the Python Package Index (PyPI). +The **pytest-celery** plugin can be easily installed via the Python Package Index (PyPI) using :command:`pip`. + +Installing the pytest-celery package +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -To install using :command:`pip`: +To install the latest version of **pytest-celery**, run the following command: .. code-block:: console - $ pip install -U pytest-celery + pip install -U pytest-celery + +This command installs **pytest-celery** along with its required dependencies. + +This will include: + +- Latest version of :pypi:`celery`. +- RabbitMQ broker via :pypi:`kombu`, installed as a dependency of Celery. + +Installing pytest-celery vendors +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +The plugin detects which vendor dependencies are installed in the test environment to configure +the default configurations automatically. This means that just by installing the matching dependencies, +the plugin will allow extending the default configurations, up to the supported built-in :ref:`vendors`. + +.. warning:: + + If you don't install any vendor (e.g. no extras and no manual installation), the plugin will result in an + empty setup matrix and might not be fully functional. + +To install the vendors, you may either install all of the dependencies manually, or use the following extras: + +- ``all``: Installs all vendors. +- ``redis``: Installs Redis vendor, providing **broker** and **result backend** components. +- ``memcached``: Installs Memcached vendor, providing a **result backend** component. + +The following extra is installed by default: + +- ``rabbitmq``: Installs RabbitMQ vendor, providing a **broker** component. + +To install **pytest-celery** with the built-in :ref:`vendors`, replace ```` with the name of the vendor. + +.. code-block:: console + + pip install -U "pytest-celery[]" + +RabbitMQ & Redis combo +---------------------- + +.. code-block:: console + + pip install -U "pytest-celery[redis]" + +This will configure the plugin to generate all possible setups using only RabbitMQ and Redis vendors. + +All vendors +----------- + +.. code-block:: console -The :pypi:`celery` package will be installed by default with the ``redis`` and ``pymemcache`` -`extras `_. + pip install -U "pytest-celery[all]" -With git -~~~~~~~~ +This will configure the plugin to generate all possible setups. -Please see the :ref:`Contributing ` section. +This approach allows you to tailor the installation to your project's specific needs by including only the necessary optional vendors. diff --git a/examples/django/requirements.txt b/examples/django/requirements.txt index a97a31b3..98a37508 100644 --- a/examples/django/requirements.txt +++ b/examples/django/requirements.txt @@ -1,5 +1,5 @@ sqlalchemy>=1.2.18 django>=2.2.1 pytest-django>=4.7.0 -git+https://github.com/celery/pytest-celery.git pytest-xdist>=3.5.0 +pytest-celery[all]@git+https://github.com/Katz-Consulting-Group/pytest-celery.git@bugfix diff --git a/examples/django/tests/DjangoWorker.Dockerfile b/examples/django/tests/DjangoWorker.Dockerfile index 9c4edd56..23727bc8 100644 --- a/examples/django/tests/DjangoWorker.Dockerfile +++ b/examples/django/tests/DjangoWorker.Dockerfile @@ -4,7 +4,7 @@ FROM python:3.11-bookworm RUN adduser --disabled-password --gecos "" test_user # Install system dependencies -RUN apt-get update && apt-get install -y build-essential +RUN apt-get update && apt-get install -y build-essential git # Set arguments ARG CELERY_LOG_LEVEL=INFO diff --git a/examples/myutils/requirements.txt b/examples/myutils/requirements.txt index a0c33720..b8a10941 100644 --- a/examples/myutils/requirements.txt +++ b/examples/myutils/requirements.txt @@ -1,3 +1,3 @@ pytest>=7.4.4 -git+https://github.com/celery/pytest-celery.git pytest-xdist>=3.5.0 +pytest-celery[all]@git+https://github.com/Katz-Consulting-Group/pytest-celery.git@bugfix diff --git a/examples/myworker/requirements.txt b/examples/myworker/requirements.txt index a0c33720..b8a10941 100644 --- a/examples/myworker/requirements.txt +++ b/examples/myworker/requirements.txt @@ -1,3 +1,3 @@ pytest>=7.4.4 -git+https://github.com/celery/pytest-celery.git pytest-xdist>=3.5.0 +pytest-celery[all]@git+https://github.com/Katz-Consulting-Group/pytest-celery.git@bugfix diff --git a/examples/rabbitmq_management/requirements.txt b/examples/rabbitmq_management/requirements.txt index a0c33720..b8a10941 100644 --- a/examples/rabbitmq_management/requirements.txt +++ b/examples/rabbitmq_management/requirements.txt @@ -1,3 +1,3 @@ pytest>=7.4.4 -git+https://github.com/celery/pytest-celery.git pytest-xdist>=3.5.0 +pytest-celery[all]@git+https://github.com/Katz-Consulting-Group/pytest-celery.git@bugfix diff --git a/examples/range/requirements.txt b/examples/range/requirements.txt index 182bf0c5..d893cd6b 100644 --- a/examples/range/requirements.txt +++ b/examples/range/requirements.txt @@ -1,4 +1,4 @@ pytest>=7.4.4 -git+https://github.com/celery/pytest-celery.git pytest-xdist>=3.5.0 pytest-subtests>=0.11.0 +pytest-celery[all]@git+https://github.com/Katz-Consulting-Group/pytest-celery.git@bugfix diff --git a/poetry.lock b/poetry.lock index 84f22b61..e7b1fad2 100644 --- a/poetry.lock +++ b/poetry.lock @@ -1,4 +1,4 @@ -# This file is automatically @generated by Poetry 1.8.1 and should not be changed by hand. +# This file is automatically @generated by Poetry 1.7.1 and should not be changed by hand. [[package]] name = "alabaster" @@ -54,7 +54,7 @@ typing-extensions = {version = ">=4.0.0", markers = "python_version < \"3.9\""} name = "async-timeout" version = "4.0.3" description = "Timeout context manager for asyncio programs" -optional = false +optional = true python-versions = ">=3.7" files = [ {file = "async-timeout-4.0.3.tar.gz", hash = "sha256:4640d96be84d82d02ed59ea2b7105a0f7b33abe8703703cd0ab0bf87c427522f"}, @@ -217,18 +217,18 @@ uvloop = ["uvloop (>=0.15.2)"] [[package]] name = "build" -version = "1.0.3" +version = "1.1.1" description = "A simple, correct Python build frontend" optional = false python-versions = ">= 3.7" files = [ - {file = "build-1.0.3-py3-none-any.whl", hash = "sha256:589bf99a67df7c9cf07ec0ac0e5e2ea5d4b37ac63301c4986d1acb126aa83f8f"}, - {file = "build-1.0.3.tar.gz", hash = "sha256:538aab1b64f9828977f84bc63ae570b060a8ed1be419e7870b8b4fc5e6ea553b"}, + {file = "build-1.1.1-py3-none-any.whl", hash = "sha256:8ed0851ee76e6e38adce47e4bee3b51c771d86c64cf578d0c2245567ee200e73"}, + {file = "build-1.1.1.tar.gz", hash = "sha256:8eea65bb45b1aac2e734ba2cc8dad3a6d97d97901a395bd0ed3e7b46953d2a31"}, ] [package.dependencies] colorama = {version = "*", markers = "os_name == \"nt\""} -importlib-metadata = {version = ">=4.6", markers = "python_version < \"3.10\""} +importlib-metadata = {version = ">=4.6", markers = "python_full_version < \"3.10.2\""} packaging = ">=19.0" pyproject_hooks = "*" tomli = {version = ">=1.1.0", markers = "python_version < \"3.11\""} @@ -291,8 +291,6 @@ click-plugins = ">=1.1.1" click-repl = ">=0.2.0" kombu = ">=5.3.4,<6.0" python-dateutil = ">=2.8.2" -python-memcached = {version = "1.59", optional = true, markers = "extra == \"pymemcache\""} -redis = {version = ">=4.5.2,<4.5.5 || >4.5.5,<6.0.0", optional = true, markers = "extra == \"redis\""} tzdata = ">=2022.7" vine = ">=5.1.0,<6.0" @@ -977,19 +975,19 @@ pyflakes = ">=2.5.0,<2.6.0" [[package]] name = "flake8" -version = "6.1.0" +version = "7.0.0" description = "the modular source code checker: pep8 pyflakes and co" optional = false python-versions = ">=3.8.1" files = [ - {file = "flake8-6.1.0-py2.py3-none-any.whl", hash = "sha256:ffdfce58ea94c6580c77888a86506937f9a1a227dfcd15f245d694ae20a6b6e5"}, - {file = "flake8-6.1.0.tar.gz", hash = "sha256:d5b3857f07c030bdb5bf41c7f53799571d75c4491748a3adcd47de929e34cd23"}, + {file = "flake8-7.0.0-py2.py3-none-any.whl", hash = "sha256:a6dfbb75e03252917f2473ea9653f7cd799c3064e54d4c8140044c5c065f53c3"}, + {file = "flake8-7.0.0.tar.gz", hash = "sha256:33f96621059e65eec474169085dc92bf26e7b2d47366b70be2f67ab80dc25132"}, ] [package.dependencies] mccabe = ">=0.7.0,<0.8.0" pycodestyle = ">=2.11.0,<2.12.0" -pyflakes = ">=3.1.0,<3.2.0" +pyflakes = ">=3.2.0,<3.3.0" [[package]] name = "identify" @@ -1316,67 +1314,68 @@ files = [ [[package]] name = "msgpack" -version = "1.0.7" +version = "1.0.8" description = "MessagePack serializer" optional = false python-versions = ">=3.8" files = [ - {file = "msgpack-1.0.7-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:04ad6069c86e531682f9e1e71b71c1c3937d6014a7c3e9edd2aa81ad58842862"}, - {file = "msgpack-1.0.7-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:cca1b62fe70d761a282496b96a5e51c44c213e410a964bdffe0928e611368329"}, - {file = "msgpack-1.0.7-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:e50ebce52f41370707f1e21a59514e3375e3edd6e1832f5e5235237db933c98b"}, - {file = "msgpack-1.0.7-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4a7b4f35de6a304b5533c238bee86b670b75b03d31b7797929caa7a624b5dda6"}, - {file = "msgpack-1.0.7-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:28efb066cde83c479dfe5a48141a53bc7e5f13f785b92ddde336c716663039ee"}, - {file = "msgpack-1.0.7-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:4cb14ce54d9b857be9591ac364cb08dc2d6a5c4318c1182cb1d02274029d590d"}, - {file = "msgpack-1.0.7-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:b573a43ef7c368ba4ea06050a957c2a7550f729c31f11dd616d2ac4aba99888d"}, - {file = "msgpack-1.0.7-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:ccf9a39706b604d884d2cb1e27fe973bc55f2890c52f38df742bc1d79ab9f5e1"}, - {file = "msgpack-1.0.7-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:cb70766519500281815dfd7a87d3a178acf7ce95390544b8c90587d76b227681"}, - {file = "msgpack-1.0.7-cp310-cp310-win32.whl", hash = "sha256:b610ff0f24e9f11c9ae653c67ff8cc03c075131401b3e5ef4b82570d1728f8a9"}, - {file = "msgpack-1.0.7-cp310-cp310-win_amd64.whl", hash = "sha256:a40821a89dc373d6427e2b44b572efc36a2778d3f543299e2f24eb1a5de65415"}, - {file = "msgpack-1.0.7-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:576eb384292b139821c41995523654ad82d1916da6a60cff129c715a6223ea84"}, - {file = "msgpack-1.0.7-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:730076207cb816138cf1af7f7237b208340a2c5e749707457d70705715c93b93"}, - {file = "msgpack-1.0.7-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:85765fdf4b27eb5086f05ac0491090fc76f4f2b28e09d9350c31aac25a5aaff8"}, - {file = "msgpack-1.0.7-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3476fae43db72bd11f29a5147ae2f3cb22e2f1a91d575ef130d2bf49afd21c46"}, - {file = "msgpack-1.0.7-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6d4c80667de2e36970ebf74f42d1088cc9ee7ef5f4e8c35eee1b40eafd33ca5b"}, - {file = "msgpack-1.0.7-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:5b0bf0effb196ed76b7ad883848143427a73c355ae8e569fa538365064188b8e"}, - {file = "msgpack-1.0.7-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:f9a7c509542db4eceed3dcf21ee5267ab565a83555c9b88a8109dcecc4709002"}, - {file = "msgpack-1.0.7-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:84b0daf226913133f899ea9b30618722d45feffa67e4fe867b0b5ae83a34060c"}, - {file = "msgpack-1.0.7-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:ec79ff6159dffcc30853b2ad612ed572af86c92b5168aa3fc01a67b0fa40665e"}, - {file = "msgpack-1.0.7-cp311-cp311-win32.whl", hash = "sha256:3e7bf4442b310ff154b7bb9d81eb2c016b7d597e364f97d72b1acc3817a0fdc1"}, - {file = "msgpack-1.0.7-cp311-cp311-win_amd64.whl", hash = "sha256:3f0c8c6dfa6605ab8ff0611995ee30d4f9fcff89966cf562733b4008a3d60d82"}, - {file = "msgpack-1.0.7-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:f0936e08e0003f66bfd97e74ee530427707297b0d0361247e9b4f59ab78ddc8b"}, - {file = "msgpack-1.0.7-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:98bbd754a422a0b123c66a4c341de0474cad4a5c10c164ceed6ea090f3563db4"}, - {file = "msgpack-1.0.7-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:b291f0ee7961a597cbbcc77709374087fa2a9afe7bdb6a40dbbd9b127e79afee"}, - {file = "msgpack-1.0.7-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ebbbba226f0a108a7366bf4b59bf0f30a12fd5e75100c630267d94d7f0ad20e5"}, - {file = "msgpack-1.0.7-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:1e2d69948e4132813b8d1131f29f9101bc2c915f26089a6d632001a5c1349672"}, - {file = "msgpack-1.0.7-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:bdf38ba2d393c7911ae989c3bbba510ebbcdf4ecbdbfec36272abe350c454075"}, - {file = "msgpack-1.0.7-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:993584fc821c58d5993521bfdcd31a4adf025c7d745bbd4d12ccfecf695af5ba"}, - {file = "msgpack-1.0.7-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:52700dc63a4676669b341ba33520f4d6e43d3ca58d422e22ba66d1736b0a6e4c"}, - {file = "msgpack-1.0.7-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:e45ae4927759289c30ccba8d9fdce62bb414977ba158286b5ddaf8df2cddb5c5"}, - {file = "msgpack-1.0.7-cp312-cp312-win32.whl", hash = "sha256:27dcd6f46a21c18fa5e5deed92a43d4554e3df8d8ca5a47bf0615d6a5f39dbc9"}, - {file = "msgpack-1.0.7-cp312-cp312-win_amd64.whl", hash = "sha256:7687e22a31e976a0e7fc99c2f4d11ca45eff652a81eb8c8085e9609298916dcf"}, - {file = "msgpack-1.0.7-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:5b6ccc0c85916998d788b295765ea0e9cb9aac7e4a8ed71d12e7d8ac31c23c95"}, - {file = "msgpack-1.0.7-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:235a31ec7db685f5c82233bddf9858748b89b8119bf4538d514536c485c15fe0"}, - {file = "msgpack-1.0.7-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:cab3db8bab4b7e635c1c97270d7a4b2a90c070b33cbc00c99ef3f9be03d3e1f7"}, - {file = "msgpack-1.0.7-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0bfdd914e55e0d2c9e1526de210f6fe8ffe9705f2b1dfcc4aecc92a4cb4b533d"}, - {file = "msgpack-1.0.7-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:36e17c4592231a7dbd2ed09027823ab295d2791b3b1efb2aee874b10548b7524"}, - {file = "msgpack-1.0.7-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:38949d30b11ae5f95c3c91917ee7a6b239f5ec276f271f28638dec9156f82cfc"}, - {file = "msgpack-1.0.7-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:ff1d0899f104f3921d94579a5638847f783c9b04f2d5f229392ca77fba5b82fc"}, - {file = "msgpack-1.0.7-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:dc43f1ec66eb8440567186ae2f8c447d91e0372d793dfe8c222aec857b81a8cf"}, - {file = "msgpack-1.0.7-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:dd632777ff3beaaf629f1ab4396caf7ba0bdd075d948a69460d13d44357aca4c"}, - {file = "msgpack-1.0.7-cp38-cp38-win32.whl", hash = "sha256:4e71bc4416de195d6e9b4ee93ad3f2f6b2ce11d042b4d7a7ee00bbe0358bd0c2"}, - {file = "msgpack-1.0.7-cp38-cp38-win_amd64.whl", hash = "sha256:8f5b234f567cf76ee489502ceb7165c2a5cecec081db2b37e35332b537f8157c"}, - {file = "msgpack-1.0.7-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:bfef2bb6ef068827bbd021017a107194956918ab43ce4d6dc945ffa13efbc25f"}, - {file = "msgpack-1.0.7-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:484ae3240666ad34cfa31eea7b8c6cd2f1fdaae21d73ce2974211df099a95d81"}, - {file = "msgpack-1.0.7-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:3967e4ad1aa9da62fd53e346ed17d7b2e922cba5ab93bdd46febcac39be636fc"}, - {file = "msgpack-1.0.7-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8dd178c4c80706546702c59529ffc005681bd6dc2ea234c450661b205445a34d"}, - {file = "msgpack-1.0.7-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f6ffbc252eb0d229aeb2f9ad051200668fc3a9aaa8994e49f0cb2ffe2b7867e7"}, - {file = "msgpack-1.0.7-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:822ea70dc4018c7e6223f13affd1c5c30c0f5c12ac1f96cd8e9949acddb48a61"}, - {file = "msgpack-1.0.7-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:384d779f0d6f1b110eae74cb0659d9aa6ff35aaf547b3955abf2ab4c901c4819"}, - {file = "msgpack-1.0.7-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:f64e376cd20d3f030190e8c32e1c64582eba56ac6dc7d5b0b49a9d44021b52fd"}, - {file = "msgpack-1.0.7-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:5ed82f5a7af3697b1c4786053736f24a0efd0a1b8a130d4c7bfee4b9ded0f08f"}, - {file = "msgpack-1.0.7-cp39-cp39-win32.whl", hash = "sha256:f26a07a6e877c76a88e3cecac8531908d980d3d5067ff69213653649ec0f60ad"}, - {file = "msgpack-1.0.7-cp39-cp39-win_amd64.whl", hash = "sha256:1dc93e8e4653bdb5910aed79f11e165c85732067614f180f70534f056da97db3"}, - {file = "msgpack-1.0.7.tar.gz", hash = "sha256:572efc93db7a4d27e404501975ca6d2d9775705c2d922390d878fcf768d92c87"}, + {file = "msgpack-1.0.8-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:505fe3d03856ac7d215dbe005414bc28505d26f0c128906037e66d98c4e95868"}, + {file = "msgpack-1.0.8-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:e6b7842518a63a9f17107eb176320960ec095a8ee3b4420b5f688e24bf50c53c"}, + {file = "msgpack-1.0.8-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:376081f471a2ef24828b83a641a02c575d6103a3ad7fd7dade5486cad10ea659"}, + {file = "msgpack-1.0.8-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5e390971d082dba073c05dbd56322427d3280b7cc8b53484c9377adfbae67dc2"}, + {file = "msgpack-1.0.8-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:00e073efcba9ea99db5acef3959efa45b52bc67b61b00823d2a1a6944bf45982"}, + {file = "msgpack-1.0.8-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:82d92c773fbc6942a7a8b520d22c11cfc8fd83bba86116bfcf962c2f5c2ecdaa"}, + {file = "msgpack-1.0.8-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:9ee32dcb8e531adae1f1ca568822e9b3a738369b3b686d1477cbc643c4a9c128"}, + {file = "msgpack-1.0.8-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:e3aa7e51d738e0ec0afbed661261513b38b3014754c9459508399baf14ae0c9d"}, + {file = "msgpack-1.0.8-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:69284049d07fce531c17404fcba2bb1df472bc2dcdac642ae71a2d079d950653"}, + {file = "msgpack-1.0.8-cp310-cp310-win32.whl", hash = "sha256:13577ec9e247f8741c84d06b9ece5f654920d8365a4b636ce0e44f15e07ec693"}, + {file = "msgpack-1.0.8-cp310-cp310-win_amd64.whl", hash = "sha256:e532dbd6ddfe13946de050d7474e3f5fb6ec774fbb1a188aaf469b08cf04189a"}, + {file = "msgpack-1.0.8-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:9517004e21664f2b5a5fd6333b0731b9cf0817403a941b393d89a2f1dc2bd836"}, + {file = "msgpack-1.0.8-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:d16a786905034e7e34098634b184a7d81f91d4c3d246edc6bd7aefb2fd8ea6ad"}, + {file = "msgpack-1.0.8-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:e2872993e209f7ed04d963e4b4fbae72d034844ec66bc4ca403329db2074377b"}, + {file = "msgpack-1.0.8-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5c330eace3dd100bdb54b5653b966de7f51c26ec4a7d4e87132d9b4f738220ba"}, + {file = "msgpack-1.0.8-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:83b5c044f3eff2a6534768ccfd50425939e7a8b5cf9a7261c385de1e20dcfc85"}, + {file = "msgpack-1.0.8-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:1876b0b653a808fcd50123b953af170c535027bf1d053b59790eebb0aeb38950"}, + {file = "msgpack-1.0.8-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:dfe1f0f0ed5785c187144c46a292b8c34c1295c01da12e10ccddfc16def4448a"}, + {file = "msgpack-1.0.8-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:3528807cbbb7f315bb81959d5961855e7ba52aa60a3097151cb21956fbc7502b"}, + {file = "msgpack-1.0.8-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:e2f879ab92ce502a1e65fce390eab619774dda6a6ff719718069ac94084098ce"}, + {file = "msgpack-1.0.8-cp311-cp311-win32.whl", hash = "sha256:26ee97a8261e6e35885c2ecd2fd4a6d38252246f94a2aec23665a4e66d066305"}, + {file = "msgpack-1.0.8-cp311-cp311-win_amd64.whl", hash = "sha256:eadb9f826c138e6cf3c49d6f8de88225a3c0ab181a9b4ba792e006e5292d150e"}, + {file = "msgpack-1.0.8-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:114be227f5213ef8b215c22dde19532f5da9652e56e8ce969bf0a26d7c419fee"}, + {file = "msgpack-1.0.8-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:d661dc4785affa9d0edfdd1e59ec056a58b3dbb9f196fa43587f3ddac654ac7b"}, + {file = "msgpack-1.0.8-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:d56fd9f1f1cdc8227d7b7918f55091349741904d9520c65f0139a9755952c9e8"}, + {file = "msgpack-1.0.8-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0726c282d188e204281ebd8de31724b7d749adebc086873a59efb8cf7ae27df3"}, + {file = "msgpack-1.0.8-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8db8e423192303ed77cff4dce3a4b88dbfaf43979d280181558af5e2c3c71afc"}, + {file = "msgpack-1.0.8-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:99881222f4a8c2f641f25703963a5cefb076adffd959e0558dc9f803a52d6a58"}, + {file = "msgpack-1.0.8-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:b5505774ea2a73a86ea176e8a9a4a7c8bf5d521050f0f6f8426afe798689243f"}, + {file = "msgpack-1.0.8-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:ef254a06bcea461e65ff0373d8a0dd1ed3aa004af48839f002a0c994a6f72d04"}, + {file = "msgpack-1.0.8-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:e1dd7839443592d00e96db831eddb4111a2a81a46b028f0facd60a09ebbdd543"}, + {file = "msgpack-1.0.8-cp312-cp312-win32.whl", hash = "sha256:64d0fcd436c5683fdd7c907eeae5e2cbb5eb872fafbc03a43609d7941840995c"}, + {file = "msgpack-1.0.8-cp312-cp312-win_amd64.whl", hash = "sha256:74398a4cf19de42e1498368c36eed45d9528f5fd0155241e82c4082b7e16cffd"}, + {file = "msgpack-1.0.8-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:0ceea77719d45c839fd73abcb190b8390412a890df2f83fb8cf49b2a4b5c2f40"}, + {file = "msgpack-1.0.8-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:1ab0bbcd4d1f7b6991ee7c753655b481c50084294218de69365f8f1970d4c151"}, + {file = "msgpack-1.0.8-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:1cce488457370ffd1f953846f82323cb6b2ad2190987cd4d70b2713e17268d24"}, + {file = "msgpack-1.0.8-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3923a1778f7e5ef31865893fdca12a8d7dc03a44b33e2a5f3295416314c09f5d"}, + {file = "msgpack-1.0.8-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a22e47578b30a3e199ab067a4d43d790249b3c0587d9a771921f86250c8435db"}, + {file = "msgpack-1.0.8-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:bd739c9251d01e0279ce729e37b39d49a08c0420d3fee7f2a4968c0576678f77"}, + {file = "msgpack-1.0.8-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:d3420522057ebab1728b21ad473aa950026d07cb09da41103f8e597dfbfaeb13"}, + {file = "msgpack-1.0.8-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:5845fdf5e5d5b78a49b826fcdc0eb2e2aa7191980e3d2cfd2a30303a74f212e2"}, + {file = "msgpack-1.0.8-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:6a0e76621f6e1f908ae52860bdcb58e1ca85231a9b0545e64509c931dd34275a"}, + {file = "msgpack-1.0.8-cp38-cp38-win32.whl", hash = "sha256:374a8e88ddab84b9ada695d255679fb99c53513c0a51778796fcf0944d6c789c"}, + {file = "msgpack-1.0.8-cp38-cp38-win_amd64.whl", hash = "sha256:f3709997b228685fe53e8c433e2df9f0cdb5f4542bd5114ed17ac3c0129b0480"}, + {file = "msgpack-1.0.8-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:f51bab98d52739c50c56658cc303f190785f9a2cd97b823357e7aeae54c8f68a"}, + {file = "msgpack-1.0.8-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:73ee792784d48aa338bba28063e19a27e8d989344f34aad14ea6e1b9bd83f596"}, + {file = "msgpack-1.0.8-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:f9904e24646570539a8950400602d66d2b2c492b9010ea7e965025cb71d0c86d"}, + {file = "msgpack-1.0.8-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e75753aeda0ddc4c28dce4c32ba2f6ec30b1b02f6c0b14e547841ba5b24f753f"}, + {file = "msgpack-1.0.8-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:5dbf059fb4b7c240c873c1245ee112505be27497e90f7c6591261c7d3c3a8228"}, + {file = "msgpack-1.0.8-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:4916727e31c28be8beaf11cf117d6f6f188dcc36daae4e851fee88646f5b6b18"}, + {file = "msgpack-1.0.8-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:7938111ed1358f536daf311be244f34df7bf3cdedb3ed883787aca97778b28d8"}, + {file = "msgpack-1.0.8-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:493c5c5e44b06d6c9268ce21b302c9ca055c1fd3484c25ba41d34476c76ee746"}, + {file = "msgpack-1.0.8-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:5fbb160554e319f7b22ecf530a80a3ff496d38e8e07ae763b9e82fadfe96f273"}, + {file = "msgpack-1.0.8-cp39-cp39-win32.whl", hash = "sha256:f9af38a89b6a5c04b7d18c492c8ccf2aee7048aff1ce8437c4683bb5a1df893d"}, + {file = "msgpack-1.0.8-cp39-cp39-win_amd64.whl", hash = "sha256:ed59dd52075f8fc91da6053b12e8c89e37aa043f8986efd89e61fae69dc1b011"}, + {file = "msgpack-1.0.8-py3-none-any.whl", hash = "sha256:24f727df1e20b9876fa6e95f840a2a2651e34c0ad147676356f4bf5fbb0206ca"}, + {file = "msgpack-1.0.8.tar.gz", hash = "sha256:95c02b0e27e706e48d0e5426d1710ca78e0f0628d6e89d5b5a5b91a5f12274f3"}, ] [[package]] @@ -1489,17 +1488,17 @@ ptyprocess = ">=0.5" [[package]] name = "pkginfo" -version = "1.9.6" +version = "1.10.0" description = "Query metadata from sdists / bdists / installed packages." optional = false python-versions = ">=3.6" files = [ - {file = "pkginfo-1.9.6-py3-none-any.whl", hash = "sha256:4b7a555a6d5a22169fcc9cf7bfd78d296b0361adad412a346c1226849af5e546"}, - {file = "pkginfo-1.9.6.tar.gz", hash = "sha256:8fd5896e8718a4372f0ea9cc9d96f6417c9b986e23a4d116dda26b62cc29d046"}, + {file = "pkginfo-1.10.0-py3-none-any.whl", hash = "sha256:889a6da2ed7ffc58ab5b900d888ddce90bce912f2d2de1dc1c26f4cb9fe65097"}, + {file = "pkginfo-1.10.0.tar.gz", hash = "sha256:5df73835398d10db79f8eecd5cd86b1f6d29317589ea70796994d49399af6297"}, ] [package.extras] -testing = ["pytest", "pytest-cov"] +testing = ["pytest", "pytest-cov", "wheel"] [[package]] name = "platformdirs" @@ -1533,13 +1532,13 @@ testing = ["pytest", "pytest-benchmark"] [[package]] name = "poetry" -version = "1.8.1" +version = "1.8.2" description = "Python dependency management and packaging made easy." optional = false python-versions = ">=3.8,<4.0" files = [ - {file = "poetry-1.8.1-py3-none-any.whl", hash = "sha256:cf133946661025822672422769567980f8e489ed5b6fc170d1025a4d6c9aac29"}, - {file = "poetry-1.8.1.tar.gz", hash = "sha256:23519cc45eb3cf48e899145bc762425a141e3afd52ecc53ec443ca635122327f"}, + {file = "poetry-1.8.2-py3-none-any.whl", hash = "sha256:b42b400d9a803af6e788a30a6f3e9998020b77860e28df20647eb10b6f414910"}, + {file = "poetry-1.8.2.tar.gz", hash = "sha256:49cceb3838104647c3e1021f3a4f13c6053704cc18d33f849a90fe687a29cb73"}, ] [package.dependencies] @@ -1628,6 +1627,24 @@ nodeenv = ">=0.11.1" pyyaml = ">=5.1" virtualenv = ">=20.10.0" +[[package]] +name = "pre-commit" +version = "3.6.2" +description = "A framework for managing and maintaining multi-language pre-commit hooks." +optional = false +python-versions = ">=3.9" +files = [ + {file = "pre_commit-3.6.2-py2.py3-none-any.whl", hash = "sha256:ba637c2d7a670c10daedc059f5c49b5bd0aadbccfcd7ec15592cf9665117532c"}, + {file = "pre_commit-3.6.2.tar.gz", hash = "sha256:c3ef34f463045c88658c5b99f38c1e297abdcc0ff13f98d3370055fbbfabc67e"}, +] + +[package.dependencies] +cfgv = ">=2.0.0" +identify = ">=1.0.0" +nodeenv = ">=0.11.1" +pyyaml = ">=5.1" +virtualenv = ">=20.10.0" + [[package]] name = "prompt-toolkit" version = "3.0.43" @@ -1848,13 +1865,13 @@ files = [ [[package]] name = "pyflakes" -version = "3.1.0" +version = "3.2.0" description = "passive checker of Python programs" optional = false python-versions = ">=3.8" files = [ - {file = "pyflakes-3.1.0-py2.py3-none-any.whl", hash = "sha256:4132f6d49cb4dae6819e5379898f2b8cce3c5f23994194c24b77d5da2e36f774"}, - {file = "pyflakes-3.1.0.tar.gz", hash = "sha256:a0aae034c444db0071aa077972ba4768d40c830d9539fd45bf4cd3f8f6992efc"}, + {file = "pyflakes-3.2.0-py2.py3-none-any.whl", hash = "sha256:84b5be138a2dfbb40689ca07e2152deb896a65c3a3e24c251c5c62489568074a"}, + {file = "pyflakes-3.2.0.tar.gz", hash = "sha256:1c61603ff154621fb2a9172037d84dca3500def8c8b630657d1701f026f8af3f"}, ] [[package]] @@ -2031,13 +2048,13 @@ testing = ["filelock"] [[package]] name = "python-dateutil" -version = "2.8.2" +version = "2.9.0.post0" description = "Extensions to the standard Python datetime module" optional = false python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,>=2.7" files = [ - {file = "python-dateutil-2.8.2.tar.gz", hash = "sha256:0123cacc1627ae19ddf3c27a5de5bd67ee4586fbdd6440d9748f8abb483d3e86"}, - {file = "python_dateutil-2.8.2-py2.py3-none-any.whl", hash = "sha256:961d03dc3453ebbc59dbdea9e4e11c5651520a876d0f4db161e8674aae935da9"}, + {file = "python-dateutil-2.9.0.post0.tar.gz", hash = "sha256:37dd54208da7e1cd875388217d5e00ebd4179249f90fb72437e91a35459a0ad3"}, + {file = "python_dateutil-2.9.0.post0-py2.py3-none-any.whl", hash = "sha256:a8b2bc7bffae282281c8140a97d3aa9c14da0b136dfe83f850eea9a5f7470427"}, ] [package.dependencies] @@ -2045,18 +2062,15 @@ six = ">=1.5" [[package]] name = "python-memcached" -version = "1.59" +version = "1.62" description = "Pure python memcached client" -optional = false +optional = true python-versions = "*" files = [ - {file = "python-memcached-1.59.tar.gz", hash = "sha256:a2e28637be13ee0bf1a8b6843e7490f9456fd3f2a4cb60471733c7b5d5557e4f"}, - {file = "python_memcached-1.59-py2.py3-none-any.whl", hash = "sha256:4dac64916871bd3550263323fc2ce18e1e439080a2d5670c594cf3118d99b594"}, + {file = "python-memcached-1.62.tar.gz", hash = "sha256:0285470599b7f593fbf3bec084daa1f483221e68c1db2cf1d846a9f7c2655103"}, + {file = "python_memcached-1.62-py2.py3-none-any.whl", hash = "sha256:1bdd8d2393ff53e80cd5e9442d750e658e0b35c3eebb3211af137303e3b729d1"}, ] -[package.dependencies] -six = ">=1.4.0" - [[package]] name = "pytz" version = "2024.1" @@ -2268,7 +2282,7 @@ full = ["numpy"] name = "redis" version = "5.0.2" description = "Python client for Redis database and key-value store" -optional = false +optional = true python-versions = ">=3.7" files = [ {file = "redis-5.0.2-py3-none-any.whl", hash = "sha256:4caa8e1fcb6f3c0ef28dba99535101d80934b7d4cd541bbb47f4a3826ee472d1"}, @@ -2869,13 +2883,13 @@ testing = ["black", "devpi-process", "flake8 (>=6,<7)", "mypy", "pytest (>=7,<8) [[package]] name = "trove-classifiers" -version = "2024.2.23" +version = "2024.3.3" description = "Canonical source for classifiers on PyPI (pypi.org)." optional = false python-versions = "*" files = [ - {file = "trove-classifiers-2024.2.23.tar.gz", hash = "sha256:8385160a12aac69c93fff058fb613472ed773a24a27eb3cd4b144cfbdd79f38c"}, - {file = "trove_classifiers-2024.2.23-py3-none-any.whl", hash = "sha256:3094534b8021dc1822aadb1d11d4c7b62a854d464d19458fd0a49d6fe2b68b77"}, + {file = "trove-classifiers-2024.3.3.tar.gz", hash = "sha256:df7edff9c67ff86b733628998330b180e81d125b1e096536d83ac0fd79673fdc"}, + {file = "trove_classifiers-2024.3.3-py3-none-any.whl", hash = "sha256:3a84096861b385ec422c79995d1f6435dde47a9b63adaa3c886e53232ba7e6e0"}, ] [[package]] @@ -3076,7 +3090,12 @@ files = [ docs = ["furo", "jaraco.packaging (>=9.3)", "jaraco.tidelift (>=1.4)", "rst.linker (>=1.9)", "sphinx (<7.2.5)", "sphinx (>=3.5)", "sphinx-lint"] testing = ["big-O", "jaraco.functools", "jaraco.itertools", "more-itertools", "pytest (>=6)", "pytest-black (>=0.3.7)", "pytest-checkdocs (>=2.4)", "pytest-cov", "pytest-enabler (>=2.2)", "pytest-ignore-flaky", "pytest-mypy (>=0.9.1)", "pytest-ruff"] +[extras] +all = ["python-memcached", "redis"] +memcached = ["python-memcached"] +redis = ["redis"] + [metadata] lock-version = "2.0" -python-versions = ">= 3.8,<4.0" -content-hash = "3fada5411477ce7c77a50f589addba6655625c256d5e2b614706f45d59786b9c" +python-versions = ">=3.8,<4.0" +content-hash = "e74916e8d0f294f0e480f8f3ad71e03ba7ea6dcab43e89bc06c3de88d0434ee1" diff --git a/pyproject.toml b/pyproject.toml index 92f90d41..035ed75c 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -72,51 +72,59 @@ search = ':Version: {current_version}' replace = ':Version: {new_version}' [tool.poetry.dependencies] -celery = { version = "^5.0.0", extras = ["redis", "pymemcache"] } -python = ">= 3.8,<4.0" -retry = "^0.9.2" -pytest-docker-tools = "^3.1.3" +celery = { version = "*" } +redis = { version = "*", optional = true } +python-memcached = { version = "*", optional = true } +python = ">=3.8,<4.0" +retry = ">=0.9.2" +pytest-docker-tools = ">=3.1.3" docker = "^7.0.0" -psutil = "^5.9.7" -setuptools = "^69.1.0" +psutil = ">=5.9.7" +setuptools = ">=69.1.0" + +[tool.poetry.extras] +all = ["redis", "python-memcached"] +redis = ["redis"] +memcached = ["python-memcached"] [tool.poetry.group.dev] [tool.poetry.group.dev.dependencies] -poetry-bumpversion = "^0.3.2" +poetry-bumpversion = ">=0.3.2" black = "*" -toml-sort = "^0.23.1" +toml-sort = ">=0.23.1" autoflake = [ { version = "^1.7.0", python = "<3.8.1" }, - { version = "^2.0.0", python = ">=3.8.1,<4.0" }, + { version = ">=2.0.0", python = ">=3.8.1,<4.0" }, ] isort = [ { version = "^5.11.0", python = "<3.8.0" }, - { version = "^5.12.0", python = ">=3.8.0,<4.0" }, + { version = ">=5.12.0", python = ">=3.8.0,<4.0" }, ] flake8 = [ { version = "^5.0.0", python = "<3.8.1" }, - { version = "^6.0.0", python = ">=3.8.1,<4.0" }, + { version = ">=6.0.0", python = ">=3.8.1,<4.0" }, ] pre-commit = [ { version = "^2.21.0", python = "<3.8.0" }, { version = "^3.1.0", python = ">=3.8.0,<4.0" }, + { version = ">=3.6.0", python = ">=3.9.0,<4.0" }, ] -mypy = "^1.0.1" -types-redis = "^4.6.0.20240218" -cleanpy = "^0.4.0" +mypy = ">=1.0.1" +types-redis = ">=4.6.0.20240218" +cleanpy = ">=0.4.0" [tool.poetry.group.test] optional = true [tool.poetry.group.test.dependencies] pytest = "^8.0.1" -coverage = "^7.4.2" -pytest-sugar = { version = "^1.0.0", python = ">=3.8,<4.0" } -pytest-cov = "^4.0.0" -pytest-xdist = "^3.1.0" -pytest-subtests = "^0.11.0" -pytest-rerunfailures = "^13.0" +coverage = ">=7.4.2" +pytest-sugar = { version = ">=1.0.0", python = ">=3.8,<4.0" } +pytest-cov = ">=4.0.0" +pytest-xdist = ">=3.1.0" +pytest-subtests = ">=0.11.0" +pytest-rerunfailures = ">=13.0.0" [tool.poetry.group.ci] optional = true @@ -124,26 +132,26 @@ optional = true [tool.poetry.group.ci.dependencies] tox = [ { version = "^3.0.0", python = "<3.8.1" }, - { version = "^4.0.0", python = ">=3.8.1,<4.0" }, + { version = ">=4.0.0", python = ">=3.8.1,<4.0" }, ] tox-gh-actions = [ { version = "^2.0.0", python = "<3.8.1" }, - { version = "^3.0.0", python = ">=3.8.1,<4.0" }, + { version = ">=3.0.0", python = ">=3.8.1,<4.0" }, ] [tool.poetry.group.docs] optional = true [tool.poetry.group.docs.dependencies] -sphinx_celery = "^2.1.3" +sphinx_celery = ">=2.1.3" Sphinx = [ { version = "^7.1.0", python = "<3.9" }, - { version = "^7.0.0", python = ">=3.9,<4.0" }, + { version = ">=7.0.0", python = ">=3.9,<4.0" }, ] -sphinx-testing = "^1.0.1" -sphinx-click = "^5.1.0" -sphinx-autobuild = "^2021.3.14" -sphinxcontrib-mermaid = "^0.9.2" +sphinx-testing = ">=1.0.1" +sphinx-click = ">=5.1.0" +sphinx-autobuild = ">=2021.3.14" +sphinxcontrib-mermaid = ">=0.9.2" [tool.poetry.plugins.pytest11] celery = "pytest_celery.plugin" diff --git a/src/pytest_celery/__init__.py b/src/pytest_celery/__init__.py index 75183b8a..a4bc7bbe 100644 --- a/src/pytest_celery/__init__.py +++ b/src/pytest_celery/__init__.py @@ -13,34 +13,103 @@ import re from collections import namedtuple -from pytest_celery.api.backend import * -from pytest_celery.api.base import * -from pytest_celery.api.broker import * -from pytest_celery.api.container import * -from pytest_celery.api.setup import * -from pytest_celery.api.worker import * +from pytest_celery.api.backend import CeleryBackendCluster +from pytest_celery.api.backend import CeleryTestBackend +from pytest_celery.api.base import CeleryTestCluster +from pytest_celery.api.base import CeleryTestNode +from pytest_celery.api.broker import CeleryBrokerCluster +from pytest_celery.api.broker import CeleryTestBroker +from pytest_celery.api.container import CeleryTestContainer +from pytest_celery.api.setup import CeleryTestSetup +from pytest_celery.api.worker import CeleryTestWorker +from pytest_celery.api.worker import CeleryWorkerCluster from pytest_celery.defaults import * -from pytest_celery.fixtures.backend import * -from pytest_celery.fixtures.broker import * -from pytest_celery.fixtures.setup import * -from pytest_celery.fixtures.worker import * -from pytest_celery.vendors.memcached.api import * -from pytest_celery.vendors.memcached.container import * -from pytest_celery.vendors.memcached.fixtures import * -from pytest_celery.vendors.rabbitmq.api import * -from pytest_celery.vendors.rabbitmq.container import * -from pytest_celery.vendors.rabbitmq.fixtures import * -from pytest_celery.vendors.redis.backend.api import * -from pytest_celery.vendors.redis.backend.fixtures import * -from pytest_celery.vendors.redis.broker.api import * -from pytest_celery.vendors.redis.broker.fixtures import * -from pytest_celery.vendors.redis.container import * -from pytest_celery.vendors.worker.container import * -from pytest_celery.vendors.worker.content import app -from pytest_celery.vendors.worker.content import utils -from pytest_celery.vendors.worker.fixtures import * -from pytest_celery.vendors.worker.tasks import * -from pytest_celery.vendors.worker.volume import * +from pytest_celery.fixtures.backend import celery_backend +from pytest_celery.fixtures.backend import celery_backend_cluster +from pytest_celery.fixtures.backend import celery_backend_cluster_config +from pytest_celery.fixtures.broker import celery_broker +from pytest_celery.fixtures.broker import celery_broker_cluster +from pytest_celery.fixtures.broker import celery_broker_cluster_config +from pytest_celery.fixtures.setup import celery_setup +from pytest_celery.fixtures.setup import celery_setup_app +from pytest_celery.fixtures.setup import celery_setup_cls +from pytest_celery.fixtures.setup import celery_setup_config +from pytest_celery.fixtures.setup import celery_setup_name +from pytest_celery.fixtures.worker import celery_worker +from pytest_celery.fixtures.worker import celery_worker_cluster +from pytest_celery.fixtures.worker import celery_worker_cluster_config +from pytest_celery.vendors import _is_vendor_installed + +if _is_vendor_installed("memcached"): + from pytest_celery.vendors.memcached.api import MemcachedTestBackend + from pytest_celery.vendors.memcached.container import MemcachedContainer + from pytest_celery.vendors.memcached.defaults import * + from pytest_celery.vendors.memcached.fixtures import celery_memcached_backend + from pytest_celery.vendors.memcached.fixtures import default_memcached_backend + from pytest_celery.vendors.memcached.fixtures import default_memcached_backend_cls + from pytest_celery.vendors.memcached.fixtures import default_memcached_backend_env + from pytest_celery.vendors.memcached.fixtures import default_memcached_backend_image + from pytest_celery.vendors.memcached.fixtures import default_memcached_backend_ports + +if _is_vendor_installed("rabbitmq"): + from pytest_celery.vendors.rabbitmq.api import RabbitMQTestBroker + from pytest_celery.vendors.rabbitmq.container import RabbitMQContainer + from pytest_celery.vendors.rabbitmq.defaults import * + from pytest_celery.vendors.rabbitmq.fixtures import celery_rabbitmq_broker + from pytest_celery.vendors.rabbitmq.fixtures import default_rabbitmq_broker + from pytest_celery.vendors.rabbitmq.fixtures import default_rabbitmq_broker_cls + from pytest_celery.vendors.rabbitmq.fixtures import default_rabbitmq_broker_env + from pytest_celery.vendors.rabbitmq.fixtures import default_rabbitmq_broker_image + from pytest_celery.vendors.rabbitmq.fixtures import default_rabbitmq_broker_ports + +if _is_vendor_installed("redis"): + from pytest_celery.vendors.redis.backend.api import RedisTestBackend + from pytest_celery.vendors.redis.backend.defaults import * + from pytest_celery.vendors.redis.backend.fixtures import celery_redis_backend + from pytest_celery.vendors.redis.backend.fixtures import default_redis_backend + from pytest_celery.vendors.redis.backend.fixtures import default_redis_backend_cls + from pytest_celery.vendors.redis.backend.fixtures import default_redis_backend_command + from pytest_celery.vendors.redis.backend.fixtures import default_redis_backend_env + from pytest_celery.vendors.redis.backend.fixtures import default_redis_backend_image + from pytest_celery.vendors.redis.backend.fixtures import default_redis_backend_ports + from pytest_celery.vendors.redis.broker.api import RedisTestBroker + from pytest_celery.vendors.redis.broker.defaults import * + from pytest_celery.vendors.redis.broker.fixtures import celery_redis_broker + from pytest_celery.vendors.redis.broker.fixtures import default_redis_broker + from pytest_celery.vendors.redis.broker.fixtures import default_redis_broker_cls + from pytest_celery.vendors.redis.broker.fixtures import default_redis_broker_command + from pytest_celery.vendors.redis.broker.fixtures import default_redis_broker_env + from pytest_celery.vendors.redis.broker.fixtures import default_redis_broker_image + from pytest_celery.vendors.redis.broker.fixtures import default_redis_broker_ports + from pytest_celery.vendors.redis.container import RedisContainer + from pytest_celery.vendors.redis.defaults import * + +if _is_vendor_installed("worker"): + from pytest_celery.vendors.worker.container import CeleryWorkerContainer + from pytest_celery.vendors.worker.content import app + from pytest_celery.vendors.worker.content import utils + from pytest_celery.vendors.worker.fixtures import celery_base_worker_image + from pytest_celery.vendors.worker.fixtures import celery_setup_worker + from pytest_celery.vendors.worker.fixtures import default_worker_app + from pytest_celery.vendors.worker.fixtures import default_worker_app_module + from pytest_celery.vendors.worker.fixtures import default_worker_celery_log_level + from pytest_celery.vendors.worker.fixtures import default_worker_celery_version + from pytest_celery.vendors.worker.fixtures import default_worker_celery_worker_name + from pytest_celery.vendors.worker.fixtures import default_worker_celery_worker_queue + from pytest_celery.vendors.worker.fixtures import default_worker_cls + from pytest_celery.vendors.worker.fixtures import default_worker_command + from pytest_celery.vendors.worker.fixtures import default_worker_container + from pytest_celery.vendors.worker.fixtures import default_worker_container_cls + from pytest_celery.vendors.worker.fixtures import default_worker_container_session_cls + from pytest_celery.vendors.worker.fixtures import default_worker_env + from pytest_celery.vendors.worker.fixtures import default_worker_initial_content + from pytest_celery.vendors.worker.fixtures import default_worker_signals + from pytest_celery.vendors.worker.fixtures import default_worker_tasks + from pytest_celery.vendors.worker.fixtures import default_worker_utils_module + from pytest_celery.vendors.worker.fixtures import default_worker_volume + from pytest_celery.vendors.worker.tasks import ping + from pytest_celery.vendors.worker.volume import WorkerInitialContent + version_info_t = namedtuple( "version_info_t", diff --git a/src/pytest_celery/defaults.py b/src/pytest_celery/defaults.py index b67947a5..b29cb19a 100644 --- a/src/pytest_celery/defaults.py +++ b/src/pytest_celery/defaults.py @@ -4,6 +4,7 @@ from pytest_docker_tools import network +from pytest_celery.vendors import _is_vendor_installed from pytest_celery.vendors.memcached.defaults import CELERY_MEMCACHED_BACKEND from pytest_celery.vendors.memcached.defaults import * from pytest_celery.vendors.rabbitmq.defaults import CELERY_RABBITMQ_BROKER @@ -28,15 +29,24 @@ # will automatically add it to the parametrization of every (relevant) test IMPLICITLY! # Tests that do not rely on default parametrization will not be affected. + +ALL_CELERY_BACKENDS = [] +ALL_CELERY_BROKERS = [] + +if _is_vendor_installed("redis"): + ALL_CELERY_BACKENDS.append(CELERY_REDIS_BACKEND) + ALL_CELERY_BROKERS.append(CELERY_REDIS_BROKER) + +if _is_vendor_installed("rabbitmq"): + # Uses Kombu + ALL_CELERY_BROKERS.append(CELERY_RABBITMQ_BROKER) + +# Memcached is disabled by default regardless of its availability. +if _is_vendor_installed("memcached") and False: + ALL_CELERY_BACKENDS.append(CELERY_MEMCACHED_BACKEND) + +# Worker setup is assumed to be always available. ALL_CELERY_WORKERS = (CELERY_SETUP_WORKER,) -ALL_CELERY_BACKENDS = ( - CELERY_REDIS_BACKEND, - # CELERY_MEMCACHED_BACKEND, # Beta support at the moment, to be used manually -) -ALL_CELERY_BROKERS = ( - CELERY_REDIS_BROKER, - CELERY_RABBITMQ_BROKER, -) #################################################################################### # Fixtures diff --git a/src/pytest_celery/vendors/__init__.py b/src/pytest_celery/vendors/__init__.py index b08b47eb..fae2f50d 100644 --- a/src/pytest_celery/vendors/__init__.py +++ b/src/pytest_celery/vendors/__init__.py @@ -1 +1,19 @@ """See :ref:`vendors`.""" + + +def _is_vendor_installed(vendor_name: str) -> bool: + """Check if a vendor is installed. + + Args: + vendor_name (str): Vendor package name. + + Returns: + bool: True if the vendor is installed, False otherwise. + """ + + try: + container_module = f"pytest_celery.vendors.{vendor_name}.container" + __import__(container_module) + return True + except ImportError: + return False diff --git a/src/pytest_celery/vendors/worker/Dockerfile b/src/pytest_celery/vendors/worker/Dockerfile index 4e3f6454..7ec7b844 100644 --- a/src/pytest_celery/vendors/worker/Dockerfile +++ b/src/pytest_celery/vendors/worker/Dockerfile @@ -4,7 +4,7 @@ FROM python:3.10-slim-buster RUN adduser --disabled-password --gecos "" test_user # Install system dependencies -RUN apt-get update && apt-get install -y build-essential +RUN apt-get update && apt-get install -y build-essential git # Set arguments ARG CELERY_VERSION="" @@ -23,7 +23,7 @@ ENV PYTHONDONTWRITEBYTECODE=1 RUN pip install --no-cache-dir --upgrade \ pip \ celery[redis,pymemcache]${WORKER_VERSION:+==$WORKER_VERSION} \ - psutil + pytest-celery@git+https://github.com/Katz-Consulting-Group/pytest-celery.git@bugfix # The workdir must be /app WORKDIR /app diff --git a/tox.ini b/tox.ini index c6a6b429..c9159d39 100644 --- a/tox.ini +++ b/tox.ini @@ -24,7 +24,7 @@ setenv = PYTHONUNBUFFERED = 1 PYTHONDONTWRITEBYTECODE = 1 commands_pre = - poetry install --with test + poetry install -E "all" --with test commands = unit: poetry run pytest tests/unit/ --maxfail=3 {posargs} integration: poetry run pytest tests/integration/ --exitfirst --dist=loadscope {posargs} @@ -51,7 +51,7 @@ setenv = PYTHONUNBUFFERED = 1 PYTHONDONTWRITEBYTECODE = 1 commands_pre = - poetry install --with test + poetry install -E "all" --with test commands = poetry run pytest tests --exitfirst \ -n auto --dist=loadscope \ @@ -64,7 +64,7 @@ setenv = PYTHONUNBUFFERED = 1 PYTHONDONTWRITEBYTECODE = 1 commands_pre = - poetry install --with test + poetry install -E "all" --with test commands = tox -e py312-unit,py312-integration,py312-smoke -p auto -o -- --exitfirst \ -n auto --dist=loadscope \ @@ -74,7 +74,7 @@ commands = [testenv:mypy] description = Run mypy using {basepython} commands_pre = - poetry install --only dev + poetry install -E "all" --only dev poetry run mypy --install-types --non-interactive commands = poetry run mypy --config-file pyproject.toml @@ -83,7 +83,7 @@ commands = description = Run code+doc lint using {basepython} allowlist_externals = poetry, make commands_pre = - poetry install --with dev,docs + poetry install -E "all" --with dev,docs commands = poetry run pre-commit {posargs:run --all-files --show-diff-on-failure} make -C ./docs apicheck @@ -107,7 +107,7 @@ commands = description = Build docs using {basepython} allowlist_externals = poetry, make commands_pre = - poetry install --with docs + poetry install -E "all" --with docs commands = make -C ./docs html @@ -115,7 +115,7 @@ commands = description = Build docs using {basepython} and serve in http://0.0.0.0:7010 allowlist_externals = poetry, make commands_pre = - poetry install --with docs + poetry install -E "all" --with docs commands = make -C ./docs livehtml @@ -123,6 +123,6 @@ commands = description = Regenerate API Reference doc section using {basepython} allowlist_externals = poetry, make commands_pre = - poetry install --with docs + poetry install -E "all" --with docs commands = make -C ./docs apidoc