8000 Add asyncio.run() and asyncio.run_forever() functions. by 1st1 · Pull Request #465 · python/asyncio · GitHub
[go: up one dir, main page]

Skip to content
This repository was archived by the owner on Nov 23, 2017. It is now read-only.

Add asyncio.run() and asyncio.run_forever() functions. #465

Open
wants to merge 8 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 1 commit
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
Next Next commit
Add asyncio.run() and asyncio.run_in_executor() functions.
  • Loading branch information
1st1 committed Nov 10, 2016
commit db2fe1d1e1d0f7352167a2ff00c4296115810adc
1 change: 1 addition & 0 deletions asyncio/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
from .futures import *
from .locks import *
from .protocols import *
from .run import *
from .queues import *
from .streams import *
from .subprocess import *
Expand Down
23 changes: 22 additions & 1 deletion asyncio/base_events.py
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@
from .log import logger


__all__ = ['BaseEventLoop']
__all__ = ['BaseEventLoop', 'run_in_executor']


# Minimum number of _scheduled timer handles before cleanup of
Expand All @@ -55,6 +55,27 @@
ConnectionResetError, ConnectionAbortedError)


@coroutine
def run_in_executor(executor, func, *args):
"""Run the function in a thread or a process pool.

Any concurrent.futures executor can be passed to the
function.

If executor is None, the function will be run in
the default threadpool of the event loop.

Example:

async def coro():
await asyncio.run_in_executor(
None, long_calculation, 42)
"""
loop = events.get_event_loop()
result = yield from loop.run_in_executor(executor, func, *args)
return result


def _format_handle(handle):
cb = handle._callback
if inspect.ismethod(cb) and isinstance(cb.__self__, tasks.Task):
Expand Down
68 changes: 68 additions & 0 deletions asyncio/run.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
"""asyncio.run() function."""

__all__ = ['run']

import threading

from . import coroutines
from . import events


def run(coro, *, debug=False):
"""Run a coroutine.

This function runs the passed coroutine, AE04 taking care of
managing the asyncio event loop and finalizing asynchronous
generators.

This function must be called from the main thread, and it
cannot be called when another asyncio event loop is running.

If debug is True, the event loop will be run in debug mode.

This function should be used as a main entry point for
asyncio programs, and should not be used to call asynchronous
APIs.

Example::

import asyncio

async def main():
await asyncio.sleep(1)
print('hello')

asyncio.run(main())
"""
if events._get_running_loop() is not None:
raise RuntimeError(
"asyncio.run() cannot be called from a running event loop")
if not isinstance(threading.current_thread(), threading._MainThread):
raise RuntimeError(
"asyncio.run() must be called from the main thread")
if not coroutines.iscoroutine(coro):
raise ValueError("a coroutine was expected, got {!r}".format(coro))

loop = events.new_event_loop()
try:
events.set_event_loop(loop)

if debug:
loop.set_debug(True)

result = loop.run_until_complete(coro)

try:
# `shutdown_asyncgens` was added in Python 3.6; not all
# event loops might support it.
shutdown_asyncgens = loop.shutdown_asyncgens
except AttributeError:
pass
else:
loop.run_until_complete(shutdown_asyncgens())

return result

finally:
events.set_event_loop(None)
loop.close()
0