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

Suppress most warnings in tests #232

Merged
merged 1 commit into from
May 9, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion MANIFEST.in
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ include MANIFEST.in
include requirements.txt
include requirements-dev.txt
include *.md
include tox.ini
include pytest.ini
include pyproject.toml
include .pre-commit-config.yaml
include nbclient/py.typed
Expand Down
45 changes: 28 additions & 17 deletions nbclient/tests/test_client.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
import warnings
from base64 import b64decode, b64encode
from queue import Empty
from typing import Any
from unittest.mock import MagicMock, Mock

import nbformat
Expand Down Expand Up @@ -78,11 +79,15 @@ class AsyncMock(Mock):
pass


def make_async(mock_value):
async def _():
return mock_value

return _()
def make_future(obj: Any) -> asyncio.Future:
try:
loop = asyncio.get_running_loop()
except RuntimeError:
loop = asyncio.new_event_loop()
asyncio.set_event_loop(loop)
future: asyncio.Future = asyncio.Future(loop=loop)
future.set_result(obj)
return future


def normalize_base64(b64_text):
Expand Down Expand Up @@ -169,7 +174,7 @@ def shell_channel_message_mock():
# Return the message generator for
# self.kc.shell_channel.get_msg => {'parent_header': {'msg_id': parent_id}}
return AsyncMock(
return_value=make_async(
return_value=make_future(
NBClientTestsBase.merge_dicts(
{
'parent_header': {'msg_id': parent_id},
Expand All @@ -186,7 +191,7 @@ def iopub_messages_mock():
return AsyncMock(
side_effect=[
# Default the parent_header so mocks don't need to include this
make_async(
make_future(
NBClientTestsBase.merge_dicts({'parent_header': {'msg_id': parent_id}}, msg)
)
for msg in messages
Expand Down Expand Up @@ -215,7 +220,7 @@ def test_mock_wrapper(self):
iopub_channel=MagicMock(get_msg=message_mock),
shell_channel=MagicMock(get_msg=shell_channel_message_mock()),
execute=MagicMock(return_value=parent_id),
is_alive=MagicMock(return_value=make_async(True)),
is_alive=MagicMock(return_value=make_future(True)),
)
executor.parent_id = parent_id
return func(self, executor, cell_mock, message_mock)
Expand Down Expand Up @@ -387,11 +392,15 @@ def test_async_parallel_notebooks(capfd, tmpdir):
res = notebook_resources()

with modified_env({"NBEXECUTE_TEST_PARALLEL_TMPDIR": str(tmpdir)}):
tasks = [
async_run_notebook(input_file.format(label=label), opts, res) for label in ("A", "B")
]
loop = asyncio.get_event_loop()
loop.run_until_complete(asyncio.gather(*tasks))

async def run_tasks():
tasks = [
async_run_notebook(input_file.format(label=label), opts, res)
for label in ("A", "B")
]
await asyncio.gather(*tasks)

asyncio.run(run_tasks())

captured = capfd.readouterr()
assert filter_messages_on_error_output(captured.err) == ""
Expand All @@ -412,9 +421,11 @@ def test_many_async_parallel_notebooks(capfd):
# run once, to trigger creating the original context
run_notebook(input_file, opts, res)

tasks = [async_run_notebook(input_file, opts, res) for i in range(4)]
loop = asyncio.get_event_loop()
loop.run_until_complete(asyncio.gather(*tasks))
async def run_tasks():
tasks = [async_run_notebook(input_file, opts, res) for i in range(4)]
await asyncio.gather(*tasks)

asyncio.run(run_tasks())

captured = capfd.readouterr()
assert filter_messages_on_error_output(captured.err) == ""
Expand Down Expand Up @@ -966,7 +977,7 @@ def message_seq(messages):

message_mock.side_effect = message_seq(list(message_mock.side_effect)[:-1])
executor.kc.shell_channel.get_msg = Mock(
return_value=make_async({'parent_header': {'msg_id': executor.parent_id}})
return_value=make_future({'parent_header': {'msg_id': executor.parent_id}})
)
executor.raise_on_iopub_timeout = True

Expand Down
12 changes: 8 additions & 4 deletions nbclient/tests/test_util.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,11 +14,15 @@ async def some_async_function():


def test_nested_asyncio_with_existing_ioloop():
ioloop = asyncio.new_event_loop()
try:
asyncio.set_event_loop(ioloop)
async def _test():
assert some_async_function() == 42
assert asyncio.get_event_loop() is ioloop
return asyncio.get_running_loop()

loop = asyncio.new_event_loop()
asyncio.set_event_loop(loop)
try:
event_loop = loop.run_until_complete(_test())
assert event_loop is loop
finally:
asyncio._set_running_loop(None) # it seems nest_asyncio doesn't reset this

Expand Down
14 changes: 6 additions & 8 deletions nbclient/util.py
Original file line number Diff line number Diff line change
Expand Up @@ -39,16 +39,14 @@ def check_patch_tornado() -> None:

def just_run(coro: Awaitable) -> Any:
"""Make the coroutine run, even if there is an event loop running (using nest_asyncio)"""
# original from vaex/asyncio.py
loop = asyncio._get_running_loop()
try:
loop = asyncio.get_running_loop()
except RuntimeError:
loop = None
if loop is None:
had_running_loop = False
try:
loop = asyncio.get_event_loop()
except RuntimeError:
# we can still get 'There is no current event loop in ...'
loop = asyncio.new_event_loop()
asyncio.set_event_loop(loop)
loop = asyncio.new_event_loop()
asyncio.set_event_loop(loop)
else:
had_running_loop = True
if had_running_loop:
Expand Down
2 changes: 2 additions & 0 deletions pytest.ini
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
[pytest]
asyncio_mode = auto