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

Commit f24ff30

Browse files
committed
try async generators
1 parent 9acdceb commit f24ff30

File tree

3 files changed

+29
-26
lines changed

3 files changed

+29
-26
lines changed

asyncio/base_events.py

-14
Original file line numberDiff line numberDiff line change
@@ -294,9 +294,6 @@ def __init__(self):
294294
# Set to True when `loop.shutdown_asyncgens` is called.
295295
self._asyncgens_shutdown_called = False
296296

297-
# Future that isn't resolved while the loop is running.
298-
self._forever_fut = None
299-
300297
def __repr__(self):
301298
return ('<%s running=%s closed=%s debug=%s>'
302299
% (self.__class__.__name__, self.is_running(),
@@ -433,12 +430,8 @@ def shutdown_asyncgens(self):
433430
'asyncgen': agen
434431
})
435432

436-
def get_forever_future(self):
437-
return self._forever_fut
438-
439433
def run_forever(self):
440434
"""Run until stop() is called."""
441-
self._forever_fut = self.create_future()
442435
self._check_closed()
443436
if self.is_running():
444437
raise RuntimeError('This event loop is already running')
@@ -457,14 +450,7 @@ def run_forever(self):
457450
self._run_once()
458451
if self._stopping:
459452
break
460-
except BaseException as ex:
461-
self._forever_fut.set_exception(ex)
462-
self._forever_fut._log_traceback = False
463-
raise ex
464-
else:
465-
self._forever_fut.set_result(None)
466453
finally:
467-
self._forever_fut = None
468454
self._stopping = False
469455
self._thread_id = None
470456
events._set_running_loop(None)

asyncio/events.py

-3
Original file line numberDiff line numberDiff line change
@@ -512,9 +512,6 @@ def get_debug(self):
512512
def set_debug(self, enabled):
513513
raise NotImplementedError
514514

515-
def get_forever_future(self):
516-
raise NotImplementedError
517-
518515

519516
class AbstractEventLoopPolicy:
520517
"""Abstract policy for accessing the event loop."""

asyncio/run.py

+29-9
Original file line numberDiff line numberDiff line change
@@ -2,12 +2,19 @@
22

33
__all__ = ['run', 'forever']
44

5+
import inspect
56
import threading
67

78
from . import coroutines
89
from . import events
910

1011

12+
def _isasyncgen(obj):
13+
if hasattr(inspect, 'isasyncgen'):
14+
return inspect.isasyncgen(obj)
15+
return False
16+
17+
1118
@coroutines.coroutine
1219
def forever():
1320
"""Wait until the current event loop stops running.
@@ -67,8 +74,10 @@ async def main():
6774
if not isinstance(threading.current_thread(), threading._MainThread):
6875
raise RuntimeError(
6976
"asyncio.run() must be called from the main thread")
70-
if not coroutines.iscoroutine(coro):
71-
raise ValueError("a coroutine was expected, got {!r}".format(coro))
77+
if not coroutines.iscoroutine(coro) and not _isasyncgen(coro):
78+
raise ValueError(
79+
"a coroutine or an asynchronous generator was expected, "
80+
"got {!r}".format(coro))
7281

7382
loop = events.new_event_loop()
7483
try:
@@ -77,15 +86,26 @@ async def main():
7786
if debug:
7887
loop.set_debug(True)
7988

80-
task = loop.create_task(coro)
81-
task.add_done_callback(lambda task: loop.stop())
89+
if _isasyncgen(coro):
90+
result = None
91+
loop.run_until_complete(coro.asend(None))
92+
try:
93+
loop.run_forever()
94+
except BaseException as ex:
95+
try:
96+
loop.run_until_complete(coro.athrow(ex))
97+
except StopAsyncIteration as ex:
98+
if ex.args:
99+
result = ex.args[0]
100+
else:
101+
try:
102+
loop.run_until_complete(coro.asend(None))
103+
except StopAsyncIteration as ex:
104+
if ex.args:
105+
result = ex.args[0]
82106

83-
try:
84-
loop.run_forever()
85-
except BaseException as ex:
86-
result = loop.run_until_complete(task)
87107
else:
88-
result = task.result()
108+
result = loop.run_until_complete(coro)
89109

90110
try:
91111
# `shutdown_asyncgens` was added in Python 3.6; not all

0 commit comments

Comments
 (0)