Skip to content
This repository was archived by the owner on Oct 1, 2024. It is now read-only.
This repository was archived by the owner on Oct 1, 2024. It is now read-only.

Python 3.10: RuntimeError: Event loop is closed/Task attached to a different loop #382

Description

@RamonGiovane

Description

I'm unable to update Ward to version 0.67.0b0 or later.
When I run Ward async tests for FastAPI + SQLAlchemy async, this shows on console in the middle of the test execution:

Exception closing connection <AdaptedConnection <asyncpg.connection.Connection object at 0x7fa78460a420>>
Traceback (most recent call last):
  File "/home/ramon/project/.venv/lib/python3.10/site-packages/sqlalchemy/pool/base.py", line 928, in _checkout
    result = pool._dialect.do_ping(fairy.dbapi_connection)
  File "/home/ramon/project/.venv/lib/python3.10/site-packages/sqlalchemy/engine/default.py", line 703, in do_ping
    cursor.execute(self._dialect_specific_select_one)
  File "/home/ramon/project/.venv/lib/python3.10/site-packages/sqlalchemy/dialects/postgresql/asyncpg.py", line 479, in execute
    self._adapt_connection.await_(
  File "/home/ramon/project/.venv/lib/python3.10/site-packages/sqlalchemy/util/_concurrency_py3k.py", line 68, in await_only
    return current.driver.switch(awaitable)
  File "/home/ramon/project/.venv/lib/python3.10/site-packages/sqlalchemy/util/_concurrency_py3k.py", line 121, in greenlet_spawn
    value = await result
  File "/home/ramon/project/.venv/lib/python3.10/site-packages/sqlalchemy/dialects/postgresql/asyncpg.py", line 408, in _prepare_and_execute
    await adapt_connection._start_transaction()
  File "/home/ramon/project/.venv/lib/python3.10/site-packages/sqlalchemy/dialects/postgresql/asyncpg.py", line 716, in _start_transaction
    self._handle_exception(error)
  File "/home/ramon/project/.venv/lib/python3.10/site-packages/sqlalchemy/dialects/postgresql/asyncpg.py", line 684, in _handle_exception
    raise error
  File "/home/ramon/project/.venv/lib/python3.10/site-packages/sqlalchemy/dialects/postgresql/asyncpg.py", line 714, in _start_transaction
    await self._transaction.start()
  File "/home/ramon/project/.venv/lib/python3.10/site-packages/asyncpg/transaction.py", line 138, in start
    await self._connection.execute(query)
  File "/home/ramon/project/.venv/lib/python3.10/site-packages/asyncpg/connection.py", line 318, in execute
    return await self._protocol.query(query, timeout)
  File "asyncpg/protocol/protocol.pyx", line 338, in query
RuntimeError: Task <Task pending name='Task-9' coro=<_() running at /home/ramon/project/tests/api/test_application_route.py:98> cb=[_run_until_complete_cb() at 
/home/ramon/.asdf/installs/python/3.10.11/lib/python3.10/asyncio/base_events.py:184]> got Future <Future pending cb=[Protocol._on_waiter_completed()]> attached to a different loop

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "/home/ramon/project/.venv/lib/python3.10/site-packages/sqlalchemy/pool/base.py", line 260, in _close_connection
    self._dialect.do_terminate(connection)
  File "/home/ramon/project/.venv/lib/python3.10/site-packages/sqlalchemy/dialects/postgresql/asyncpg.py", line 995, in do_terminate
    dbapi_connection.terminate()
  File "/home/ramon/project/.venv/lib/python3.10/site-packages/sqlalchemy/dialects/postgresql/asyncpg.py", line 752, in terminate
    self._connection.terminate()
  File "/home/ramon/project/.venv/lib/python3.10/site-packages/asyncpg/connection.py", line 1345, in terminate
    self._abort()
  File "/home/ramon/project/.venv/lib/python3.10/site-packages/asyncpg/connection.py", line 1372, in _abort
    self._protocol.abort()
  File "asyncpg/protocol/protocol.pyx", line 569, in asyncpg.protocol.protocol.BaseProtocol.abort
  File "asyncpg/protocol/protocol.pyx", line 668, in asyncpg.protocol.protocol.BaseProtocol._handle_waiter_on_connection_lost
  File "/home/ramon/.asdf/installs/python/3.10.11/lib/python3.10/asyncio/base_events.py", line 753, in call_soon
    self._check_closed()
  File "/home/ramon/.asdf/installs/python/3.10.11/lib/python3.10/asyncio/base_events.py", line 515, in _check_closed
    raise RuntimeError('Event loop is closed')
RuntimeError: Event loop is closed

Then on Ward's test results, we got this message:

RuntimeError: Task <Task pending name='starlette.middleware.base.BaseHTTPMiddleware.__call__.<locals>.call_next.<locals>.coro'
coro=<BaseHTTPMiddleware.__call__.<locals>.call_next.<locals>.coro()
running at /home/ramon/project/.venv/lib/python3.10/site-packages/starlette/middleware/base.py:34> cb=[TaskGroup._spawn.<locals>.task_done() at 
/home/ramon/project/.venv/lib/python3.10/site-packages/anyio/_backends/_asyncio.py:661]>
got Future <Future pending cb=[Protocol._on_waiter_completed()]> attached to a 
different loop

I guess this was introduced in PR #334

My specs

Python 3.10.11
Ward 0.67.0b0

Expected behavior

The test to work like it did on previous Ward version 0.66.1b0

Possible solution:

Instead of using asyncio.run() I think we should still try get the current event loop. This approach may work https://stackoverflow.com/a/73884759

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions