You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
host_conftest pooled async engine causes 'Future attached to a different loop' across tests #76
host_conftest.py's shared app fixture builds a single async engine that's reused across tests. asyncpg connections are bound to the event loop in which they're first acquired. With pytest-asyncio's default function-scoped event loops, a connection acquired in test N becomes stale in test N+1's loop, producing:
RuntimeError: Future <Future pending> attached to a different loop
Symptoms: tests that hit the DB pass individually but fail in a batch.
Workaround currently used
Every module's tests/conftest.py overrides the framework's db fixture with a per-test NullPool engine:
NullPool avoids connection pooling entirely so every test gets a fresh connection in its own loop.
Suggested fix
In host_conftest.py, ship the db fixture as NullPool-backed by default:
@pytest_asyncio.fixtureasyncdefdb(app):
# Don't share app.state.sm.db.session_factory — that's pooled.# Use a per-test engine to match pytest-asyncio's per-test loops.engine=create_async_engine(_TEST_DATABASE_URL, poolclass=NullPool)
factory=async_sessionmaker(engine, expire_on_commit=False)
asyncwithfactory() assession:
try:
yieldsessionfinally:
awaitsession.rollback()
awaitengine.dispose()
Or document the override prominently and ship a helper users can call from their conftest.
Impact
Every multi-test module needs a NullPool conftest override. We carry this in 4 module conftests already (lacowiki_legends, lacowiki_sampling, lacowiki_validation, and lacowiki_datasets would need it too if it had >1 async test).
Environment
pytest-asyncio>=0.24 (function-scoped event loops by default)
Closing — addressed by commit ade3e24 (PR #98). simple_module_db.session.init_db now accepts a poolclass parameter, so test setups can pass NullPool to avoid the cross-loop Future attached to a different loop failures with asyncpg + pytest-asyncio's per-test event loops.
Activity
fix: address framework papercuts (#66, #68, #71, #73, #75, #76, #81, #90
antosubash commentedon May 1, 2026
Closing — addressed by commit ade3e24 (PR #98).
simple_module_db.session.init_dbnow accepts apoolclassparameter, so test setups can passNullPoolto avoid the cross-loopFuture attached to a different loopfailures with asyncpg + pytest-asyncio's per-test event loops.Generated by Claude Code