From 70ef87aea24927933a6062e30ed6d759dc06cfdb Mon Sep 17 00:00:00 2001 From: Joseph Doherty Date: Fri, 10 Jul 2026 04:11:45 -0400 Subject: [PATCH] ci(tst-03): ensure a current event loop for sync python tests (py3.12) The last portable failure: pytest-asyncio 1.x does not install a current event loop for synchronous tests and clears it after each async test, so a later sync test that builds a grpc.aio.Channel (create_channel) hit "RuntimeError: There is no current event loop" on Python 3.12 depending on test order (CI hit it; local order did not). Add an autouse conftest fixture that ensures a usable current loop per test. Local: 127 passed, 1 skipped. Claude-Session: https://claude.ai/code/session_01DMXXvNuPekkkrTEyPNxEkW --- clients/python/tests/conftest.py | 27 +++++++++++++++++++++++++++ 1 file changed, 27 insertions(+) create mode 100644 clients/python/tests/conftest.py diff --git a/clients/python/tests/conftest.py b/clients/python/tests/conftest.py new file mode 100644 index 0000000..6bf79cd --- /dev/null +++ b/clients/python/tests/conftest.py @@ -0,0 +1,27 @@ +"""Shared pytest fixtures for the client test suite. + +pytest-asyncio 1.x no longer installs a current event loop for *synchronous* +tests, and it clears the loop after each ``async`` test. Some synchronous tests +build a ``grpc.aio.Channel`` (via ``create_channel``), which calls +``asyncio.get_event_loop()`` and therefore raises +``RuntimeError: There is no current event loop`` on Python 3.12 when a prior +async test has left the policy with no current loop. Ensure every test starts +with a usable current loop so channel construction in a sync test is +order-independent. +""" + +from __future__ import annotations + +import asyncio +from collections.abc import Iterator + +import pytest + + +@pytest.fixture(autouse=True) +def _ensure_current_event_loop() -> Iterator[None]: + try: + asyncio.get_event_loop() + except RuntimeError: + asyncio.set_event_loop(asyncio.new_event_loop()) + yield