-
Notifications
You must be signed in to change notification settings - Fork 94
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
Workaround for asyncio.get_event_loop() deprecation #355
Changes from all commits
cf1f2ae
25cbb08
c950c78
528e46e
875679c
a9c5fc8
502852a
667464a
f8128e7
462b3c0
0271497
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,4 +1,21 @@ | ||
# Copyright 2014-2021 The aiosmtpd Developers | ||
# SPDX-License-Identifier: Apache-2.0 | ||
import asyncio | ||
import warnings | ||
|
||
__version__ = "1.4.4a0" | ||
|
||
__version__ = "1.4.4a1" | ||
|
||
|
||
def _get_or_new_eventloop() -> asyncio.AbstractEventLoop: | ||
loop = None | ||
with warnings.catch_warnings(): | ||
warnings.simplefilter("error") | ||
try: | ||
loop = asyncio.get_event_loop() | ||
except (DeprecationWarning, RuntimeError): # pragma: py-lt-310 | ||
if loop is None: # pragma: py-lt-312 | ||
loop = asyncio.new_event_loop() | ||
asyncio.set_event_loop(loop) | ||
assert isinstance(loop, asyncio.AbstractEventLoop) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. comment FWIW this is probably less useful, since assertions can be disabled. And everything will go sideways shortly after this function gets called anyway 😂 There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. It's mostly for type checking, not expected to do anything useful 😂 |
||
return loop |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,52 @@ | ||
# Copyright 2014-2021 The aiosmtpd Developers | ||
# SPDX-License-Identifier: Apache-2.0 | ||
|
||
"""Test other aspects of the server implementation.""" | ||
|
||
import asyncio | ||
import warnings | ||
from typing import Generator, Optional | ||
|
||
import pytest | ||
|
||
from aiosmtpd import _get_or_new_eventloop | ||
|
||
|
||
@pytest.fixture(scope="module") | ||
def close_existing_loop() -> Generator[Optional[asyncio.AbstractEventLoop], None, None]: | ||
loop: Optional[asyncio.AbstractEventLoop] | ||
with warnings.catch_warnings(): | ||
warnings.filterwarnings("error") | ||
try: | ||
loop = asyncio.get_event_loop() | ||
except (DeprecationWarning, RuntimeError): | ||
loop = None | ||
if loop: | ||
loop.stop() | ||
loop.close() | ||
asyncio.set_event_loop(None) | ||
yield loop | ||
else: | ||
yield None | ||
|
||
|
||
class TestInit: | ||
|
||
def test_create_new_if_none(self, close_existing_loop): | ||
old_loop = close_existing_loop | ||
loop: Optional[asyncio.AbstractEventLoop] | ||
loop = _get_or_new_eventloop() | ||
assert loop is not None | ||
assert loop is not old_loop | ||
assert isinstance(loop, asyncio.AbstractEventLoop) | ||
|
||
def test_not_create_new_if_exist(self, close_existing_loop): | ||
old_loop = close_existing_loop | ||
loop: Optional[asyncio.AbstractEventLoop] | ||
loop = asyncio.new_event_loop() | ||
assert loop is not old_loop | ||
asyncio.set_event_loop(loop) | ||
ret_loop = _get_or_new_eventloop() | ||
assert ret_loop is not old_loop | ||
assert ret_loop == loop | ||
assert ret_loop is loop |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
On Python 3.11 (and I believe also 3.10), though
get_event_loop()
raises a warning when there's no existing event loop, it does indeed return a newly-created event loop. This defensive check prevents (re-)creation of a new event loop in that situation.On Python 3.12 the behavior likely changes, i.e., no implicit creation of event loop inside
get_event_loop()
. In that situation,loop
will remainNone
and only in that case will we create a new event loop.That is why this particular check has a
# pragma: py-lt-312
mark there, because the branch will never be taken for Python<3.12