alt-pytest-asyncio
alt-pytest-asyncio copied to clipboard
ContextVar not propagated from fixture to test
As pytest-asyncio
, it seems that alt-pytest-asyncio
also doesn't propagate ContextVar to tests. Instead of duplicating the problem description, I will list the references to the issue below:
Hello,
I've never worked with context vars before. I might have time to look today, this sounds more interesting than what I was gonna do hahah
I've got a new issue on alt-pytest-asyncio that might be related to #8 since the library databases relies on ContextVars. I created a minimal example to show the problem:
from collections.abc import AsyncIterable
from databases import Database
from pytest import fixture
@fixture
async def db() -> AsyncIterable[Database]:
db: Database = Database("sqlite:///", force_rollback=True)
await db.connect()
try:
yield db
finally:
await db.disconnect()
async def test_db(db: Database) -> None: ...
It is just one test_1.py
file that is supposed to be run by pytest test_issue.py
. It is supposed to run flawlessly but I get this error:
$ pytest
=================================== test session starts ===================================
platform linux -- Python 3.12.3, pytest-8.2.0, pluggy-1.5.0
rootdir: /tmp/databases
plugins: alt-pytest-asyncio-0.7.2
collected 1 item
tests/test_1.py .E [100%]
========================================= ERRORS ==========================================
______________________________ ERROR at teardown of test_db _______________________________
@fixture
async def db() -> AsyncIterable[Database]:
db: Database = Database("sqlite:///", force_rollback=True)
await db.connect()
try:
yield db
finally:
> await db.disconnect()
tests/test_1.py:14:
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
.venv/lib/python3.12/site-packages/databases/core.py:141: in disconnect
await self._global_transaction.__aexit__()
.venv/lib/python3.12/site-packages/databases/core.py:426: in __aexit__
await self.rollback()
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
self = <databases.core.Transaction object at 0x75ea0da77470>
async def rollback(self) -> None:
async with self._connection._transaction_lock:
assert self._connection._transaction_stack[-1] is self
self._connection._transaction_stack.pop()
> assert self._transaction is not None
E AssertionError
.venv/lib/python3.12/site-packages/databases/core.py:473: AssertionError
The test not only fails but it also hangs.
Note that databases
uses a contexVar
Setup
To run this snippet, you need:
- databases[aiosqlite]
- pytest
- alt-pytest-asyncio
Can you help me solve that?
Hello,
I should have time on the weekend to take a look :)
On Tue, 14 May 2024, 03:21 André Felipe Dias, @.***> wrote:
I've got a new issue on alt-pytest-asyncio that might be related to #8 https://github.com/delfick/alt-pytest-asyncio/issues/8 since the library databases relies on ContextVars https://github.com/encode/databases/blob/ae3fb16f40201d9ed0ed31bea31a289127169568/databases/core.py#L39. I created a minimal example to show the problem:
from collections.abc import AsyncIterable from databases import Databasefrom pytest import fixture
@fixtureasync def db() -> AsyncIterable[Database]: db: Database = Database("sqlite:///", force_rollback=True) await db.connect() try: yield db finally: await db.disconnect()
async def test_db(db: Database) -> None: ...
It is just one test_1.py file that is supposed to be run by pytest test_issue.py. It is supposed to run flawlessly but I get this error:
$ pytest =================================== test session starts =================================== platform linux -- Python 3.12.3, pytest-8.2.0, pluggy-1.5.0 rootdir: /tmp/databases plugins: alt-pytest-asyncio-0.7.2 collected 1 item
tests/test_1.py .E [100%]
========================================= ERRORS ========================================== ______________________________ ERROR at teardown of test_db _______________________________
@fixture async def db() -> AsyncIterable[Database]: db: Database = Database("sqlite:///", force_rollback=True) await db.connect() try: yield db finally:> await db.disconnect()
tests/test_1.py:14:
.venv/lib/python3.12/site-packages/databases/core.py:141: in disconnect await self._global_transaction.aexit() .venv/lib/python3.12/site-packages/databases/core.py:426: in aexit await self.rollback()
self = <databases.core.Transaction object at 0x75ea0da77470>
async def rollback(self) -> None: async with self._connection._transaction_lock: assert self._connection._transaction_stack[-1] is self self._connection._transaction_stack.pop()> assert self._transaction is not None
E AssertionError
.venv/lib/python3.12/site-packages/databases/core.py:473: AssertionError
The test not only fails but it also hangs.
Note that databases uses a contexVar Setup
To run this snippet, you need:
- databases[aiosqlite]
- pytest
- alt-pytest-asyncio
Can you help me solve that?
— Reply to this email directly, view it on GitHub https://github.com/delfick/alt-pytest-asyncio/issues/8#issuecomment-2108316047, or unsubscribe https://github.com/notifications/unsubscribe-auth/AAA2V5PIRFEWGPQIB63LFPDZCDZAVAVCNFSM5GCIA4EKU5DIOJSWCZC7NNSXTN2JONZXKZKDN5WW2ZLOOQ5TEMJQHAZTCNRQGQ3Q . You are receiving this because you commented.Message ID: @.***>
Thanks!
The exact same issue was reported here. There is another comment in the previous link that mentions anyio pytest-plugin as a possible solution.
I saw somewhere else about using asyncio.Runner to keep the context among different tasks.
I should have time on the weekend to take a look :)
Turns out that very much wasn't the case, we'll see if I do this weekend.
@andredias
I saw somewhere else about using asyncio.Runner to keep the context among different tasks.
I tried using asyncio.Runner against the changes already in that PR and it got messy really quick. I'd need to do some very invasive surgery to this project to use that properly and I don't have the time atm.
Also, it would require the project being python 3.11 and above. I have put in that change into the PR anyway cause it removed one of the hacks the original attempt was doing.
Does that PR work for you now? https://github.com/delfick/alt-pytest-asyncio/pull/9
Fixed as part of the 0.8.0 release