AsyncGen.c 38 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066
  1. // This is copied from genobject.c in CPython 3.6.
  2. // Try to keep it in sync by doing this from time to time:
  3. // sed -e 's|__pyx_||ig' Cython/Utility/AsyncGen.c | diff -udw - cpython/Objects/genobject.c | less
  4. //////////////////// AsyncGenerator.proto ////////////////////
  5. //@requires: Coroutine.c::Coroutine
  6. #define __Pyx_AsyncGen_USED
  7. typedef struct {
  8. __pyx_CoroutineObject coro;
  9. PyObject *ag_finalizer;
  10. int ag_hooks_inited;
  11. int ag_closed;
  12. } __pyx_PyAsyncGenObject;
  13. static PyTypeObject *__pyx__PyAsyncGenWrappedValueType = 0;
  14. static PyTypeObject *__pyx__PyAsyncGenASendType = 0;
  15. static PyTypeObject *__pyx__PyAsyncGenAThrowType = 0;
  16. static PyTypeObject *__pyx_AsyncGenType = 0;
  17. #define __Pyx_AsyncGen_CheckExact(obj) (Py_TYPE(obj) == __pyx_AsyncGenType)
  18. #define __pyx_PyAsyncGenASend_CheckExact(o) \
  19. (Py_TYPE(o) == __pyx__PyAsyncGenASendType)
  20. #define __pyx_PyAsyncGenAThrow_CheckExact(o) \
  21. (Py_TYPE(o) == __pyx__PyAsyncGenAThrowType)
  22. static PyObject *__Pyx_async_gen_anext(PyObject *o);
  23. static CYTHON_INLINE PyObject *__Pyx_async_gen_asend_iternext(PyObject *o);
  24. static PyObject *__Pyx_async_gen_asend_send(PyObject *o, PyObject *arg);
  25. static PyObject *__Pyx_async_gen_asend_close(PyObject *o, PyObject *args);
  26. static PyObject *__Pyx_async_gen_athrow_close(PyObject *o, PyObject *args);
  27. static PyObject *__Pyx__PyAsyncGenValueWrapperNew(PyObject *val);
  28. static __pyx_CoroutineObject *__Pyx_AsyncGen_New(
  29. __pyx_coroutine_body_t body, PyObject *code, PyObject *closure,
  30. PyObject *name, PyObject *qualname, PyObject *module_name) {
  31. __pyx_PyAsyncGenObject *gen = PyObject_GC_New(__pyx_PyAsyncGenObject, __pyx_AsyncGenType);
  32. if (unlikely(!gen))
  33. return NULL;
  34. gen->ag_finalizer = NULL;
  35. gen->ag_closed = 0;
  36. gen->ag_hooks_inited = 0;
  37. return __Pyx__Coroutine_NewInit((__pyx_CoroutineObject*)gen, body, code, closure, name, qualname, module_name);
  38. }
  39. static int __pyx_AsyncGen_init(void);
  40. static void __Pyx_PyAsyncGen_Fini(void);
  41. //////////////////// AsyncGenerator.cleanup ////////////////////
  42. __Pyx_PyAsyncGen_Fini();
  43. //////////////////// AsyncGeneratorInitFinalizer ////////////////////
  44. // this is separated out because it needs more adaptation
  45. #if PY_VERSION_HEX < 0x030600B0
  46. static int __Pyx_async_gen_init_hooks(__pyx_PyAsyncGenObject *o) {
  47. #if 0
  48. // TODO: implement finalizer support in older Python versions
  49. PyThreadState *tstate;
  50. PyObject *finalizer;
  51. PyObject *firstiter;
  52. #endif
  53. if (likely(o->ag_hooks_inited)) {
  54. return 0;
  55. }
  56. o->ag_hooks_inited = 1;
  57. #if 0
  58. tstate = __Pyx_PyThreadState_Current;
  59. finalizer = tstate->async_gen_finalizer;
  60. if (finalizer) {
  61. Py_INCREF(finalizer);
  62. o->ag_finalizer = finalizer;
  63. }
  64. firstiter = tstate->async_gen_firstiter;
  65. if (firstiter) {
  66. PyObject *res;
  67. Py_INCREF(firstiter);
  68. res = __Pyx_PyObject_CallOneArg(firstiter, (PyObject*)o);
  69. Py_DECREF(firstiter);
  70. if (res == NULL) {
  71. return 1;
  72. }
  73. Py_DECREF(res);
  74. }
  75. #endif
  76. return 0;
  77. }
  78. #endif
  79. //////////////////// AsyncGenerator ////////////////////
  80. //@requires: AsyncGeneratorInitFinalizer
  81. //@requires: Coroutine.c::Coroutine
  82. //@requires: Coroutine.c::ReturnWithStopIteration
  83. //@requires: ObjectHandling.c::PyObjectCallMethod1
  84. //@requires: ObjectHandling.c::PyObject_GenericGetAttrNoDict
  85. PyDoc_STRVAR(__Pyx_async_gen_send_doc,
  86. "send(arg) -> send 'arg' into generator,\n\
  87. return next yielded value or raise StopIteration.");
  88. PyDoc_STRVAR(__Pyx_async_gen_close_doc,
  89. "close() -> raise GeneratorExit inside generator.");
  90. PyDoc_STRVAR(__Pyx_async_gen_throw_doc,
  91. "throw(typ[,val[,tb]]) -> raise exception in generator,\n\
  92. return next yielded value or raise StopIteration.");
  93. PyDoc_STRVAR(__Pyx_async_gen_await_doc,
  94. "__await__() -> return a representation that can be passed into the 'await' expression.");
  95. // COPY STARTS HERE:
  96. static PyObject *__Pyx_async_gen_asend_new(__pyx_PyAsyncGenObject *, PyObject *);
  97. static PyObject *__Pyx_async_gen_athrow_new(__pyx_PyAsyncGenObject *, PyObject *);
  98. static const char *__Pyx_NON_INIT_CORO_MSG = "can't send non-None value to a just-started coroutine";
  99. static const char *__Pyx_ASYNC_GEN_IGNORED_EXIT_MSG = "async generator ignored GeneratorExit";
  100. typedef enum {
  101. __PYX_AWAITABLE_STATE_INIT, /* new awaitable, has not yet been iterated */
  102. __PYX_AWAITABLE_STATE_ITER, /* being iterated */
  103. __PYX_AWAITABLE_STATE_CLOSED, /* closed */
  104. } __pyx_AwaitableState;
  105. typedef struct {
  106. PyObject_HEAD
  107. __pyx_PyAsyncGenObject *ags_gen;
  108. /* Can be NULL, when in the __anext__() mode (equivalent of "asend(None)") */
  109. PyObject *ags_sendval;
  110. __pyx_AwaitableState ags_state;
  111. } __pyx_PyAsyncGenASend;
  112. typedef struct {
  113. PyObject_HEAD
  114. __pyx_PyAsyncGenObject *agt_gen;
  115. /* Can be NULL, when in the "aclose()" mode (equivalent of "athrow(GeneratorExit)") */
  116. PyObject *agt_args;
  117. __pyx_AwaitableState agt_state;
  118. } __pyx_PyAsyncGenAThrow;
  119. typedef struct {
  120. PyObject_HEAD
  121. PyObject *agw_val;
  122. } __pyx__PyAsyncGenWrappedValue;
  123. #ifndef _PyAsyncGen_MAXFREELIST
  124. #define _PyAsyncGen_MAXFREELIST 80
  125. #endif
  126. // Freelists boost performance 6-10%; they also reduce memory
  127. // fragmentation, as _PyAsyncGenWrappedValue and PyAsyncGenASend
  128. // are short-living objects that are instantiated for every
  129. // __anext__ call.
  130. static __pyx__PyAsyncGenWrappedValue *__Pyx_ag_value_freelist[_PyAsyncGen_MAXFREELIST];
  131. static int __Pyx_ag_value_freelist_free = 0;
  132. static __pyx_PyAsyncGenASend *__Pyx_ag_asend_freelist[_PyAsyncGen_MAXFREELIST];
  133. static int __Pyx_ag_asend_freelist_free = 0;
  134. #define __pyx__PyAsyncGenWrappedValue_CheckExact(o) \
  135. (Py_TYPE(o) == __pyx__PyAsyncGenWrappedValueType)
  136. static int
  137. __Pyx_async_gen_traverse(__pyx_PyAsyncGenObject *gen, visitproc visit, void *arg)
  138. {
  139. Py_VISIT(gen->ag_finalizer);
  140. return __Pyx_Coroutine_traverse((__pyx_CoroutineObject*)gen, visit, arg);
  141. }
  142. static PyObject *
  143. __Pyx_async_gen_repr(__pyx_CoroutineObject *o)
  144. {
  145. // avoid NULL pointer dereference for qualname during garbage collection
  146. return PyUnicode_FromFormat("<async_generator object %S at %p>",
  147. o->gi_qualname ? o->gi_qualname : Py_None, o);
  148. }
  149. #if PY_VERSION_HEX >= 0x030600B0
  150. static int
  151. __Pyx_async_gen_init_hooks(__pyx_PyAsyncGenObject *o)
  152. {
  153. PyThreadState *tstate;
  154. PyObject *finalizer;
  155. PyObject *firstiter;
  156. if (o->ag_hooks_inited) {
  157. return 0;
  158. }
  159. o->ag_hooks_inited = 1;
  160. tstate = __Pyx_PyThreadState_Current;
  161. finalizer = tstate->async_gen_finalizer;
  162. if (finalizer) {
  163. Py_INCREF(finalizer);
  164. o->ag_finalizer = finalizer;
  165. }
  166. firstiter = tstate->async_gen_firstiter;
  167. if (firstiter) {
  168. PyObject *res;
  169. Py_INCREF(firstiter);
  170. // at least asyncio stores methods here => optimise the call
  171. res = __Pyx__PyObject_CallMethod1(firstiter, (PyObject*)o);
  172. Py_DECREF(firstiter);
  173. if (unlikely(res == NULL)) {
  174. return 1;
  175. }
  176. Py_DECREF(res);
  177. }
  178. return 0;
  179. }
  180. #endif
  181. static PyObject *
  182. __Pyx_async_gen_anext(PyObject *g)
  183. {
  184. __pyx_PyAsyncGenObject *o = (__pyx_PyAsyncGenObject*) g;
  185. if (__Pyx_async_gen_init_hooks(o)) {
  186. return NULL;
  187. }
  188. return __Pyx_async_gen_asend_new(o, NULL);
  189. }
  190. static PyObject *
  191. __Pyx_async_gen_asend(__pyx_PyAsyncGenObject *o, PyObject *arg)
  192. {
  193. if (__Pyx_async_gen_init_hooks(o)) {
  194. return NULL;
  195. }
  196. return __Pyx_async_gen_asend_new(o, arg);
  197. }
  198. static PyObject *
  199. __Pyx_async_gen_aclose(__pyx_PyAsyncGenObject *o, CYTHON_UNUSED PyObject *arg)
  200. {
  201. if (__Pyx_async_gen_init_hooks(o)) {
  202. return NULL;
  203. }
  204. return __Pyx_async_gen_athrow_new(o, NULL);
  205. }
  206. static PyObject *
  207. __Pyx_async_gen_athrow(__pyx_PyAsyncGenObject *o, PyObject *args)
  208. {
  209. if (__Pyx_async_gen_init_hooks(o)) {
  210. return NULL;
  211. }
  212. return __Pyx_async_gen_athrow_new(o, args);
  213. }
  214. static PyGetSetDef __Pyx_async_gen_getsetlist[] = {
  215. {(char*) "__name__", (getter)__Pyx_Coroutine_get_name, (setter)__Pyx_Coroutine_set_name,
  216. (char*) PyDoc_STR("name of the async generator"), 0},
  217. {(char*) "__qualname__", (getter)__Pyx_Coroutine_get_qualname, (setter)__Pyx_Coroutine_set_qualname,
  218. (char*) PyDoc_STR("qualified name of the async generator"), 0},
  219. //REMOVED: {(char*) "ag_await", (getter)coro_get_cr_await, NULL,
  220. //REMOVED: (char*) PyDoc_STR("object being awaited on, or None")},
  221. {0, 0, 0, 0, 0} /* Sentinel */
  222. };
  223. static PyMemberDef __Pyx_async_gen_memberlist[] = {
  224. //REMOVED: {(char*) "ag_frame", T_OBJECT, offsetof(__pyx_PyAsyncGenObject, ag_frame), READONLY},
  225. {(char*) "ag_running", T_BOOL, offsetof(__pyx_CoroutineObject, is_running), READONLY, NULL},
  226. //REMOVED: {(char*) "ag_code", T_OBJECT, offsetof(__pyx_PyAsyncGenObject, ag_code), READONLY},
  227. //ADDED: "ag_await"
  228. {(char*) "ag_await", T_OBJECT, offsetof(__pyx_CoroutineObject, yieldfrom), READONLY,
  229. (char*) PyDoc_STR("object being awaited on, or None")},
  230. {0, 0, 0, 0, 0} /* Sentinel */
  231. };
  232. PyDoc_STRVAR(__Pyx_async_aclose_doc,
  233. "aclose() -> raise GeneratorExit inside generator.");
  234. PyDoc_STRVAR(__Pyx_async_asend_doc,
  235. "asend(v) -> send 'v' in generator.");
  236. PyDoc_STRVAR(__Pyx_async_athrow_doc,
  237. "athrow(typ[,val[,tb]]) -> raise exception in generator.");
  238. PyDoc_STRVAR(__Pyx_async_aiter_doc,
  239. "__aiter__(v) -> return an asynchronous iterator.");
  240. PyDoc_STRVAR(__Pyx_async_anext_doc,
  241. "__anext__(v) -> continue asynchronous iteration and return the next element.");
  242. static PyMethodDef __Pyx_async_gen_methods[] = {
  243. {"asend", (PyCFunction)__Pyx_async_gen_asend, METH_O, __Pyx_async_asend_doc},
  244. {"athrow",(PyCFunction)__Pyx_async_gen_athrow, METH_VARARGS, __Pyx_async_athrow_doc},
  245. {"aclose", (PyCFunction)__Pyx_async_gen_aclose, METH_NOARGS, __Pyx_async_aclose_doc},
  246. {"__aiter__", (PyCFunction)PyObject_SelfIter, METH_NOARGS, __Pyx_async_aiter_doc},
  247. {"__anext__", (PyCFunction)__Pyx_async_gen_anext, METH_NOARGS, __Pyx_async_anext_doc},
  248. {0, 0, 0, 0} /* Sentinel */
  249. };
  250. #if CYTHON_USE_ASYNC_SLOTS
  251. static __Pyx_PyAsyncMethodsStruct __Pyx_async_gen_as_async = {
  252. 0, /* am_await */
  253. PyObject_SelfIter, /* am_aiter */
  254. (unaryfunc)__Pyx_async_gen_anext /* am_anext */
  255. };
  256. #endif
  257. static PyTypeObject __pyx_AsyncGenType_type = {
  258. PyVarObject_HEAD_INIT(0, 0)
  259. "async_generator", /* tp_name */
  260. sizeof(__pyx_PyAsyncGenObject), /* tp_basicsize */
  261. 0, /* tp_itemsize */
  262. (destructor)__Pyx_Coroutine_dealloc, /* tp_dealloc */
  263. 0, /* tp_print */
  264. 0, /* tp_getattr */
  265. 0, /* tp_setattr */
  266. #if CYTHON_USE_ASYNC_SLOTS
  267. &__Pyx_async_gen_as_async, /* tp_as_async */
  268. #else
  269. 0, /*tp_reserved*/
  270. #endif
  271. (reprfunc)__Pyx_async_gen_repr, /* tp_repr */
  272. 0, /* tp_as_number */
  273. 0, /* tp_as_sequence */
  274. 0, /* tp_as_mapping */
  275. 0, /* tp_hash */
  276. 0, /* tp_call */
  277. 0, /* tp_str */
  278. 0, /* tp_getattro */
  279. 0, /* tp_setattro */
  280. 0, /* tp_as_buffer */
  281. Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC |
  282. Py_TPFLAGS_HAVE_FINALIZE, /* tp_flags */
  283. 0, /* tp_doc */
  284. (traverseproc)__Pyx_async_gen_traverse, /* tp_traverse */
  285. 0, /* tp_clear */
  286. #if CYTHON_USE_ASYNC_SLOTS && CYTHON_COMPILING_IN_CPYTHON && PY_MAJOR_VERSION >= 3 && PY_VERSION_HEX < 0x030500B1
  287. // in order to (mis-)use tp_reserved above, we must also implement tp_richcompare
  288. __Pyx_Coroutine_compare, /*tp_richcompare*/
  289. #else
  290. 0, /*tp_richcompare*/
  291. #endif
  292. offsetof(__pyx_CoroutineObject, gi_weakreflist), /* tp_weaklistoffset */
  293. 0, /* tp_iter */
  294. 0, /* tp_iternext */
  295. __Pyx_async_gen_methods, /* tp_methods */
  296. __Pyx_async_gen_memberlist, /* tp_members */
  297. __Pyx_async_gen_getsetlist, /* tp_getset */
  298. 0, /* tp_base */
  299. 0, /* tp_dict */
  300. 0, /* tp_descr_get */
  301. 0, /* tp_descr_set */
  302. 0, /* tp_dictoffset */
  303. 0, /* tp_init */
  304. 0, /* tp_alloc */
  305. 0, /* tp_new */
  306. 0, /* tp_free */
  307. 0, /* tp_is_gc */
  308. 0, /* tp_bases */
  309. 0, /* tp_mro */
  310. 0, /* tp_cache */
  311. 0, /* tp_subclasses */
  312. 0, /* tp_weaklist */
  313. #if CYTHON_USE_TP_FINALIZE
  314. 0, /*tp_del*/
  315. #else
  316. __Pyx_Coroutine_del, /*tp_del*/
  317. #endif
  318. 0, /* tp_version_tag */
  319. #if CYTHON_USE_TP_FINALIZE
  320. __Pyx_Coroutine_del, /* tp_finalize */
  321. #elif PY_VERSION_HEX >= 0x030400a1
  322. 0, /* tp_finalize */
  323. #endif
  324. };
  325. static int
  326. __Pyx_PyAsyncGen_ClearFreeLists(void)
  327. {
  328. int ret = __Pyx_ag_value_freelist_free + __Pyx_ag_asend_freelist_free;
  329. while (__Pyx_ag_value_freelist_free) {
  330. __pyx__PyAsyncGenWrappedValue *o;
  331. o = __Pyx_ag_value_freelist[--__Pyx_ag_value_freelist_free];
  332. assert(__pyx__PyAsyncGenWrappedValue_CheckExact(o));
  333. PyObject_GC_Del(o);
  334. }
  335. while (__Pyx_ag_asend_freelist_free) {
  336. __pyx_PyAsyncGenASend *o;
  337. o = __Pyx_ag_asend_freelist[--__Pyx_ag_asend_freelist_free];
  338. assert(Py_TYPE(o) == __pyx__PyAsyncGenASendType);
  339. PyObject_GC_Del(o);
  340. }
  341. return ret;
  342. }
  343. static void
  344. __Pyx_PyAsyncGen_Fini(void)
  345. {
  346. __Pyx_PyAsyncGen_ClearFreeLists();
  347. }
  348. static PyObject *
  349. __Pyx_async_gen_unwrap_value(__pyx_PyAsyncGenObject *gen, PyObject *result)
  350. {
  351. if (result == NULL) {
  352. PyObject *exc_type = PyErr_Occurred();
  353. if (!exc_type) {
  354. PyErr_SetNone(__Pyx_PyExc_StopAsyncIteration);
  355. gen->ag_closed = 1;
  356. } else if (__Pyx_PyErr_GivenExceptionMatches2(exc_type, __Pyx_PyExc_StopAsyncIteration, PyExc_GeneratorExit)) {
  357. gen->ag_closed = 1;
  358. }
  359. return NULL;
  360. }
  361. if (__pyx__PyAsyncGenWrappedValue_CheckExact(result)) {
  362. /* async yield */
  363. __Pyx_ReturnWithStopIteration(((__pyx__PyAsyncGenWrappedValue*)result)->agw_val);
  364. Py_DECREF(result);
  365. return NULL;
  366. }
  367. return result;
  368. }
  369. /* ---------- Async Generator ASend Awaitable ------------ */
  370. static void
  371. __Pyx_async_gen_asend_dealloc(__pyx_PyAsyncGenASend *o)
  372. {
  373. PyObject_GC_UnTrack((PyObject *)o);
  374. Py_CLEAR(o->ags_gen);
  375. Py_CLEAR(o->ags_sendval);
  376. if (__Pyx_ag_asend_freelist_free < _PyAsyncGen_MAXFREELIST) {
  377. assert(__pyx_PyAsyncGenASend_CheckExact(o));
  378. __Pyx_ag_asend_freelist[__Pyx_ag_asend_freelist_free++] = o;
  379. } else {
  380. PyObject_GC_Del(o);
  381. }
  382. }
  383. static int
  384. __Pyx_async_gen_asend_traverse(__pyx_PyAsyncGenASend *o, visitproc visit, void *arg)
  385. {
  386. Py_VISIT(o->ags_gen);
  387. Py_VISIT(o->ags_sendval);
  388. return 0;
  389. }
  390. static PyObject *
  391. __Pyx_async_gen_asend_send(PyObject *g, PyObject *arg)
  392. {
  393. __pyx_PyAsyncGenASend *o = (__pyx_PyAsyncGenASend*) g;
  394. PyObject *result;
  395. if (unlikely(o->ags_state == __PYX_AWAITABLE_STATE_CLOSED)) {
  396. PyErr_SetNone(PyExc_StopIteration);
  397. return NULL;
  398. }
  399. if (o->ags_state == __PYX_AWAITABLE_STATE_INIT) {
  400. if (arg == NULL || arg == Py_None) {
  401. arg = o->ags_sendval ? o->ags_sendval : Py_None;
  402. }
  403. o->ags_state = __PYX_AWAITABLE_STATE_ITER;
  404. }
  405. result = __Pyx_Coroutine_Send((PyObject*)o->ags_gen, arg);
  406. result = __Pyx_async_gen_unwrap_value(o->ags_gen, result);
  407. if (result == NULL) {
  408. o->ags_state = __PYX_AWAITABLE_STATE_CLOSED;
  409. }
  410. return result;
  411. }
  412. static CYTHON_INLINE PyObject *
  413. __Pyx_async_gen_asend_iternext(PyObject *o)
  414. {
  415. return __Pyx_async_gen_asend_send(o, Py_None);
  416. }
  417. static PyObject *
  418. __Pyx_async_gen_asend_throw(__pyx_PyAsyncGenASend *o, PyObject *args)
  419. {
  420. PyObject *result;
  421. if (unlikely(o->ags_state == __PYX_AWAITABLE_STATE_CLOSED)) {
  422. PyErr_SetNone(PyExc_StopIteration);
  423. return NULL;
  424. }
  425. result = __Pyx_Coroutine_Throw((PyObject*)o->ags_gen, args);
  426. result = __Pyx_async_gen_unwrap_value(o->ags_gen, result);
  427. if (result == NULL) {
  428. o->ags_state = __PYX_AWAITABLE_STATE_CLOSED;
  429. }
  430. return result;
  431. }
  432. static PyObject *
  433. __Pyx_async_gen_asend_close(PyObject *g, CYTHON_UNUSED PyObject *args)
  434. {
  435. __pyx_PyAsyncGenASend *o = (__pyx_PyAsyncGenASend*) g;
  436. o->ags_state = __PYX_AWAITABLE_STATE_CLOSED;
  437. Py_RETURN_NONE;
  438. }
  439. static PyMethodDef __Pyx_async_gen_asend_methods[] = {
  440. {"send", (PyCFunction)__Pyx_async_gen_asend_send, METH_O, __Pyx_async_gen_send_doc},
  441. {"throw", (PyCFunction)__Pyx_async_gen_asend_throw, METH_VARARGS, __Pyx_async_gen_throw_doc},
  442. {"close", (PyCFunction)__Pyx_async_gen_asend_close, METH_NOARGS, __Pyx_async_gen_close_doc},
  443. {"__await__", (PyCFunction)PyObject_SelfIter, METH_NOARGS, __Pyx_async_gen_await_doc},
  444. {0, 0, 0, 0} /* Sentinel */
  445. };
  446. #if CYTHON_USE_ASYNC_SLOTS
  447. static __Pyx_PyAsyncMethodsStruct __Pyx_async_gen_asend_as_async = {
  448. PyObject_SelfIter, /* am_await */
  449. 0, /* am_aiter */
  450. 0 /* am_anext */
  451. };
  452. #endif
  453. static PyTypeObject __pyx__PyAsyncGenASendType_type = {
  454. PyVarObject_HEAD_INIT(0, 0)
  455. "async_generator_asend", /* tp_name */
  456. sizeof(__pyx_PyAsyncGenASend), /* tp_basicsize */
  457. 0, /* tp_itemsize */
  458. /* methods */
  459. (destructor)__Pyx_async_gen_asend_dealloc, /* tp_dealloc */
  460. 0, /* tp_print */
  461. 0, /* tp_getattr */
  462. 0, /* tp_setattr */
  463. #if CYTHON_USE_ASYNC_SLOTS
  464. &__Pyx_async_gen_asend_as_async, /* tp_as_async */
  465. #else
  466. 0, /*tp_reserved*/
  467. #endif
  468. 0, /* tp_repr */
  469. 0, /* tp_as_number */
  470. 0, /* tp_as_sequence */
  471. 0, /* tp_as_mapping */
  472. 0, /* tp_hash */
  473. 0, /* tp_call */
  474. 0, /* tp_str */
  475. 0, /* tp_getattro */
  476. 0, /* tp_setattro */
  477. 0, /* tp_as_buffer */
  478. Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC, /* tp_flags */
  479. 0, /* tp_doc */
  480. (traverseproc)__Pyx_async_gen_asend_traverse, /* tp_traverse */
  481. 0, /* tp_clear */
  482. #if CYTHON_USE_ASYNC_SLOTS && CYTHON_COMPILING_IN_CPYTHON && PY_MAJOR_VERSION >= 3 && PY_VERSION_HEX < 0x030500B1
  483. // in order to (mis-)use tp_reserved above, we must also implement tp_richcompare
  484. __Pyx_Coroutine_compare, /*tp_richcompare*/
  485. #else
  486. 0, /*tp_richcompare*/
  487. #endif
  488. 0, /* tp_weaklistoffset */
  489. PyObject_SelfIter, /* tp_iter */
  490. (iternextfunc)__Pyx_async_gen_asend_iternext, /* tp_iternext */
  491. __Pyx_async_gen_asend_methods, /* tp_methods */
  492. 0, /* tp_members */
  493. 0, /* tp_getset */
  494. 0, /* tp_base */
  495. 0, /* tp_dict */
  496. 0, /* tp_descr_get */
  497. 0, /* tp_descr_set */
  498. 0, /* tp_dictoffset */
  499. 0, /* tp_init */
  500. 0, /* tp_alloc */
  501. 0, /* tp_new */
  502. 0, /* tp_free */
  503. 0, /* tp_is_gc */
  504. 0, /* tp_bases */
  505. 0, /* tp_mro */
  506. 0, /* tp_cache */
  507. 0, /* tp_subclasses */
  508. 0, /* tp_weaklist */
  509. 0, /* tp_del */
  510. 0, /* tp_version_tag */
  511. #if PY_VERSION_HEX >= 0x030400a1
  512. 0, /* tp_finalize */
  513. #endif
  514. };
  515. static PyObject *
  516. __Pyx_async_gen_asend_new(__pyx_PyAsyncGenObject *gen, PyObject *sendval)
  517. {
  518. __pyx_PyAsyncGenASend *o;
  519. if (__Pyx_ag_asend_freelist_free) {
  520. __Pyx_ag_asend_freelist_free--;
  521. o = __Pyx_ag_asend_freelist[__Pyx_ag_asend_freelist_free];
  522. _Py_NewReference((PyObject *)o);
  523. } else {
  524. o = PyObject_GC_New(__pyx_PyAsyncGenASend, __pyx__PyAsyncGenASendType);
  525. if (o == NULL) {
  526. return NULL;
  527. }
  528. }
  529. Py_INCREF(gen);
  530. o->ags_gen = gen;
  531. Py_XINCREF(sendval);
  532. o->ags_sendval = sendval;
  533. o->ags_state = __PYX_AWAITABLE_STATE_INIT;
  534. PyObject_GC_Track((PyObject*)o);
  535. return (PyObject*)o;
  536. }
  537. /* ---------- Async Generator Value Wrapper ------------ */
  538. static void
  539. __Pyx_async_gen_wrapped_val_dealloc(__pyx__PyAsyncGenWrappedValue *o)
  540. {
  541. PyObject_GC_UnTrack((PyObject *)o);
  542. Py_CLEAR(o->agw_val);
  543. if (__Pyx_ag_value_freelist_free < _PyAsyncGen_MAXFREELIST) {
  544. assert(__pyx__PyAsyncGenWrappedValue_CheckExact(o));
  545. __Pyx_ag_value_freelist[__Pyx_ag_value_freelist_free++] = o;
  546. } else {
  547. PyObject_GC_Del(o);
  548. }
  549. }
  550. static int
  551. __Pyx_async_gen_wrapped_val_traverse(__pyx__PyAsyncGenWrappedValue *o,
  552. visitproc visit, void *arg)
  553. {
  554. Py_VISIT(o->agw_val);
  555. return 0;
  556. }
  557. static PyTypeObject __pyx__PyAsyncGenWrappedValueType_type = {
  558. PyVarObject_HEAD_INIT(0, 0)
  559. "async_generator_wrapped_value", /* tp_name */
  560. sizeof(__pyx__PyAsyncGenWrappedValue), /* tp_basicsize */
  561. 0, /* tp_itemsize */
  562. /* methods */
  563. (destructor)__Pyx_async_gen_wrapped_val_dealloc, /* tp_dealloc */
  564. 0, /* tp_print */
  565. 0, /* tp_getattr */
  566. 0, /* tp_setattr */
  567. 0, /* tp_as_async */
  568. 0, /* tp_repr */
  569. 0, /* tp_as_number */
  570. 0, /* tp_as_sequence */
  571. 0, /* tp_as_mapping */
  572. 0, /* tp_hash */
  573. 0, /* tp_call */
  574. 0, /* tp_str */
  575. 0, /* tp_getattro */
  576. 0, /* tp_setattro */
  577. 0, /* tp_as_buffer */
  578. Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC, /* tp_flags */
  579. 0, /* tp_doc */
  580. (traverseproc)__Pyx_async_gen_wrapped_val_traverse, /* tp_traverse */
  581. 0, /* tp_clear */
  582. 0, /* tp_richcompare */
  583. 0, /* tp_weaklistoffset */
  584. 0, /* tp_iter */
  585. 0, /* tp_iternext */
  586. 0, /* tp_methods */
  587. 0, /* tp_members */
  588. 0, /* tp_getset */
  589. 0, /* tp_base */
  590. 0, /* tp_dict */
  591. 0, /* tp_descr_get */
  592. 0, /* tp_descr_set */
  593. 0, /* tp_dictoffset */
  594. 0, /* tp_init */
  595. 0, /* tp_alloc */
  596. 0, /* tp_new */
  597. 0, /* tp_free */
  598. 0, /* tp_is_gc */
  599. 0, /* tp_bases */
  600. 0, /* tp_mro */
  601. 0, /* tp_cache */
  602. 0, /* tp_subclasses */
  603. 0, /* tp_weaklist */
  604. 0, /* tp_del */
  605. 0, /* tp_version_tag */
  606. #if PY_VERSION_HEX >= 0x030400a1
  607. 0, /* tp_finalize */
  608. #endif
  609. };
  610. static PyObject *
  611. __Pyx__PyAsyncGenValueWrapperNew(PyObject *val)
  612. {
  613. // NOTE: steals a reference to val !
  614. __pyx__PyAsyncGenWrappedValue *o;
  615. assert(val);
  616. if (__Pyx_ag_value_freelist_free) {
  617. __Pyx_ag_value_freelist_free--;
  618. o = __Pyx_ag_value_freelist[__Pyx_ag_value_freelist_free];
  619. assert(__pyx__PyAsyncGenWrappedValue_CheckExact(o));
  620. _Py_NewReference((PyObject*)o);
  621. } else {
  622. o = PyObject_GC_New(__pyx__PyAsyncGenWrappedValue, __pyx__PyAsyncGenWrappedValueType);
  623. if (unlikely(!o)) {
  624. Py_DECREF(val);
  625. return NULL;
  626. }
  627. }
  628. o->agw_val = val;
  629. // no Py_INCREF(val) - steals reference!
  630. PyObject_GC_Track((PyObject*)o);
  631. return (PyObject*)o;
  632. }
  633. /* ---------- Async Generator AThrow awaitable ------------ */
  634. static void
  635. __Pyx_async_gen_athrow_dealloc(__pyx_PyAsyncGenAThrow *o)
  636. {
  637. PyObject_GC_UnTrack((PyObject *)o);
  638. Py_CLEAR(o->agt_gen);
  639. Py_CLEAR(o->agt_args);
  640. PyObject_GC_Del(o);
  641. }
  642. static int
  643. __Pyx_async_gen_athrow_traverse(__pyx_PyAsyncGenAThrow *o, visitproc visit, void *arg)
  644. {
  645. Py_VISIT(o->agt_gen);
  646. Py_VISIT(o->agt_args);
  647. return 0;
  648. }
  649. static PyObject *
  650. __Pyx_async_gen_athrow_send(__pyx_PyAsyncGenAThrow *o, PyObject *arg)
  651. {
  652. __pyx_CoroutineObject *gen = (__pyx_CoroutineObject*)o->agt_gen;
  653. PyObject *retval;
  654. if (o->agt_state == __PYX_AWAITABLE_STATE_CLOSED) {
  655. PyErr_SetNone(PyExc_StopIteration);
  656. return NULL;
  657. }
  658. if (o->agt_state == __PYX_AWAITABLE_STATE_INIT) {
  659. if (o->agt_gen->ag_closed) {
  660. PyErr_SetNone(PyExc_StopIteration);
  661. return NULL;
  662. }
  663. if (arg != Py_None) {
  664. PyErr_SetString(PyExc_RuntimeError, __Pyx_NON_INIT_CORO_MSG);
  665. return NULL;
  666. }
  667. o->agt_state = __PYX_AWAITABLE_STATE_ITER;
  668. if (o->agt_args == NULL) {
  669. /* aclose() mode */
  670. o->agt_gen->ag_closed = 1;
  671. retval = __Pyx__Coroutine_Throw((PyObject*)gen,
  672. /* Do not close generator when
  673. PyExc_GeneratorExit is passed */
  674. PyExc_GeneratorExit, NULL, NULL, NULL, 0);
  675. if (retval && __pyx__PyAsyncGenWrappedValue_CheckExact(retval)) {
  676. Py_DECREF(retval);
  677. goto yield_close;
  678. }
  679. } else {
  680. PyObject *typ;
  681. PyObject *tb = NULL;
  682. PyObject *val = NULL;
  683. if (!PyArg_UnpackTuple(o->agt_args, "athrow", 1, 3,
  684. &typ, &val, &tb)) {
  685. return NULL;
  686. }
  687. retval = __Pyx__Coroutine_Throw((PyObject*)gen,
  688. /* Do not close generator when PyExc_GeneratorExit is passed */
  689. typ, val, tb, o->agt_args, 0);
  690. retval = __Pyx_async_gen_unwrap_value(o->agt_gen, retval);
  691. }
  692. if (retval == NULL) {
  693. goto check_error;
  694. }
  695. return retval;
  696. }
  697. assert (o->agt_state == __PYX_AWAITABLE_STATE_ITER);
  698. retval = __Pyx_Coroutine_Send((PyObject *)gen, arg);
  699. if (o->agt_args) {
  700. return __Pyx_async_gen_unwrap_value(o->agt_gen, retval);
  701. } else {
  702. /* aclose() mode */
  703. if (retval) {
  704. if (__pyx__PyAsyncGenWrappedValue_CheckExact(retval)) {
  705. Py_DECREF(retval);
  706. goto yield_close;
  707. }
  708. else {
  709. return retval;
  710. }
  711. }
  712. else {
  713. goto check_error;
  714. }
  715. }
  716. yield_close:
  717. PyErr_SetString(
  718. PyExc_RuntimeError, __Pyx_ASYNC_GEN_IGNORED_EXIT_MSG);
  719. return NULL;
  720. check_error:
  721. if (PyErr_ExceptionMatches(__Pyx_PyExc_StopAsyncIteration)) {
  722. o->agt_state = __PYX_AWAITABLE_STATE_CLOSED;
  723. if (o->agt_args == NULL) {
  724. // when aclose() is called we don't want to propagate
  725. // StopAsyncIteration; just raise StopIteration, signalling
  726. // that 'aclose()' is done.
  727. PyErr_Clear();
  728. PyErr_SetNone(PyExc_StopIteration);
  729. }
  730. }
  731. else if (PyErr_ExceptionMatches(PyExc_GeneratorExit)) {
  732. o->agt_state = __PYX_AWAITABLE_STATE_CLOSED;
  733. PyErr_Clear(); /* ignore these errors */
  734. PyErr_SetNone(PyExc_StopIteration);
  735. }
  736. return NULL;
  737. }
  738. static PyObject *
  739. __Pyx_async_gen_athrow_throw(__pyx_PyAsyncGenAThrow *o, PyObject *args)
  740. {
  741. PyObject *retval;
  742. if (o->agt_state == __PYX_AWAITABLE_STATE_INIT) {
  743. PyErr_SetString(PyExc_RuntimeError, __Pyx_NON_INIT_CORO_MSG);
  744. return NULL;
  745. }
  746. if (o->agt_state == __PYX_AWAITABLE_STATE_CLOSED) {
  747. PyErr_SetNone(PyExc_StopIteration);
  748. return NULL;
  749. }
  750. retval = __Pyx_Coroutine_Throw((PyObject*)o->agt_gen, args);
  751. if (o->agt_args) {
  752. return __Pyx_async_gen_unwrap_value(o->agt_gen, retval);
  753. } else {
  754. /* aclose() mode */
  755. if (retval && __pyx__PyAsyncGenWrappedValue_CheckExact(retval)) {
  756. Py_DECREF(retval);
  757. PyErr_SetString(PyExc_RuntimeError, __Pyx_ASYNC_GEN_IGNORED_EXIT_MSG);
  758. return NULL;
  759. }
  760. return retval;
  761. }
  762. }
  763. static PyObject *
  764. __Pyx_async_gen_athrow_iternext(__pyx_PyAsyncGenAThrow *o)
  765. {
  766. return __Pyx_async_gen_athrow_send(o, Py_None);
  767. }
  768. static PyObject *
  769. __Pyx_async_gen_athrow_close(PyObject *g, CYTHON_UNUSED PyObject *args)
  770. {
  771. __pyx_PyAsyncGenAThrow *o = (__pyx_PyAsyncGenAThrow*) g;
  772. o->agt_state = __PYX_AWAITABLE_STATE_CLOSED;
  773. Py_RETURN_NONE;
  774. }
  775. static PyMethodDef __Pyx_async_gen_athrow_methods[] = {
  776. {"send", (PyCFunction)__Pyx_async_gen_athrow_send, METH_O, __Pyx_async_gen_send_doc},
  777. {"throw", (PyCFunction)__Pyx_async_gen_athrow_throw, METH_VARARGS, __Pyx_async_gen_throw_doc},
  778. {"close", (PyCFunction)__Pyx_async_gen_athrow_close, METH_NOARGS, __Pyx_async_gen_close_doc},
  779. {"__await__", (PyCFunction)PyObject_SelfIter, METH_NOARGS, __Pyx_async_gen_await_doc},
  780. {0, 0, 0, 0} /* Sentinel */
  781. };
  782. #if CYTHON_USE_ASYNC_SLOTS
  783. static __Pyx_PyAsyncMethodsStruct __Pyx_async_gen_athrow_as_async = {
  784. PyObject_SelfIter, /* am_await */
  785. 0, /* am_aiter */
  786. 0 /* am_anext */
  787. };
  788. #endif
  789. static PyTypeObject __pyx__PyAsyncGenAThrowType_type = {
  790. PyVarObject_HEAD_INIT(0, 0)
  791. "async_generator_athrow", /* tp_name */
  792. sizeof(__pyx_PyAsyncGenAThrow), /* tp_basicsize */
  793. 0, /* tp_itemsize */
  794. (destructor)__Pyx_async_gen_athrow_dealloc, /* tp_dealloc */
  795. 0, /* tp_print */
  796. 0, /* tp_getattr */
  797. 0, /* tp_setattr */
  798. #if CYTHON_USE_ASYNC_SLOTS
  799. &__Pyx_async_gen_athrow_as_async, /* tp_as_async */
  800. #else
  801. 0, /*tp_reserved*/
  802. #endif
  803. 0, /* tp_repr */
  804. 0, /* tp_as_number */
  805. 0, /* tp_as_sequence */
  806. 0, /* tp_as_mapping */
  807. 0, /* tp_hash */
  808. 0, /* tp_call */
  809. 0, /* tp_str */
  810. 0, /* tp_getattro */
  811. 0, /* tp_setattro */
  812. 0, /* tp_as_buffer */
  813. Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC, /* tp_flags */
  814. 0, /* tp_doc */
  815. (traverseproc)__Pyx_async_gen_athrow_traverse, /* tp_traverse */
  816. 0, /* tp_clear */
  817. #if CYTHON_USE_ASYNC_SLOTS && CYTHON_COMPILING_IN_CPYTHON && PY_MAJOR_VERSION >= 3 && PY_VERSION_HEX < 0x030500B1
  818. // in order to (mis-)use tp_reserved above, we must also implement tp_richcompare
  819. __Pyx_Coroutine_compare, /*tp_richcompare*/
  820. #else
  821. 0, /*tp_richcompare*/
  822. #endif
  823. 0, /* tp_weaklistoffset */
  824. PyObject_SelfIter, /* tp_iter */
  825. (iternextfunc)__Pyx_async_gen_athrow_iternext, /* tp_iternext */
  826. __Pyx_async_gen_athrow_methods, /* tp_methods */
  827. 0, /* tp_members */
  828. 0, /* tp_getset */
  829. 0, /* tp_base */
  830. 0, /* tp_dict */
  831. 0, /* tp_descr_get */
  832. 0, /* tp_descr_set */
  833. 0, /* tp_dictoffset */
  834. 0, /* tp_init */
  835. 0, /* tp_alloc */
  836. 0, /* tp_new */
  837. 0, /* tp_free */
  838. 0, /* tp_is_gc */
  839. 0, /* tp_bases */
  840. 0, /* tp_mro */
  841. 0, /* tp_cache */
  842. 0, /* tp_subclasses */
  843. 0, /* tp_weaklist */
  844. 0, /* tp_del */
  845. 0, /* tp_version_tag */
  846. #if PY_VERSION_HEX >= 0x030400a1
  847. 0, /* tp_finalize */
  848. #endif
  849. };
  850. static PyObject *
  851. __Pyx_async_gen_athrow_new(__pyx_PyAsyncGenObject *gen, PyObject *args)
  852. {
  853. __pyx_PyAsyncGenAThrow *o;
  854. o = PyObject_GC_New(__pyx_PyAsyncGenAThrow, __pyx__PyAsyncGenAThrowType);
  855. if (o == NULL) {
  856. return NULL;
  857. }
  858. o->agt_gen = gen;
  859. o->agt_args = args;
  860. o->agt_state = __PYX_AWAITABLE_STATE_INIT;
  861. Py_INCREF(gen);
  862. Py_XINCREF(args);
  863. PyObject_GC_Track((PyObject*)o);
  864. return (PyObject*)o;
  865. }
  866. /* ---------- global type sharing ------------ */
  867. static int __pyx_AsyncGen_init(void) {
  868. // on Windows, C-API functions can't be used in slots statically
  869. __pyx_AsyncGenType_type.tp_getattro = __Pyx_PyObject_GenericGetAttrNoDict;
  870. __pyx__PyAsyncGenWrappedValueType_type.tp_getattro = __Pyx_PyObject_GenericGetAttrNoDict;
  871. __pyx__PyAsyncGenAThrowType_type.tp_getattro = __Pyx_PyObject_GenericGetAttrNoDict;
  872. __pyx__PyAsyncGenASendType_type.tp_getattro = __Pyx_PyObject_GenericGetAttrNoDict;
  873. __pyx_AsyncGenType = __Pyx_FetchCommonType(&__pyx_AsyncGenType_type);
  874. if (unlikely(!__pyx_AsyncGenType))
  875. return -1;
  876. __pyx__PyAsyncGenAThrowType = __Pyx_FetchCommonType(&__pyx__PyAsyncGenAThrowType_type);
  877. if (unlikely(!__pyx__PyAsyncGenAThrowType))
  878. return -1;
  879. __pyx__PyAsyncGenWrappedValueType = __Pyx_FetchCommonType(&__pyx__PyAsyncGenWrappedValueType_type);
  880. if (unlikely(!__pyx__PyAsyncGenWrappedValueType))
  881. return -1;
  882. __pyx__PyAsyncGenASendType = __Pyx_FetchCommonType(&__pyx__PyAsyncGenASendType_type);
  883. if (unlikely(!__pyx__PyAsyncGenASendType))
  884. return -1;
  885. return 0;
  886. }