diff --git a/pyproject.toml b/pyproject.toml index 9b566f5ce..3771259fb 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -48,7 +48,7 @@ testing = [ "mypy==2.1.0", "pre-commit==4.6.0", "pytest", - "pytest-asyncio<1.0", + "pytest-asyncio>=1.4.0", "pytest-cov", "pytest-sugar", "pytest-timeout", diff --git a/tests/conftest.py b/tests/conftest.py index 9eb760efa..b3506a2a7 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -1,7 +1,7 @@ """Test configuration for the ZHA component.""" import asyncio -from collections.abc import Generator +from collections.abc import AsyncGenerator, Generator from contextlib import contextmanager import logging import os @@ -12,6 +12,7 @@ import looptime import pytest +import pytest_asyncio import zhaquirks import zhaquirks.legacy import zigpy @@ -162,18 +163,18 @@ def expected_lingering_timers() -> bool: return False -@pytest.fixture(autouse=True) -def verify_cleanup( - event_loop: asyncio.AbstractEventLoop, +@pytest_asyncio.fixture(autouse=True) +async def verify_cleanup( expected_lingering_tasks: bool, # pylint: disable=redefined-outer-name expected_lingering_timers: bool, # pylint: disable=redefined-outer-name -) -> Generator[None, None, None]: +) -> AsyncGenerator[None, None]: """Verify that the test has cleaned up resources correctly.""" + event_loop = asyncio.get_running_loop() threads_before = frozenset(threading.enumerate()) tasks_before = asyncio.all_tasks(event_loop) yield - event_loop.run_until_complete(event_loop.shutdown_default_executor()) + await event_loop.shutdown_default_executor() if len(INSTANCES) >= 2: count = len(INSTANCES) @@ -183,7 +184,12 @@ def verify_cleanup( # Warn and clean-up lingering tasks and timers # before moving on to the next test. - tasks = asyncio.all_tasks(event_loop) - tasks_before + current_task = asyncio.current_task() + tasks = { + task + for task in asyncio.all_tasks(event_loop) - tasks_before + if task is not current_task + } for task in tasks: if expected_lingering_tasks: _LOGGER.warning("Lingering task after test %r", task) @@ -191,7 +197,7 @@ def verify_cleanup( pytest.fail(f"Lingering task after test {task!r}") task.cancel() if tasks: - event_loop.run_until_complete(asyncio.wait(tasks)) + await asyncio.wait(tasks) for handle in event_loop._scheduled: if not handle.cancelled(): diff --git a/uv.lock b/uv.lock index 1786123bb..a8db40a57 100644 --- a/uv.lock +++ b/uv.lock @@ -2769,14 +2769,15 @@ wheels = [ [[package]] name = "pytest-asyncio" -version = "0.26.0" +version = "1.4.0" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "pytest" }, + { name = "typing-extensions", marker = "python_full_version < '3.13'" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/8e/c4/453c52c659521066969523e87d85d54139bbd17b78f09532fb8eb8cdb58e/pytest_asyncio-0.26.0.tar.gz", hash = "sha256:c4df2a697648241ff39e7f0e4a73050b03f123f760673956cf0d72a4990e312f", size = 54156, upload-time = "2025-03-25T06:22:28.883Z" } +sdist = { url = "https://files.pythonhosted.org/packages/43/7c/d36d04db312ecf4298932ef77e6e4a9e8ad017906e24e34f0b0c361a2473/pytest_asyncio-1.4.0.tar.gz", hash = "sha256:c6c0d2259945122819f171a32ecea2c349ead889ee28176caaf492143424be42", size = 58514, upload-time = "2026-05-26T09:56:04.083Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/20/7f/338843f449ace853647ace35870874f69a764d251872ed1b4de9f234822c/pytest_asyncio-0.26.0-py3-none-any.whl", hash = "sha256:7b51ed894f4fbea1340262bdae5135797ebbe21d8638978e35d31c6d19f72fb0", size = 19694, upload-time = "2025-03-25T06:22:27.807Z" }, + { url = "https://files.pythonhosted.org/packages/03/e2/08a497ef684b88559c9cc5f4ad53a37e7b99e727094a86d6ea32536d5d3c/pytest_asyncio-1.4.0-py3-none-any.whl", hash = "sha256:933ca923a23075a87fb7070c0ec272a6848489824d887c85c812670932835aa1", size = 16930, upload-time = "2026-05-26T09:56:02.576Z" }, ] [[package]] @@ -4074,7 +4075,7 @@ ci = [ { name = "mypy", specifier = "==2.1.0" }, { name = "pre-commit", specifier = "==4.6.0" }, { name = "pytest" }, - { name = "pytest-asyncio", specifier = "<1.0" }, + { name = "pytest-asyncio", specifier = ">=1.4.0" }, { name = "pytest-cov" }, { name = "pytest-github-actions-annotate-failures" }, { name = "pytest-sugar" }, @@ -4095,7 +4096,7 @@ testing = [ { name = "mypy", specifier = "==2.1.0" }, { name = "pre-commit", specifier = "==4.6.0" }, { name = "pytest" }, - { name = "pytest-asyncio", specifier = "<1.0" }, + { name = "pytest-asyncio", specifier = ">=1.4.0" }, { name = "pytest-cov" }, { name = "pytest-sugar" }, { name = "pytest-timeout" },