diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index 9eee2c2..5fc9637 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -4,6 +4,8 @@ on: branches: main pull_request: branches: main +env: + FORCE_COLOR: 1 jobs: tests: name: Run Tests diff --git a/packages/amgi-aiobotocore/pyproject.toml b/packages/amgi-aiobotocore/pyproject.toml index 3b31aab..3e9eb3c 100644 --- a/packages/amgi-aiobotocore/pyproject.toml +++ b/packages/amgi-aiobotocore/pyproject.toml @@ -35,6 +35,10 @@ entry-points.amgi_server.amgi-aiobotocore-sqs = "amgi_aiobotocore.sqs:_run_cli" [dependency-groups] dev = [ + "pytest>=8.4.1", + "pytest-asyncio>=1.3.0", + "pytest-cov>=7.0.0", + "pytest-timeout>=2.4.0", "test-utils", "testcontainers[localstack]>=4.13.0", ] diff --git a/packages/amgi-aiokafka/pyproject.toml b/packages/amgi-aiokafka/pyproject.toml index be6ac30..dfefcef 100644 --- a/packages/amgi-aiokafka/pyproject.toml +++ b/packages/amgi-aiokafka/pyproject.toml @@ -41,6 +41,10 @@ entry-points.amgi_server.amgi-aiokafka = "amgi_aiokafka:_run_cli" [dependency-groups] dev = [ + "pytest>=8.4.1", + "pytest-asyncio>=1.3.0", + "pytest-cov>=7.0.0", + "pytest-timeout>=2.4.0", "test-utils", "testcontainers[kafka]>=4.13.0", ] diff --git a/packages/amgi-common/pyproject.toml b/packages/amgi-common/pyproject.toml index 15253a0..b1cb26c 100644 --- a/packages/amgi-common/pyproject.toml +++ b/packages/amgi-common/pyproject.toml @@ -26,9 +26,27 @@ classifiers = [ "Programming Language :: Python :: 3.13", "Programming Language :: Python :: 3.14", ] -dependencies = [ ] +dependencies = [ + "amgi-types==0.25.1", + "typing-extensions>=4.15.0; python_full_version<'3.13'", +] urls.Changelog = "https://github.com/asyncfast/amgi/blob/main/CHANGELOG.md" urls.Homepage = "https://github.com/asyncfast/amgi/tree/main/packages/amgi-common" urls.Issues = "https://github.com/asyncfast/amgi/issues/" urls.Repository = "https://github.com/asyncfast/amgi/" + +[dependency-groups] +dev = [ + "pytest>=8.4.1", + "pytest-asyncio>=1.3.0", + "pytest-cov>=7.0.0", + "pytest-timeout>=2.4.0", + "test-utils", +] + +[tool.uv.sources.test-utils] +workspace = true + +[tool.uv.sources.amgi-types] +workspace = true diff --git a/packages/amgi-common/src/amgi_common/__init__.py b/packages/amgi-common/src/amgi_common/__init__.py index 73224a4..b68eb86 100644 --- a/packages/amgi-common/src/amgi_common/__init__.py +++ b/packages/amgi-common/src/amgi_common/__init__.py @@ -2,6 +2,7 @@ import asyncio import logging +import sys from asyncio import AbstractEventLoop from asyncio import Event from asyncio import Future @@ -30,7 +31,11 @@ from amgi_types import LifespanScope from amgi_types import LifespanShutdownEvent from amgi_types import LifespanStartupEvent -from typing_extensions import ParamSpec + +if sys.version_info >= (3, 13): + from typing import ParamSpec +else: + from typing_extensions import ParamSpec P = ParamSpec("P") T = TypeVar("T") diff --git a/packages/amgi-paho-mqtt/pyproject.toml b/packages/amgi-paho-mqtt/pyproject.toml index b4a7727..fa15f1a 100644 --- a/packages/amgi-paho-mqtt/pyproject.toml +++ b/packages/amgi-paho-mqtt/pyproject.toml @@ -35,6 +35,10 @@ entry-points.amgi_server.amgi-paho-mqtt = "amgi_paho_mqtt:run" [dependency-groups] dev = [ + "pytest>=8.4.1", + "pytest-asyncio>=1.3.0", + "pytest-cov>=7.0.0", + "pytest-timeout>=2.4.0", "test-utils", "testcontainers[mqtt]>=4.13.0", ] diff --git a/packages/amgi-redis/pyproject.toml b/packages/amgi-redis/pyproject.toml index 44a1525..bfd6fbb 100644 --- a/packages/amgi-redis/pyproject.toml +++ b/packages/amgi-redis/pyproject.toml @@ -35,6 +35,10 @@ entry-points.amgi_server.amgi-redis = "amgi_redis:_run_cli" [dependency-groups] dev = [ + "pytest>=8.4.1", + "pytest-asyncio>=1.3.0", + "pytest-cov>=7.0.0", + "pytest-timeout>=2.4.0", "test-utils", "testcontainers[redis]>=4.13.0", ] diff --git a/packages/amgi-sqs-event-source-mapping/pyproject.toml b/packages/amgi-sqs-event-source-mapping/pyproject.toml index 570204f..6de3466 100644 --- a/packages/amgi-sqs-event-source-mapping/pyproject.toml +++ b/packages/amgi-sqs-event-source-mapping/pyproject.toml @@ -28,11 +28,19 @@ classifiers = [ dependencies = [ "amgi-common==0.25.1", "amgi-types==0.25.1", + "typing-extensions>=4.15.0; python_full_version<'3.11'", +] + +optional-dependencies.boto3 = [ + "boto3>=1.40.70", ] [dependency-groups] dev = [ - "boto3>=1.40.70", + "pytest>=8.4.1", + "pytest-asyncio>=1.3.0", + "pytest-cov>=7.0.0", + "pytest-timeout>=2.4.0", "test-utils", "testcontainers[localstack]>=4.13.0", ] diff --git a/packages/amgi-types/pyproject.toml b/packages/amgi-types/pyproject.toml index 0410611..dfb720b 100644 --- a/packages/amgi-types/pyproject.toml +++ b/packages/amgi-types/pyproject.toml @@ -27,7 +27,9 @@ classifiers = [ "Programming Language :: Python :: 3.13", "Programming Language :: Python :: 3.14", ] -dependencies = [ ] +dependencies = [ + "typing-extensions>=4.15.0; python_full_version<'3.11'", +] urls.Changelog = "https://github.com/asyncfast/amgi/blob/main/CHANGELOG.md" urls.Homepage = "https://github.com/asyncfast/amgi/tree/main/packages/amgi-types" diff --git a/packages/asyncfast/pyproject.toml b/packages/asyncfast/pyproject.toml index 1518082..96fd57d 100644 --- a/packages/asyncfast/pyproject.toml +++ b/packages/asyncfast/pyproject.toml @@ -51,6 +51,8 @@ scripts.asyncfast = "asyncfast.cli:main" dev = [ "pytest>=8.4.1", "pytest-asyncio>=1.1", + "pytest-cov>=7.0.0", + "pytest-timeout>=2.4.0", ] [tool.uv.sources.amgi-types] diff --git a/pyproject.toml b/pyproject.toml index 546f2b7..fc99739 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -25,8 +25,6 @@ dev = [ "mypy>=1.17.1", "myst-parser>=3.0.1", "pre-commit-uv>=4.1.4", - "pytest-cov>=7.0.0", - "pytest-timeout>=2.4.0", "sphinx>=7.4.7", "sphinx-copybutton>=0.5.2", "sphinx-inline-tabs>=2023.4.21", diff --git a/tox.ini b/tox.ini index 6aa884e..da71892 100644 --- a/tox.ini +++ b/tox.ini @@ -2,12 +2,10 @@ requires = tox>=4.2 env_list = - py313 - py312 - py311 - py310 clean pre-commit + py3{10-13}-{amgi-aiobotocore, amgi-aiokafka, amgi-common, amgi-paho-mqtt, amgi-redis, amgi-sqs-event-source-mapping, asyncfast} + py3{10-13}-{amgi-aiobotocore, amgi-aiokafka, amgi-common, amgi-paho-mqtt, amgi-redis, amgi-sqs-event-source-mapping, amgi-types, asyncfast, asyncfast-cli}-import [testenv] runner = uv-venv-lock-runner @@ -26,15 +24,111 @@ depends = uv_sync_flags = --all-packages [testenv:clean] -runner = uv-venv-lock-runner description = clean coverage report commands = coverage erase uv_sync_flags = --all-packages [testenv:pre-commit] -runner = uv-venv-lock-runner description = run pre-commit commands = pre-commit run --all-files --show-diff-on-failure -uv_sync_flags = --all-packages + +[testenv:py3{10-13}-amgi-aiobotocore] +commands = + {[testenv]commands} packages/amgi-aiobotocore +uv_sync_flags = --package=amgi-aiobotocore + +[testenv:py3{10-13}-amgi-aiokafka] +commands = + {[testenv]commands} packages/amgi-aiokafka +uv_sync_flags = --package=amgi-aiokafka + +[testenv:py3{10-13}-amgi-common] +commands = + {[testenv]commands} packages/amgi-common +uv_sync_flags = --package=amgi-common + +[testenv:py3{10-13}-amgi-paho-mqtt] +commands = + {[testenv]commands} packages/amgi-paho-mqtt +uv_sync_flags = --package=amgi-paho-mqtt + +[testenv:py3{10-13}-amgi-redis] +commands = + {[testenv]commands} packages/amgi-redis +uv_sync_flags = --package=amgi-redis + +[testenv:py3{10-13}-amgi-sqs-event-source-mapping] +commands = + {[testenv]commands} packages/amgi-sqs-event-source-mapping +uv_sync_flags = --package=amgi-sqs-event-source-mapping + +[testenv:py3{10-13}-asyncfast] +commands = + {[testenv]commands} packages/asyncfast +uv_sync_flags = --package=asyncfast + +[testenv:py3{10-13}-amgi-aiobotocore-import] +commands = + python -c "import amgi_aiobotocore" +uv_sync_flags = + --package=amgi-aiobotocore + --no-dev + +[testenv:py3{10-13}-amgi-aiokafka-import] +commands = + python -c "import amgi_aiokafka" +uv_sync_flags = + --package=amgi-aiokafka + --no-dev + +[testenv:py3{10-13}-amgi-common-import] +commands = + python -c "import amgi_common" +uv_sync_flags = + --package=amgi-common + --no-dev + +[testenv:py3{10-13}-amgi-paho-mqtt-import] +commands = + python -c "import amgi_paho_mqtt" +uv_sync_flags = + --package=amgi-paho-mqtt + --no-dev + +[testenv:py3{10-13}-amgi-redis-import] +commands = + python -c "import amgi_redis" +uv_sync_flags = + --package=amgi-redis + --no-dev + +[testenv:py3{10-13}-amgi-sqs-event-source-mapping-import] +commands = + python -c "import amgi_sqs_event_source_mapping" +uv_sync_flags = + --package=amgi-sqs-event-source-mapping + --no-dev + --extra=boto3 + +[testenv:py3{10-13}-amgi-types-import] +commands = + python -c "import amgi_types" +uv_sync_flags = + --package=amgi-types + --no-dev + +[testenv:py3{10-13}-asyncfast-import] +commands = + python -c "import asyncfast" +uv_sync_flags = + --package=asyncfast + --no-dev + +[testenv:py3{10-13}-asyncfast-cli-import] +commands = + python -c "import asyncfast_cli" +uv_sync_flags = + --package=asyncfast-cli + --no-dev diff --git a/uv.lock b/uv.lock index fc69509..48b646f 100644 --- a/uv.lock +++ b/uv.lock @@ -259,8 +259,6 @@ dev = [ { name = "mypy" }, { name = "myst-parser" }, { name = "pre-commit-uv" }, - { name = "pytest-cov" }, - { name = "pytest-timeout" }, { name = "sphinx" }, { name = "sphinx-copybutton" }, { name = "sphinx-inline-tabs" }, @@ -280,8 +278,6 @@ dev = [ { name = "mypy", specifier = ">=1.17.1" }, { name = "myst-parser", specifier = ">=3.0.1" }, { name = "pre-commit-uv", specifier = ">=4.1.4" }, - { name = "pytest-cov", specifier = ">=7.0.0" }, - { name = "pytest-timeout", specifier = ">=2.4.0" }, { name = "sphinx", specifier = ">=7.4.7" }, { name = "sphinx-copybutton", specifier = ">=0.5.2" }, { name = "sphinx-inline-tabs", specifier = ">=2023.4.21" }, @@ -302,6 +298,10 @@ dependencies = [ [package.dev-dependencies] dev = [ + { name = "pytest" }, + { name = "pytest-asyncio" }, + { name = "pytest-cov" }, + { name = "pytest-timeout" }, { name = "test-utils" }, { name = "testcontainers", extra = ["localstack"] }, ] @@ -315,6 +315,10 @@ requires-dist = [ [package.metadata.requires-dev] dev = [ + { name = "pytest", specifier = ">=8.4.1" }, + { name = "pytest-asyncio", specifier = ">=1.3.0" }, + { name = "pytest-cov", specifier = ">=7.0.0" }, + { name = "pytest-timeout", specifier = ">=2.4.0" }, { name = "test-utils", editable = "packages/test-utils" }, { name = "testcontainers", extras = ["localstack"], specifier = ">=4.13.0" }, ] @@ -331,6 +335,10 @@ dependencies = [ [package.dev-dependencies] dev = [ + { name = "pytest" }, + { name = "pytest-asyncio" }, + { name = "pytest-cov" }, + { name = "pytest-timeout" }, { name = "test-utils" }, { name = "testcontainers" }, ] @@ -344,6 +352,10 @@ requires-dist = [ [package.metadata.requires-dev] dev = [ + { name = "pytest", specifier = ">=8.4.1" }, + { name = "pytest-asyncio", specifier = ">=1.3.0" }, + { name = "pytest-cov", specifier = ">=7.0.0" }, + { name = "pytest-timeout", specifier = ">=2.4.0" }, { name = "test-utils", editable = "packages/test-utils" }, { name = "testcontainers", extras = ["kafka"], specifier = ">=4.13.0" }, ] @@ -352,6 +364,34 @@ dev = [ name = "amgi-common" version = "0.25.1" source = { editable = "packages/amgi-common" } +dependencies = [ + { name = "amgi-types" }, + { name = "typing-extensions", marker = "python_full_version < '3.13'" }, +] + +[package.dev-dependencies] +dev = [ + { name = "pytest" }, + { name = "pytest-asyncio" }, + { name = "pytest-cov" }, + { name = "pytest-timeout" }, + { name = "test-utils" }, +] + +[package.metadata] +requires-dist = [ + { name = "amgi-types", editable = "packages/amgi-types" }, + { name = "typing-extensions", marker = "python_full_version < '3.13'", specifier = ">=4.15.0" }, +] + +[package.metadata.requires-dev] +dev = [ + { name = "pytest", specifier = ">=8.4.1" }, + { name = "pytest-asyncio", specifier = ">=1.3.0" }, + { name = "pytest-cov", specifier = ">=7.0.0" }, + { name = "pytest-timeout", specifier = ">=2.4.0" }, + { name = "test-utils", editable = "packages/test-utils" }, +] [[package]] name = "amgi-paho-mqtt" @@ -365,6 +405,10 @@ dependencies = [ [package.dev-dependencies] dev = [ + { name = "pytest" }, + { name = "pytest-asyncio" }, + { name = "pytest-cov" }, + { name = "pytest-timeout" }, { name = "test-utils" }, { name = "testcontainers" }, ] @@ -378,6 +422,10 @@ requires-dist = [ [package.metadata.requires-dev] dev = [ + { name = "pytest", specifier = ">=8.4.1" }, + { name = "pytest-asyncio", specifier = ">=1.3.0" }, + { name = "pytest-cov", specifier = ">=7.0.0" }, + { name = "pytest-timeout", specifier = ">=2.4.0" }, { name = "test-utils", editable = "packages/test-utils" }, { name = "testcontainers", extras = ["mqtt"], specifier = ">=4.13.0" }, ] @@ -394,6 +442,10 @@ dependencies = [ [package.dev-dependencies] dev = [ + { name = "pytest" }, + { name = "pytest-asyncio" }, + { name = "pytest-cov" }, + { name = "pytest-timeout" }, { name = "test-utils" }, { name = "testcontainers", extra = ["redis"] }, ] @@ -407,6 +459,10 @@ requires-dist = [ [package.metadata.requires-dev] dev = [ + { name = "pytest", specifier = ">=8.4.1" }, + { name = "pytest-asyncio", specifier = ">=1.3.0" }, + { name = "pytest-cov", specifier = ">=7.0.0" }, + { name = "pytest-timeout", specifier = ">=2.4.0" }, { name = "test-utils", editable = "packages/test-utils" }, { name = "testcontainers", extras = ["redis"], specifier = ">=4.13.0" }, ] @@ -418,11 +474,20 @@ source = { editable = "packages/amgi-sqs-event-source-mapping" } dependencies = [ { name = "amgi-common" }, { name = "amgi-types" }, + { name = "typing-extensions", marker = "python_full_version < '3.11'" }, +] + +[package.optional-dependencies] +boto3 = [ + { name = "boto3" }, ] [package.dev-dependencies] dev = [ - { name = "boto3" }, + { name = "pytest" }, + { name = "pytest-asyncio" }, + { name = "pytest-cov" }, + { name = "pytest-timeout" }, { name = "test-utils" }, { name = "testcontainers", extra = ["localstack"] }, ] @@ -431,11 +496,17 @@ dev = [ requires-dist = [ { name = "amgi-common", editable = "packages/amgi-common" }, { name = "amgi-types", editable = "packages/amgi-types" }, + { name = "boto3", marker = "extra == 'boto3'", specifier = ">=1.40.70" }, + { name = "typing-extensions", marker = "python_full_version < '3.11'", specifier = ">=4.15.0" }, ] +provides-extras = ["boto3"] [package.metadata.requires-dev] dev = [ - { name = "boto3", specifier = ">=1.40.70" }, + { name = "pytest", specifier = ">=8.4.1" }, + { name = "pytest-asyncio", specifier = ">=1.3.0" }, + { name = "pytest-cov", specifier = ">=7.0.0" }, + { name = "pytest-timeout", specifier = ">=2.4.0" }, { name = "test-utils", editable = "packages/test-utils" }, { name = "testcontainers", extras = ["localstack"], specifier = ">=4.13.0" }, ] @@ -444,6 +515,12 @@ dev = [ name = "amgi-types" version = "0.25.1" source = { editable = "packages/amgi-types" } +dependencies = [ + { name = "typing-extensions", marker = "python_full_version < '3.11'" }, +] + +[package.metadata] +requires-dist = [{ name = "typing-extensions", marker = "python_full_version < '3.11'", specifier = ">=4.15.0" }] [[package]] name = "annotated-types" @@ -490,6 +567,8 @@ standard = [ dev = [ { name = "pytest" }, { name = "pytest-asyncio" }, + { name = "pytest-cov" }, + { name = "pytest-timeout" }, ] [package.metadata] @@ -504,6 +583,8 @@ provides-extras = ["standard"] dev = [ { name = "pytest", specifier = ">=8.4.1" }, { name = "pytest-asyncio", specifier = ">=1.1" }, + { name = "pytest-cov", specifier = ">=7.0.0" }, + { name = "pytest-timeout", specifier = ">=2.4.0" }, ] [[package]] @@ -1788,15 +1869,16 @@ wheels = [ [[package]] name = "pytest-asyncio" -version = "1.1.0" +version = "1.3.0" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "backports-asyncio-runner", marker = "python_full_version < '3.11'" }, { name = "pytest" }, + { name = "typing-extensions", marker = "python_full_version < '3.13'" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/4e/51/f8794af39eeb870e87a8c8068642fc07bce0c854d6865d7dd0f2a9d338c2/pytest_asyncio-1.1.0.tar.gz", hash = "sha256:796aa822981e01b68c12e4827b8697108f7205020f24b5793b3c41555dab68ea", size = 46652, upload-time = "2025-07-16T04:29:26.393Z" } +sdist = { url = "https://files.pythonhosted.org/packages/90/2c/8af215c0f776415f3590cac4f9086ccefd6fd463befeae41cd4d3f193e5a/pytest_asyncio-1.3.0.tar.gz", hash = "sha256:d7f52f36d231b80ee124cd216ffb19369aa168fc10095013c6b014a34d3ee9e5", size = 50087, upload-time = "2025-11-10T16:07:47.256Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/c7/9d/bf86eddabf8c6c9cb1ea9a869d6873b46f105a5d292d3a6f7071f5b07935/pytest_asyncio-1.1.0-py3-none-any.whl", hash = "sha256:5fe2d69607b0bd75c656d1211f969cadba035030156745ee09e7d71740e58ecf", size = 15157, upload-time = "2025-07-16T04:29:24.929Z" }, + { url = "https://files.pythonhosted.org/packages/e5/35/f8b19922b6a25bc0880171a2f1a003eaeb93657475193ab516fd87cac9da/pytest_asyncio-1.3.0-py3-none-any.whl", hash = "sha256:611e26147c7f77640e6d0a92a38ed17c3e9848063698d5c93d5aa7aa11cebff5", size = 15075, upload-time = "2025-11-10T16:07:45.537Z" }, ] [[package]]