Commit e9726181 authored by Stefan Behnel's avatar Stefan Behnel

make async generator type async-iterable in older Python versions

parent d8853365
...@@ -302,10 +302,18 @@ PyDoc_STRVAR(__Pyx_async_asend_doc, ...@@ -302,10 +302,18 @@ PyDoc_STRVAR(__Pyx_async_asend_doc,
PyDoc_STRVAR(__Pyx_async_athrow_doc, PyDoc_STRVAR(__Pyx_async_athrow_doc,
"athrow(typ[,val[,tb]]) -> raise exception in generator."); "athrow(typ[,val[,tb]]) -> raise exception in generator.");
PyDoc_STRVAR(__Pyx_async_aiter_doc,
"__aiter__(v) -> return an asynchronous iterator.");
PyDoc_STRVAR(__Pyx_async_anext_doc,
"__anext__(v) -> continue asynchronous iteration and return the next element.");
static PyMethodDef __Pyx_async_gen_methods[] = { static PyMethodDef __Pyx_async_gen_methods[] = {
{"asend", (PyCFunction)__Pyx_async_gen_asend, METH_O, __Pyx_async_asend_doc}, {"asend", (PyCFunction)__Pyx_async_gen_asend, METH_O, __Pyx_async_asend_doc},
{"athrow",(PyCFunction)__Pyx_async_gen_athrow, METH_VARARGS, __Pyx_async_athrow_doc}, {"athrow",(PyCFunction)__Pyx_async_gen_athrow, METH_VARARGS, __Pyx_async_athrow_doc},
{"aclose", (PyCFunction)__Pyx_async_gen_aclose, METH_NOARGS, __Pyx_async_aclose_doc}, {"aclose", (PyCFunction)__Pyx_async_gen_aclose, METH_NOARGS, __Pyx_async_aclose_doc},
{"__aiter__", (PyCFunction)PyObject_SelfIter, METH_NOARGS, __Pyx_async_aiter_doc},
{"__anext__", (PyCFunction)__Pyx_async_gen_anext, METH_NOARGS, __Pyx_async_anext_doc},
{0, 0, 0, 0} /* Sentinel */ {0, 0, 0, 0} /* Sentinel */
}; };
......
...@@ -6,8 +6,8 @@ from __future__ import generator_stop ...@@ -6,8 +6,8 @@ from __future__ import generator_stop
import os import os
import sys import sys
import inspect #import inspect
import types #import types
import unittest import unittest
import contextlib import contextlib
...@@ -36,8 +36,64 @@ else: ...@@ -36,8 +36,64 @@ else:
try: try:
from types import coroutine as types_coroutine from types import coroutine as types_coroutine
except ImportError: except ImportError:
def types_coroutine(f): def types_coroutine(func):
return f from functools import wraps
wrapped = wraps(func)
# copied from types.py in Py3.6
class _GeneratorWrapper(object):
# TODO: Implement this in C.
def __init__(self, gen):
self.__wrapped = gen
self.__isgen = hasattr(gen, 'gi_running')
self.__name__ = getattr(gen, '__name__', None)
self.__qualname__ = getattr(gen, '__qualname__', None)
def send(self, val):
return self.__wrapped.send(val)
def throw(self, tp, *rest):
return self.__wrapped.throw(tp, *rest)
def close(self):
return self.__wrapped.close()
@property
def gi_code(self):
return self.__wrapped.gi_code
@property
def gi_frame(self):
return self.__wrapped.gi_frame
@property
def gi_running(self):
return self.__wrapped.gi_running
@property
def gi_yieldfrom(self):
return self.__wrapped.gi_yieldfrom
cr_code = gi_code
cr_frame = gi_frame
cr_running = gi_running
cr_await = gi_yieldfrom
def __next__(self):
return next(self.__wrapped)
def __iter__(self):
if self.__isgen:
return self.__wrapped
return self
__await__ = __iter__
@wrapped
def call(*args, **kwargs):
return wrapped(_GeneratorWrapper(func(*args, **kwargs)))
return call
try: try:
from inspect import isawaitable as inspect_isawaitable from inspect import isawaitable as inspect_isawaitable
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment