Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

ContextVar not propagated from fixture to test #8

Closed
andredias opened this issue Oct 15, 2021 · 8 comments
Closed

ContextVar not propagated from fixture to test #8

andredias opened this issue Oct 15, 2021 · 8 comments

Comments

@andredias
Copy link
Contributor

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:

@delfick
Copy link
Owner

delfick commented Oct 15, 2021

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

delfick added a commit that referenced this issue Oct 16, 2021
Make it so everything gets executed in the same asyncio context
delfick added a commit that referenced this issue Oct 16, 2021
Make it so everything gets executed in the same asyncio context
delfick added a commit that referenced this issue Oct 23, 2021
Make it so everything gets executed in the same asyncio context
delfick added a commit that referenced this issue Oct 24, 2021
Make it so everything gets executed in the same asyncio context
@andredias
Copy link
Contributor Author

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?

@delfick
Copy link
Owner

delfick commented May 14, 2024 via email

@andredias
Copy link
Contributor Author

Thanks!

@andredias
Copy link
Contributor Author

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.

@delfick
Copy link
Owner

delfick commented May 21, 2024

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.

delfick added a commit that referenced this issue May 26, 2024
Make it so everything gets executed in the same asyncio context
delfick added a commit that referenced this issue May 26, 2024
Make it so everything gets executed in the same asyncio context
delfick added a commit that referenced this issue May 26, 2024
Make it so everything gets executed in the same asyncio context
@delfick
Copy link
Owner

delfick commented May 26, 2024

@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? #9

delfick added a commit that referenced this issue Jun 1, 2024
Make it so everything gets executed in the same asyncio context
@delfick
Copy link
Owner

delfick commented Jun 3, 2024

Fixed as part of the 0.8.0 release

@delfick delfick closed this as completed Jun 3, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants