pytest-asyncio icon indicating copy to clipboard operation
pytest-asyncio copied to clipboard

add support for async contextvars

Open n1ywb opened this issue 4 years ago • 11 comments

this ugly hack causes the context to be preserved across all excursions into async land. this fixes https://github.com/pytest-dev/pytest-asyncio/issues/127

n1ywb avatar Apr 18 '20 05:04 n1ywb

works on python 3.8 at least 😅

n1ywb avatar Apr 18 '20 08:04 n1ywb

Why are the hypothesis tests removed?

simonfagerholm avatar Apr 18 '20 09:04 simonfagerholm

Why are the hypothesis tests removed?

oops

n1ywb avatar Apr 18 '20 14:04 n1ywb

Why are the hypothesis tests removed?

honestly its because my internet went down last night and I couldn't install the hypothesis package at the time

n1ywb avatar Apr 18 '20 14:04 n1ywb

one caveat I might mention about this implementation is that EVERY async task will run in the same context. normally child tasks would inherit a COPY of the parent task's context. but it's probably an acceptable trade off in a test environment. but it could cause context to unexpectedly leak from a child task into a parent task.

it's fixable by making the root task a special case that gets the original context while child tasks get copies. but not necessary for my use case ;)

n1ywb avatar Apr 18 '20 14:04 n1ywb

I opened https://bugs.python.org/issue40320 to officially request the ability to pass context to task

n1ywb avatar Apr 18 '20 15:04 n1ywb

I just hit a similar problem regarding contextvars with async-yield fixtures. Could your PR also resolve this case as well?

achimnol avatar Apr 19 '20 15:04 achimnol

I just hit a similar problem regarding contextvars with async-yield fixtures. Could your PR also resolve this case as well?

It should. I use them in my app tests which is the reason I did this.

n1ywb avatar Apr 20 '20 17:04 n1ywb

Works great! Contextvars are such a neat feature ...

Just had to do a minor rebase the branche because master changed from doing "append if not in item.fixturenames" with "remove if in item.fixturenames then insert".

Thank you very much! :tophat:

jpic avatar Jan 10 '21 23:01 jpic

Verified that this one works. I like this one more than #161 since I can easily copy the necessary parts to my conftest.py.

lephuongbg avatar Jul 16 '21 04:07 lephuongbg

Is this fix abandoned?

mr-rodgers avatar Apr 15 '22 18:04 mr-rodgers

I really hate to do this, but I'm closing this PR in favour of the solution proposed in #312. I'll my best to outline my reasons.

I like that you found a nice Task abstraction. It has a high "code locality" (i.e. the functionality coherent and found mostly inside Task). The PR also provides the appropriates tests.

However, the Task class makes use of protected types, such as asyncio.tasks._PyTask and asyncio.futures._PyFuture. Their names or functionality might change between patch releases. As we only test with different minor versions of Python, we likely wouldn't be able to discover any breakage.

The PR also introduces the context fixture, which I see as problematic. Pytest-asyncio currently encourages overriding the event_loop fixture, in order to control the fixture scope. Unfortunately, people tend to write all sorts of code into their event_loop fixtures, in order to "inject" functionality into their tests. This makes it hard to maintain pytest-asyncio as the custom code in the loop fixture causes additional corner cases that break when changing the plugin code. Therefore, we should try to reduce the number of fixtures provided by pytest-asyncio, rather than adding more (see #311). I fear that adding the context fixture will open another can of worms similar to event_loop.

Python 3.11 introduces asyncio.Runner, which essentially allows running multiple async functions in the same context. #312 introduces the concept of a Runner in pytest-asyncio. I think this is the approach we should take

Others have reported they could use similar code in their conftest.py, so this may serve them as a workaround, until #127 is fixed.

I'm sorry this PR was stale for such a long time. A single maintainer can only spend so much time and we only "added staff" in the beginning of this year.

seifertm avatar Sep 06 '22 18:09 seifertm