There should be a better workaround for event_loop removal and Deprecation of event loop policies in 3.14
Closed this issue · 3 comments
Seeing this library and having utilized it with a few of my smaller libraries like aiocallback and aiothreading I want to be able to test asyncio's default loop alongside winloop on windows and uvloop on linux and Apple. Now I know of the event loop policies and all of that but the problem is that it's deprecated in 3.14 with removal coming in 3.16 and I would hate to have to use an uncomfortable hack of my own. I wanted to write a solution that doesn't devolve into bringing back event_loop because it was removed #1106 and I think keeping the warning's mouth shut about is a bad approach. So here's what I wanted to bring to the table hence why I am throwing this issue about it first.
Solution
I see fit to make a new autouse fixure for making use of functions that involve using new_event_loop based off winloop/uvloop's new_event_loop function and asyncio's as well. Something like this maybe to get around the different deprecated/removed approches.
@pytest.fixture(scope="session", autouse=True)
def new_event_loop() -> asyncio.AbstractEventLoop:
"""creates different asyncio event loops."""
return asyncio.new_event_loop()This fixure or apporch should be easy for anyone to pull off and here's an example of how I would go about using it.
import pytest
import sys
import asyncio
uvloop = pytest.importorskip("winloop" if sys.platform == "win32" else "uvloop", reason="uvloop library not installed")
UVLOOP_MARK = pytest.mark.uvloop_event_loop
ASYNCIO_MARK = pytest.mark.asyncio_event_loop
@pytest.fixture(
scope="module",
params=(
asyncio.new_event_loop,
pytest.param(
uvloop.new_event_loop,
marks=UVLOOP_MARK
)
)
)
def new_event_loop(request:pytest.FixtureRequest) -> asyncio.AbstractEventLoop:
return request.param()
@pytest.mark.asyncio
async def do_test():
...from cyares.aio import DNSResolver
import asyncio
import pytest
import sys
# Only apply to aio and nowhere else...
uvloop = pytest.importorskip("winloop" if sys.platform == "win32" else "uvloop")
@pytest.fixture(
scope="module",
params=(
"uvloop/winloop",
"std-asyncio"
),
# autouse allows us to override allowing multiple
# eventloops to be tested at a time.
autouse=True,
ids=str
)
def event_loop(request:pytest.FixtureRequest):
if request.param == "uvloop/winloop":
loop = uvloop.new_event_loop()
yield loop
else:
# XXX: DNS Resolver will freeze if we attempt to use
# ProactorEventLoop, your better off using winloop
# with the dns resolver.
if sys.platform == "win32":
loop = asyncio.SelectorEventLoop()
asyncio.set_event_loop(loop)
else:
loop = asyncio.new_event_loop()
yield loop
loop.close()
@pytest.mark.asyncio
async def test_dns_a():
async with DNSResolver(["8.8.8.8", "8.8.4.4"]) as dns:
t = await dns.query("google.com", "A")
assert t
@pytest.mark.asyncio
async def test_dns_aaaa():
async with DNSResolver(["8.8.8.8", "8.8.4.4"]) as dns:
t = await dns.query("google.com", "AAAA")
assert tNevermind I seem to have found one. It's not a pretty solution because I've isolated this to one module since the library I'm using this with only needs asyncio for one module, however I stand by my words of proposing updating the documentation to something that is not deprecated. Nope it's still broken.
I'm gonna try migrating to unittest.IsolatedAsyncioTestCase for the time being.
@seifertm any way forward for having the https://pytest-asyncio.rtfd.io/en/stable/how-to-guides/multiple_loops.html recipe future-proof?