/src/Python-3.8.3/Objects/genobject.c
Line  | Count  | Source  | 
1  |  | /* Generator object implementation */  | 
2  |  |  | 
3  |  | #include "Python.h"  | 
4  |  | #include "pycore_object.h"  | 
5  |  | #include "pycore_pystate.h"  | 
6  |  | #include "frameobject.h"  | 
7  |  | #include "structmember.h"  | 
8  |  | #include "opcode.h"  | 
9  |  |  | 
10  |  | static PyObject *gen_close(PyGenObject *, PyObject *);  | 
11  |  | static PyObject *async_gen_asend_new(PyAsyncGenObject *, PyObject *);  | 
12  |  | static PyObject *async_gen_athrow_new(PyAsyncGenObject *, PyObject *);  | 
13  |  |  | 
14  |  | static const char *NON_INIT_CORO_MSG = "can't send non-None value to a "  | 
15  |  |                                  "just-started coroutine";  | 
16  |  |  | 
17  |  | static const char *ASYNC_GEN_IGNORED_EXIT_MSG =  | 
18  |  |                                  "async generator ignored GeneratorExit";  | 
19  |  |  | 
20  |  | static inline int  | 
21  |  | exc_state_traverse(_PyErr_StackItem *exc_state, visitproc visit, void *arg)  | 
22  | 0  | { | 
23  | 0  |     Py_VISIT(exc_state->exc_type);  | 
24  | 0  |     Py_VISIT(exc_state->exc_value);  | 
25  | 0  |     Py_VISIT(exc_state->exc_traceback);  | 
26  | 0  |     return 0;  | 
27  | 0  | }  | 
28  |  |  | 
29  |  | static int  | 
30  |  | gen_traverse(PyGenObject *gen, visitproc visit, void *arg)  | 
31  | 0  | { | 
32  | 0  |     Py_VISIT((PyObject *)gen->gi_frame);  | 
33  | 0  |     Py_VISIT(gen->gi_code);  | 
34  | 0  |     Py_VISIT(gen->gi_name);  | 
35  | 0  |     Py_VISIT(gen->gi_qualname);  | 
36  |  |     /* No need to visit cr_origin, because it's just tuples/str/int, so can't  | 
37  |  |        participate in a reference cycle. */  | 
38  | 0  |     return exc_state_traverse(&gen->gi_exc_state, visit, arg);  | 
39  | 0  | }  | 
40  |  |  | 
41  |  | void  | 
42  |  | _PyGen_Finalize(PyObject *self)  | 
43  | 228  | { | 
44  | 228  |     PyGenObject *gen = (PyGenObject *)self;  | 
45  | 228  |     PyObject *res = NULL;  | 
46  | 228  |     PyObject *error_type, *error_value, *error_traceback;  | 
47  |  |  | 
48  | 228  |     if (gen->gi_frame == NULL || gen->gi_frame->f_stacktop == NULL) { | 
49  |  |         /* Generator isn't paused, so no need to close */  | 
50  | 195  |         return;  | 
51  | 195  |     }  | 
52  |  |  | 
53  | 33  |     if (PyAsyncGen_CheckExact(self)) { | 
54  | 15  |         PyAsyncGenObject *agen = (PyAsyncGenObject*)self;  | 
55  | 15  |         PyObject *finalizer = agen->ag_finalizer;  | 
56  | 15  |         if (finalizer && !agen->ag_closed) { | 
57  |  |             /* Save the current exception, if any. */  | 
58  | 0  |             PyErr_Fetch(&error_type, &error_value, &error_traceback);  | 
59  |  | 
  | 
60  | 0  |             res = PyObject_CallFunctionObjArgs(finalizer, self, NULL);  | 
61  |  | 
  | 
62  | 0  |             if (res == NULL) { | 
63  | 0  |                 PyErr_WriteUnraisable(self);  | 
64  | 0  |             } else { | 
65  | 0  |                 Py_DECREF(res);  | 
66  | 0  |             }  | 
67  |  |             /* Restore the saved exception. */  | 
68  | 0  |             PyErr_Restore(error_type, error_value, error_traceback);  | 
69  | 0  |             return;  | 
70  | 0  |         }  | 
71  | 15  |     }  | 
72  |  |  | 
73  |  |     /* Save the current exception, if any. */  | 
74  | 33  |     PyErr_Fetch(&error_type, &error_value, &error_traceback);  | 
75  |  |  | 
76  |  |     /* If `gen` is a coroutine, and if it was never awaited on,  | 
77  |  |        issue a RuntimeWarning. */  | 
78  | 33  |     if (gen->gi_code != NULL &&  | 
79  | 33  |         ((PyCodeObject *)gen->gi_code)->co_flags & CO_COROUTINE &&  | 
80  | 0  |         gen->gi_frame->f_lasti == -1)  | 
81  | 0  |     { | 
82  | 0  |         _PyErr_WarnUnawaitedCoroutine((PyObject *)gen);  | 
83  | 0  |     }  | 
84  | 33  |     else { | 
85  | 33  |         res = gen_close(gen, NULL);  | 
86  | 33  |     }  | 
87  |  |  | 
88  | 33  |     if (res == NULL) { | 
89  | 0  |         if (PyErr_Occurred()) { | 
90  | 0  |             PyErr_WriteUnraisable(self);  | 
91  | 0  |         }  | 
92  | 0  |     }  | 
93  | 33  |     else { | 
94  | 33  |         Py_DECREF(res);  | 
95  | 33  |     }  | 
96  |  |  | 
97  |  |     /* Restore the saved exception. */  | 
98  | 33  |     PyErr_Restore(error_type, error_value, error_traceback);  | 
99  | 33  | }  | 
100  |  |  | 
101  |  | static inline void  | 
102  |  | exc_state_clear(_PyErr_StackItem *exc_state)  | 
103  | 456  | { | 
104  | 456  |     PyObject *t, *v, *tb;  | 
105  | 456  |     t = exc_state->exc_type;  | 
106  | 456  |     v = exc_state->exc_value;  | 
107  | 456  |     tb = exc_state->exc_traceback;  | 
108  | 456  |     exc_state->exc_type = NULL;  | 
109  | 456  |     exc_state->exc_value = NULL;  | 
110  | 456  |     exc_state->exc_traceback = NULL;  | 
111  | 456  |     Py_XDECREF(t);  | 
112  | 456  |     Py_XDECREF(v);  | 
113  | 456  |     Py_XDECREF(tb);  | 
114  | 456  | }  | 
115  |  |  | 
116  |  | static void  | 
117  |  | gen_dealloc(PyGenObject *gen)  | 
118  | 228  | { | 
119  | 228  |     PyObject *self = (PyObject *) gen;  | 
120  |  |  | 
121  | 228  |     _PyObject_GC_UNTRACK(gen);  | 
122  |  |  | 
123  | 228  |     if (gen->gi_weakreflist != NULL)  | 
124  | 0  |         PyObject_ClearWeakRefs(self);  | 
125  |  |  | 
126  | 228  |     _PyObject_GC_TRACK(self);  | 
127  |  |  | 
128  | 228  |     if (PyObject_CallFinalizerFromDealloc(self))  | 
129  | 0  |         return;                     /* resurrected.  :( */  | 
130  |  |  | 
131  | 228  |     _PyObject_GC_UNTRACK(self);  | 
132  | 228  |     if (PyAsyncGen_CheckExact(gen)) { | 
133  |  |         /* We have to handle this case for asynchronous generators  | 
134  |  |            right here, because this code has to be between UNTRACK  | 
135  |  |            and GC_Del. */  | 
136  | 15  |         Py_CLEAR(((PyAsyncGenObject*)gen)->ag_finalizer);  | 
137  | 15  |     }  | 
138  | 228  |     if (gen->gi_frame != NULL) { | 
139  | 0  |         gen->gi_frame->f_gen = NULL;  | 
140  | 0  |         Py_CLEAR(gen->gi_frame);  | 
141  | 0  |     }  | 
142  | 228  |     if (((PyCodeObject *)gen->gi_code)->co_flags & CO_COROUTINE) { | 
143  | 15  |         Py_CLEAR(((PyCoroObject *)gen)->cr_origin);  | 
144  | 15  |     }  | 
145  | 228  |     Py_CLEAR(gen->gi_code);  | 
146  | 228  |     Py_CLEAR(gen->gi_name);  | 
147  | 228  |     Py_CLEAR(gen->gi_qualname);  | 
148  | 228  |     exc_state_clear(&gen->gi_exc_state);  | 
149  | 228  |     PyObject_GC_Del(gen);  | 
150  | 228  | }  | 
151  |  |  | 
152  |  | static PyObject *  | 
153  |  | gen_send_ex(PyGenObject *gen, PyObject *arg, int exc, int closing)  | 
154  | 1.04k  | { | 
155  | 1.04k  |     PyThreadState *tstate = _PyThreadState_GET();  | 
156  | 1.04k  |     PyFrameObject *f = gen->gi_frame;  | 
157  | 1.04k  |     PyObject *result;  | 
158  |  |  | 
159  | 1.04k  |     if (gen->gi_running) { | 
160  | 0  |         const char *msg = "generator already executing";  | 
161  | 0  |         if (PyCoro_CheckExact(gen)) { | 
162  | 0  |             msg = "coroutine already executing";  | 
163  | 0  |         }  | 
164  | 0  |         else if (PyAsyncGen_CheckExact(gen)) { | 
165  | 0  |             msg = "async generator already executing";  | 
166  | 0  |         }  | 
167  | 0  |         PyErr_SetString(PyExc_ValueError, msg);  | 
168  | 0  |         return NULL;  | 
169  | 0  |     }  | 
170  | 1.04k  |     if (f == NULL || f->f_stacktop == NULL) { | 
171  | 0  |         if (PyCoro_CheckExact(gen) && !closing) { | 
172  |  |             /* `gen` is an exhausted coroutine: raise an error,  | 
173  |  |                except when called from gen_close(), which should  | 
174  |  |                always be a silent method. */  | 
175  | 0  |             PyErr_SetString(  | 
176  | 0  |                 PyExc_RuntimeError,  | 
177  | 0  |                 "cannot reuse already awaited coroutine");  | 
178  | 0  |         }  | 
179  | 0  |         else if (arg && !exc) { | 
180  |  |             /* `gen` is an exhausted generator:  | 
181  |  |                only set exception if called from send(). */  | 
182  | 0  |             if (PyAsyncGen_CheckExact(gen)) { | 
183  | 0  |                 PyErr_SetNone(PyExc_StopAsyncIteration);  | 
184  | 0  |             }  | 
185  | 0  |             else { | 
186  | 0  |                 PyErr_SetNone(PyExc_StopIteration);  | 
187  | 0  |             }  | 
188  | 0  |         }  | 
189  | 0  |         return NULL;  | 
190  | 0  |     }  | 
191  |  |  | 
192  | 1.04k  |     if (f->f_lasti == -1) { | 
193  | 228  |         if (arg && arg != Py_None) { | 
194  | 0  |             const char *msg = "can't send non-None value to a "  | 
195  | 0  |                               "just-started generator";  | 
196  | 0  |             if (PyCoro_CheckExact(gen)) { | 
197  | 0  |                 msg = NON_INIT_CORO_MSG;  | 
198  | 0  |             }  | 
199  | 0  |             else if (PyAsyncGen_CheckExact(gen)) { | 
200  | 0  |                 msg = "can't send non-None value to a "  | 
201  | 0  |                       "just-started async generator";  | 
202  | 0  |             }  | 
203  | 0  |             PyErr_SetString(PyExc_TypeError, msg);  | 
204  | 0  |             return NULL;  | 
205  | 0  |         }  | 
206  | 820  |     } else { | 
207  |  |         /* Push arg onto the frame's value stack */  | 
208  | 820  |         result = arg ? arg : Py_None;  | 
209  | 820  |         Py_INCREF(result);  | 
210  | 820  |         *(f->f_stacktop++) = result;  | 
211  | 820  |     }  | 
212  |  |  | 
213  |  |     /* Generators always return to their most recent caller, not  | 
214  |  |      * necessarily their creator. */  | 
215  | 1.04k  |     Py_XINCREF(tstate->frame);  | 
216  | 1.04k  |     assert(f->f_back == NULL);  | 
217  | 1.04k  |     f->f_back = tstate->frame;  | 
218  |  |  | 
219  | 1.04k  |     gen->gi_running = 1;  | 
220  | 1.04k  |     gen->gi_exc_state.previous_item = tstate->exc_info;  | 
221  | 1.04k  |     tstate->exc_info = &gen->gi_exc_state;  | 
222  | 1.04k  |     result = PyEval_EvalFrameEx(f, exc);  | 
223  | 1.04k  |     tstate->exc_info = gen->gi_exc_state.previous_item;  | 
224  | 1.04k  |     gen->gi_exc_state.previous_item = NULL;  | 
225  | 1.04k  |     gen->gi_running = 0;  | 
226  |  |  | 
227  |  |     /* Don't keep the reference to f_back any longer than necessary.  It  | 
228  |  |      * may keep a chain of frames alive or it could create a reference  | 
229  |  |      * cycle. */  | 
230  | 1.04k  |     assert(f->f_back == tstate->frame);  | 
231  | 1.04k  |     Py_CLEAR(f->f_back);  | 
232  |  |  | 
233  |  |     /* If the generator just returned (as opposed to yielding), signal  | 
234  |  |      * that the generator is exhausted. */  | 
235  | 1.04k  |     if (result && f->f_stacktop == NULL) { | 
236  | 180  |         if (result == Py_None) { | 
237  |  |             /* Delay exception instantiation if we can */  | 
238  | 180  |             if (PyAsyncGen_CheckExact(gen)) { | 
239  | 0  |                 PyErr_SetNone(PyExc_StopAsyncIteration);  | 
240  | 0  |             }  | 
241  | 180  |             else { | 
242  | 180  |                 PyErr_SetNone(PyExc_StopIteration);  | 
243  | 180  |             }  | 
244  | 180  |         }  | 
245  | 0  |         else { | 
246  |  |             /* Async generators cannot return anything but None */  | 
247  | 0  |             assert(!PyAsyncGen_CheckExact(gen));  | 
248  | 0  |             _PyGen_SetStopIterationValue(result);  | 
249  | 0  |         }  | 
250  | 180  |         Py_CLEAR(result);  | 
251  | 180  |     }  | 
252  | 868  |     else if (!result && PyErr_ExceptionMatches(PyExc_StopIteration)) { | 
253  | 0  |         const char *msg = "generator raised StopIteration";  | 
254  | 0  |         if (PyCoro_CheckExact(gen)) { | 
255  | 0  |             msg = "coroutine raised StopIteration";  | 
256  | 0  |         }  | 
257  | 0  |         else if PyAsyncGen_CheckExact(gen) { | 
258  | 0  |             msg = "async generator raised StopIteration";  | 
259  | 0  |         }  | 
260  | 0  |         _PyErr_FormatFromCause(PyExc_RuntimeError, "%s", msg);  | 
261  |  | 
  | 
262  | 0  |     }  | 
263  | 868  |     else if (!result && PyAsyncGen_CheckExact(gen) &&  | 
264  | 15  |              PyErr_ExceptionMatches(PyExc_StopAsyncIteration))  | 
265  | 0  |     { | 
266  |  |         /* code in `gen` raised a StopAsyncIteration error:  | 
267  |  |            raise a RuntimeError.  | 
268  |  |         */  | 
269  | 0  |         const char *msg = "async generator raised StopAsyncIteration";  | 
270  | 0  |         _PyErr_FormatFromCause(PyExc_RuntimeError, "%s", msg);  | 
271  | 0  |     }  | 
272  |  |  | 
273  | 1.04k  |     if (!result || f->f_stacktop == NULL) { | 
274  |  |         /* generator can't be rerun, so release the frame */  | 
275  |  |         /* first clean reference cycle through stored exception traceback */  | 
276  | 228  |         exc_state_clear(&gen->gi_exc_state);  | 
277  | 228  |         gen->gi_frame->f_gen = NULL;  | 
278  | 228  |         gen->gi_frame = NULL;  | 
279  | 228  |         Py_DECREF(f);  | 
280  | 228  |     }  | 
281  |  |  | 
282  | 1.04k  |     return result;  | 
283  | 1.04k  | }  | 
284  |  |  | 
285  |  | PyDoc_STRVAR(send_doc,  | 
286  |  | "send(arg) -> send 'arg' into generator,\n\  | 
287  |  | return next yielded value or raise StopIteration.");  | 
288  |  |  | 
289  |  | PyObject *  | 
290  |  | _PyGen_Send(PyGenObject *gen, PyObject *arg)  | 
291  | 28  | { | 
292  | 28  |     return gen_send_ex(gen, arg, 0, 0);  | 
293  | 28  | }  | 
294  |  |  | 
295  |  | PyDoc_STRVAR(close_doc,  | 
296  |  | "close() -> raise GeneratorExit inside generator.");  | 
297  |  |  | 
298  |  | /*  | 
299  |  |  *   This helper function is used by gen_close and gen_throw to  | 
300  |  |  *   close a subiterator being delegated to by yield-from.  | 
301  |  |  */  | 
302  |  |  | 
303  |  | static int  | 
304  |  | gen_close_iter(PyObject *yf)  | 
305  | 0  | { | 
306  | 0  |     PyObject *retval = NULL;  | 
307  | 0  |     _Py_IDENTIFIER(close);  | 
308  |  | 
  | 
309  | 0  |     if (PyGen_CheckExact(yf) || PyCoro_CheckExact(yf)) { | 
310  | 0  |         retval = gen_close((PyGenObject *)yf, NULL);  | 
311  | 0  |         if (retval == NULL)  | 
312  | 0  |             return -1;  | 
313  | 0  |     }  | 
314  | 0  |     else { | 
315  | 0  |         PyObject *meth;  | 
316  | 0  |         if (_PyObject_LookupAttrId(yf, &PyId_close, &meth) < 0) { | 
317  | 0  |             PyErr_WriteUnraisable(yf);  | 
318  | 0  |         }  | 
319  | 0  |         if (meth) { | 
320  | 0  |             retval = _PyObject_CallNoArg(meth);  | 
321  | 0  |             Py_DECREF(meth);  | 
322  | 0  |             if (retval == NULL)  | 
323  | 0  |                 return -1;  | 
324  | 0  |         }  | 
325  | 0  |     }  | 
326  | 0  |     Py_XDECREF(retval);  | 
327  | 0  |     return 0;  | 
328  | 0  | }  | 
329  |  |  | 
330  |  | PyObject *  | 
331  |  | _PyGen_yf(PyGenObject *gen)  | 
332  | 48  | { | 
333  | 48  |     PyObject *yf = NULL;  | 
334  | 48  |     PyFrameObject *f = gen->gi_frame;  | 
335  |  |  | 
336  | 48  |     if (f && f->f_stacktop) { | 
337  | 48  |         PyObject *bytecode = f->f_code->co_code;  | 
338  | 48  |         unsigned char *code = (unsigned char *)PyBytes_AS_STRING(bytecode);  | 
339  |  |  | 
340  | 48  |         if (f->f_lasti < 0) { | 
341  |  |             /* Return immediately if the frame didn't start yet. YIELD_FROM  | 
342  |  |                always come after LOAD_CONST: a code object should not start  | 
343  |  |                with YIELD_FROM */  | 
344  | 45  |             assert(code[0] != YIELD_FROM);  | 
345  | 45  |             return NULL;  | 
346  | 45  |         }  | 
347  |  |  | 
348  | 3  |         if (code[f->f_lasti + sizeof(_Py_CODEUNIT)] != YIELD_FROM)  | 
349  | 3  |             return NULL;  | 
350  | 0  |         yf = f->f_stacktop[-1];  | 
351  | 0  |         Py_INCREF(yf);  | 
352  | 0  |     }  | 
353  |  |  | 
354  | 0  |     return yf;  | 
355  | 48  | }  | 
356  |  |  | 
357  |  | static PyObject *  | 
358  |  | gen_close(PyGenObject *gen, PyObject *args)  | 
359  | 48  | { | 
360  | 48  |     PyObject *retval;  | 
361  | 48  |     PyObject *yf = _PyGen_yf(gen);  | 
362  | 48  |     int err = 0;  | 
363  |  |  | 
364  | 48  |     if (yf) { | 
365  | 0  |         gen->gi_running = 1;  | 
366  | 0  |         err = gen_close_iter(yf);  | 
367  | 0  |         gen->gi_running = 0;  | 
368  | 0  |         Py_DECREF(yf);  | 
369  | 0  |     }  | 
370  | 48  |     if (err == 0)  | 
371  | 48  |         PyErr_SetNone(PyExc_GeneratorExit);  | 
372  | 48  |     retval = gen_send_ex(gen, Py_None, 1, 1);  | 
373  | 48  |     if (retval) { | 
374  | 0  |         const char *msg = "generator ignored GeneratorExit";  | 
375  | 0  |         if (PyCoro_CheckExact(gen)) { | 
376  | 0  |             msg = "coroutine ignored GeneratorExit";  | 
377  | 0  |         } else if (PyAsyncGen_CheckExact(gen)) { | 
378  | 0  |             msg = ASYNC_GEN_IGNORED_EXIT_MSG;  | 
379  | 0  |         }  | 
380  | 0  |         Py_DECREF(retval);  | 
381  | 0  |         PyErr_SetString(PyExc_RuntimeError, msg);  | 
382  | 0  |         return NULL;  | 
383  | 0  |     }  | 
384  | 48  |     if (PyErr_ExceptionMatches(PyExc_StopIteration)  | 
385  | 48  |         || PyErr_ExceptionMatches(PyExc_GeneratorExit)) { | 
386  | 48  |         PyErr_Clear();          /* ignore these errors */  | 
387  | 48  |         Py_RETURN_NONE;  | 
388  | 48  |     }  | 
389  | 0  |     return NULL;  | 
390  | 48  | }  | 
391  |  |  | 
392  |  |  | 
393  |  | PyDoc_STRVAR(throw_doc,  | 
394  |  | "throw(typ[,val[,tb]]) -> raise exception in generator,\n\  | 
395  |  | return next yielded value or raise StopIteration.");  | 
396  |  |  | 
397  |  | static PyObject *  | 
398  |  | _gen_throw(PyGenObject *gen, int close_on_genexit,  | 
399  |  |            PyObject *typ, PyObject *val, PyObject *tb)  | 
400  | 0  | { | 
401  | 0  |     PyObject *yf = _PyGen_yf(gen);  | 
402  | 0  |     _Py_IDENTIFIER(throw);  | 
403  |  | 
  | 
404  | 0  |     if (yf) { | 
405  | 0  |         PyObject *ret;  | 
406  | 0  |         int err;  | 
407  | 0  |         if (PyErr_GivenExceptionMatches(typ, PyExc_GeneratorExit) &&  | 
408  | 0  |             close_on_genexit  | 
409  | 0  |         ) { | 
410  |  |             /* Asynchronous generators *should not* be closed right away.  | 
411  |  |                We have to allow some awaits to work it through, hence the  | 
412  |  |                `close_on_genexit` parameter here.  | 
413  |  |             */  | 
414  | 0  |             gen->gi_running = 1;  | 
415  | 0  |             err = gen_close_iter(yf);  | 
416  | 0  |             gen->gi_running = 0;  | 
417  | 0  |             Py_DECREF(yf);  | 
418  | 0  |             if (err < 0)  | 
419  | 0  |                 return gen_send_ex(gen, Py_None, 1, 0);  | 
420  | 0  |             goto throw_here;  | 
421  | 0  |         }  | 
422  | 0  |         if (PyGen_CheckExact(yf) || PyCoro_CheckExact(yf)) { | 
423  |  |             /* `yf` is a generator or a coroutine. */  | 
424  | 0  |             gen->gi_running = 1;  | 
425  |  |             /* Close the generator that we are currently iterating with  | 
426  |  |                'yield from' or awaiting on with 'await'. */  | 
427  | 0  |             ret = _gen_throw((PyGenObject *)yf, close_on_genexit,  | 
428  | 0  |                              typ, val, tb);  | 
429  | 0  |             gen->gi_running = 0;  | 
430  | 0  |         } else { | 
431  |  |             /* `yf` is an iterator or a coroutine-like object. */  | 
432  | 0  |             PyObject *meth;  | 
433  | 0  |             if (_PyObject_LookupAttrId(yf, &PyId_throw, &meth) < 0) { | 
434  | 0  |                 Py_DECREF(yf);  | 
435  | 0  |                 return NULL;  | 
436  | 0  |             }  | 
437  | 0  |             if (meth == NULL) { | 
438  | 0  |                 Py_DECREF(yf);  | 
439  | 0  |                 goto throw_here;  | 
440  | 0  |             }  | 
441  | 0  |             gen->gi_running = 1;  | 
442  | 0  |             ret = PyObject_CallFunctionObjArgs(meth, typ, val, tb, NULL);  | 
443  | 0  |             gen->gi_running = 0;  | 
444  | 0  |             Py_DECREF(meth);  | 
445  | 0  |         }  | 
446  | 0  |         Py_DECREF(yf);  | 
447  | 0  |         if (!ret) { | 
448  | 0  |             PyObject *val;  | 
449  |  |             /* Pop subiterator from stack */  | 
450  | 0  |             ret = *(--gen->gi_frame->f_stacktop);  | 
451  | 0  |             assert(ret == yf);  | 
452  | 0  |             Py_DECREF(ret);  | 
453  |  |             /* Termination repetition of YIELD_FROM */  | 
454  | 0  |             assert(gen->gi_frame->f_lasti >= 0);  | 
455  | 0  |             gen->gi_frame->f_lasti += sizeof(_Py_CODEUNIT);  | 
456  | 0  |             if (_PyGen_FetchStopIterationValue(&val) == 0) { | 
457  | 0  |                 ret = gen_send_ex(gen, val, 0, 0);  | 
458  | 0  |                 Py_DECREF(val);  | 
459  | 0  |             } else { | 
460  | 0  |                 ret = gen_send_ex(gen, Py_None, 1, 0);  | 
461  | 0  |             }  | 
462  | 0  |         }  | 
463  | 0  |         return ret;  | 
464  | 0  |     }  | 
465  |  |  | 
466  | 0  | throw_here:  | 
467  |  |     /* First, check the traceback argument, replacing None with  | 
468  |  |        NULL. */  | 
469  | 0  |     if (tb == Py_None) { | 
470  | 0  |         tb = NULL;  | 
471  | 0  |     }  | 
472  | 0  |     else if (tb != NULL && !PyTraceBack_Check(tb)) { | 
473  | 0  |         PyErr_SetString(PyExc_TypeError,  | 
474  | 0  |             "throw() third argument must be a traceback object");  | 
475  | 0  |         return NULL;  | 
476  | 0  |     }  | 
477  |  |  | 
478  | 0  |     Py_INCREF(typ);  | 
479  | 0  |     Py_XINCREF(val);  | 
480  | 0  |     Py_XINCREF(tb);  | 
481  |  | 
  | 
482  | 0  |     if (PyExceptionClass_Check(typ))  | 
483  | 0  |         PyErr_NormalizeException(&typ, &val, &tb);  | 
484  |  |  | 
485  | 0  |     else if (PyExceptionInstance_Check(typ)) { | 
486  |  |         /* Raising an instance.  The value should be a dummy. */  | 
487  | 0  |         if (val && val != Py_None) { | 
488  | 0  |             PyErr_SetString(PyExc_TypeError,  | 
489  | 0  |               "instance exception may not have a separate value");  | 
490  | 0  |             goto failed_throw;  | 
491  | 0  |         }  | 
492  | 0  |         else { | 
493  |  |             /* Normalize to raise <class>, <instance> */  | 
494  | 0  |             Py_XDECREF(val);  | 
495  | 0  |             val = typ;  | 
496  | 0  |             typ = PyExceptionInstance_Class(typ);  | 
497  | 0  |             Py_INCREF(typ);  | 
498  |  | 
  | 
499  | 0  |             if (tb == NULL)  | 
500  |  |                 /* Returns NULL if there's no traceback */  | 
501  | 0  |                 tb = PyException_GetTraceback(val);  | 
502  | 0  |         }  | 
503  | 0  |     }  | 
504  | 0  |     else { | 
505  |  |         /* Not something you can raise.  throw() fails. */  | 
506  | 0  |         PyErr_Format(PyExc_TypeError,  | 
507  | 0  |                      "exceptions must be classes or instances "  | 
508  | 0  |                      "deriving from BaseException, not %s",  | 
509  | 0  |                      Py_TYPE(typ)->tp_name);  | 
510  | 0  |             goto failed_throw;  | 
511  | 0  |     }  | 
512  |  |  | 
513  | 0  |     PyErr_Restore(typ, val, tb);  | 
514  | 0  |     return gen_send_ex(gen, Py_None, 1, 0);  | 
515  |  |  | 
516  | 0  | failed_throw:  | 
517  |  |     /* Didn't use our arguments, so restore their original refcounts */  | 
518  | 0  |     Py_DECREF(typ);  | 
519  | 0  |     Py_XDECREF(val);  | 
520  | 0  |     Py_XDECREF(tb);  | 
521  | 0  |     return NULL;  | 
522  | 0  | }  | 
523  |  |  | 
524  |  |  | 
525  |  | static PyObject *  | 
526  |  | gen_throw(PyGenObject *gen, PyObject *args)  | 
527  | 0  | { | 
528  | 0  |     PyObject *typ;  | 
529  | 0  |     PyObject *tb = NULL;  | 
530  | 0  |     PyObject *val = NULL;  | 
531  |  | 
  | 
532  | 0  |     if (!PyArg_UnpackTuple(args, "throw", 1, 3, &typ, &val, &tb)) { | 
533  | 0  |         return NULL;  | 
534  | 0  |     }  | 
535  |  |  | 
536  | 0  |     return _gen_throw(gen, 1, typ, val, tb);  | 
537  | 0  | }  | 
538  |  |  | 
539  |  |  | 
540  |  | static PyObject *  | 
541  |  | gen_iternext(PyGenObject *gen)  | 
542  | 972  | { | 
543  | 972  |     return gen_send_ex(gen, NULL, 0, 0);  | 
544  | 972  | }  | 
545  |  |  | 
546  |  | /*  | 
547  |  |  * Set StopIteration with specified value.  Value can be arbitrary object  | 
548  |  |  * or NULL.  | 
549  |  |  *  | 
550  |  |  * Returns 0 if StopIteration is set and -1 if any other exception is set.  | 
551  |  |  */  | 
552  |  | int  | 
553  |  | _PyGen_SetStopIterationValue(PyObject *value)  | 
554  | 0  | { | 
555  | 0  |     PyObject *e;  | 
556  |  | 
  | 
557  | 0  |     if (value == NULL ||  | 
558  | 0  |         (!PyTuple_Check(value) && !PyExceptionInstance_Check(value)))  | 
559  | 0  |     { | 
560  |  |         /* Delay exception instantiation if we can */  | 
561  | 0  |         PyErr_SetObject(PyExc_StopIteration, value);  | 
562  | 0  |         return 0;  | 
563  | 0  |     }  | 
564  |  |     /* Construct an exception instance manually with  | 
565  |  |      * PyObject_CallFunctionObjArgs and pass it to PyErr_SetObject.  | 
566  |  |      *  | 
567  |  |      * We do this to handle a situation when "value" is a tuple, in which  | 
568  |  |      * case PyErr_SetObject would set the value of StopIteration to  | 
569  |  |      * the first element of the tuple.  | 
570  |  |      *  | 
571  |  |      * (See PyErr_SetObject/_PyErr_CreateException code for details.)  | 
572  |  |      */  | 
573  | 0  |     e = PyObject_CallFunctionObjArgs(PyExc_StopIteration, value, NULL);  | 
574  | 0  |     if (e == NULL) { | 
575  | 0  |         return -1;  | 
576  | 0  |     }  | 
577  | 0  |     PyErr_SetObject(PyExc_StopIteration, e);  | 
578  | 0  |     Py_DECREF(e);  | 
579  | 0  |     return 0;  | 
580  | 0  | }  | 
581  |  |  | 
582  |  | /*  | 
583  |  |  *   If StopIteration exception is set, fetches its 'value'  | 
584  |  |  *   attribute if any, otherwise sets pvalue to None.  | 
585  |  |  *  | 
586  |  |  *   Returns 0 if no exception or StopIteration is set.  | 
587  |  |  *   If any other exception is set, returns -1 and leaves  | 
588  |  |  *   pvalue unchanged.  | 
589  |  |  */  | 
590  |  |  | 
591  |  | int  | 
592  |  | _PyGen_FetchStopIterationValue(PyObject **pvalue)  | 
593  | 28  | { | 
594  | 28  |     PyObject *et, *ev, *tb;  | 
595  | 28  |     PyObject *value = NULL;  | 
596  |  |  | 
597  | 28  |     if (PyErr_ExceptionMatches(PyExc_StopIteration)) { | 
598  | 14  |         PyErr_Fetch(&et, &ev, &tb);  | 
599  | 14  |         if (ev) { | 
600  |  |             /* exception will usually be normalised already */  | 
601  | 14  |             if (PyObject_TypeCheck(ev, (PyTypeObject *) et)) { | 
602  | 14  |                 value = ((PyStopIterationObject *)ev)->value;  | 
603  | 14  |                 Py_INCREF(value);  | 
604  | 14  |                 Py_DECREF(ev);  | 
605  | 14  |             } else if (et == PyExc_StopIteration && !PyTuple_Check(ev)) { | 
606  |  |                 /* Avoid normalisation and take ev as value.  | 
607  |  |                  *  | 
608  |  |                  * Normalization is required if the value is a tuple, in  | 
609  |  |                  * that case the value of StopIteration would be set to  | 
610  |  |                  * the first element of the tuple.  | 
611  |  |                  *  | 
612  |  |                  * (See _PyErr_CreateException code for details.)  | 
613  |  |                  */  | 
614  | 0  |                 value = ev;  | 
615  | 0  |             } else { | 
616  |  |                 /* normalisation required */  | 
617  | 0  |                 PyErr_NormalizeException(&et, &ev, &tb);  | 
618  | 0  |                 if (!PyObject_TypeCheck(ev, (PyTypeObject *)PyExc_StopIteration)) { | 
619  | 0  |                     PyErr_Restore(et, ev, tb);  | 
620  | 0  |                     return -1;  | 
621  | 0  |                 }  | 
622  | 0  |                 value = ((PyStopIterationObject *)ev)->value;  | 
623  | 0  |                 Py_INCREF(value);  | 
624  | 0  |                 Py_DECREF(ev);  | 
625  | 0  |             }  | 
626  | 14  |         }  | 
627  | 14  |         Py_XDECREF(et);  | 
628  | 14  |         Py_XDECREF(tb);  | 
629  | 14  |     } else if (PyErr_Occurred()) { | 
630  | 0  |         return -1;  | 
631  | 0  |     }  | 
632  | 28  |     if (value == NULL) { | 
633  | 14  |         value = Py_None;  | 
634  | 14  |         Py_INCREF(value);  | 
635  | 14  |     }  | 
636  | 28  |     *pvalue = value;  | 
637  | 28  |     return 0;  | 
638  | 28  | }  | 
639  |  |  | 
640  |  | static PyObject *  | 
641  |  | gen_repr(PyGenObject *gen)  | 
642  | 0  | { | 
643  | 0  |     return PyUnicode_FromFormat("<generator object %S at %p>", | 
644  | 0  |                                 gen->gi_qualname, gen);  | 
645  | 0  | }  | 
646  |  |  | 
647  |  | static PyObject *  | 
648  |  | gen_get_name(PyGenObject *op, void *Py_UNUSED(ignored))  | 
649  | 0  | { | 
650  | 0  |     Py_INCREF(op->gi_name);  | 
651  | 0  |     return op->gi_name;  | 
652  | 0  | }  | 
653  |  |  | 
654  |  | static int  | 
655  |  | gen_set_name(PyGenObject *op, PyObject *value, void *Py_UNUSED(ignored))  | 
656  | 0  | { | 
657  |  |     /* Not legal to del gen.gi_name or to set it to anything  | 
658  |  |      * other than a string object. */  | 
659  | 0  |     if (value == NULL || !PyUnicode_Check(value)) { | 
660  | 0  |         PyErr_SetString(PyExc_TypeError,  | 
661  | 0  |                         "__name__ must be set to a string object");  | 
662  | 0  |         return -1;  | 
663  | 0  |     }  | 
664  | 0  |     Py_INCREF(value);  | 
665  | 0  |     Py_XSETREF(op->gi_name, value);  | 
666  | 0  |     return 0;  | 
667  | 0  | }  | 
668  |  |  | 
669  |  | static PyObject *  | 
670  |  | gen_get_qualname(PyGenObject *op, void *Py_UNUSED(ignored))  | 
671  | 0  | { | 
672  | 0  |     Py_INCREF(op->gi_qualname);  | 
673  | 0  |     return op->gi_qualname;  | 
674  | 0  | }  | 
675  |  |  | 
676  |  | static int  | 
677  |  | gen_set_qualname(PyGenObject *op, PyObject *value, void *Py_UNUSED(ignored))  | 
678  | 0  | { | 
679  |  |     /* Not legal to del gen.__qualname__ or to set it to anything  | 
680  |  |      * other than a string object. */  | 
681  | 0  |     if (value == NULL || !PyUnicode_Check(value)) { | 
682  | 0  |         PyErr_SetString(PyExc_TypeError,  | 
683  | 0  |                         "__qualname__ must be set to a string object");  | 
684  | 0  |         return -1;  | 
685  | 0  |     }  | 
686  | 0  |     Py_INCREF(value);  | 
687  | 0  |     Py_XSETREF(op->gi_qualname, value);  | 
688  | 0  |     return 0;  | 
689  | 0  | }  | 
690  |  |  | 
691  |  | static PyObject *  | 
692  |  | gen_getyieldfrom(PyGenObject *gen, void *Py_UNUSED(ignored))  | 
693  | 0  | { | 
694  | 0  |     PyObject *yf = _PyGen_yf(gen);  | 
695  | 0  |     if (yf == NULL)  | 
696  | 0  |         Py_RETURN_NONE;  | 
697  | 0  |     return yf;  | 
698  | 0  | }  | 
699  |  |  | 
700  |  | static PyGetSetDef gen_getsetlist[] = { | 
701  |  |     {"__name__", (getter)gen_get_name, (setter)gen_set_name, | 
702  |  |      PyDoc_STR("name of the generator")}, | 
703  |  |     {"__qualname__", (getter)gen_get_qualname, (setter)gen_set_qualname, | 
704  |  |      PyDoc_STR("qualified name of the generator")}, | 
705  |  |     {"gi_yieldfrom", (getter)gen_getyieldfrom, NULL, | 
706  |  |      PyDoc_STR("object being iterated by yield from, or None")}, | 
707  |  |     {NULL} /* Sentinel */ | 
708  |  | };  | 
709  |  |  | 
710  |  | static PyMemberDef gen_memberlist[] = { | 
711  |  |     {"gi_frame",     T_OBJECT, offsetof(PyGenObject, gi_frame),    READONLY}, | 
712  |  |     {"gi_running",   T_BOOL,   offsetof(PyGenObject, gi_running),  READONLY}, | 
713  |  |     {"gi_code",      T_OBJECT, offsetof(PyGenObject, gi_code),     READONLY}, | 
714  |  |     {NULL}      /* Sentinel */ | 
715  |  | };  | 
716  |  |  | 
717  |  | static PyMethodDef gen_methods[] = { | 
718  |  |     {"send",(PyCFunction)_PyGen_Send, METH_O, send_doc}, | 
719  |  |     {"throw",(PyCFunction)gen_throw, METH_VARARGS, throw_doc}, | 
720  |  |     {"close",(PyCFunction)gen_close, METH_NOARGS, close_doc}, | 
721  |  |     {NULL, NULL}        /* Sentinel */ | 
722  |  | };  | 
723  |  |  | 
724  |  | PyTypeObject PyGen_Type = { | 
725  |  |     PyVarObject_HEAD_INIT(&PyType_Type, 0)  | 
726  |  |     "generator",                                /* tp_name */  | 
727  |  |     sizeof(PyGenObject),                        /* tp_basicsize */  | 
728  |  |     0,                                          /* tp_itemsize */  | 
729  |  |     /* methods */  | 
730  |  |     (destructor)gen_dealloc,                    /* tp_dealloc */  | 
731  |  |     0,                                          /* tp_vectorcall_offset */  | 
732  |  |     0,                                          /* tp_getattr */  | 
733  |  |     0,                                          /* tp_setattr */  | 
734  |  |     0,                                          /* tp_as_async */  | 
735  |  |     (reprfunc)gen_repr,                         /* tp_repr */  | 
736  |  |     0,                                          /* tp_as_number */  | 
737  |  |     0,                                          /* tp_as_sequence */  | 
738  |  |     0,                                          /* tp_as_mapping */  | 
739  |  |     0,                                          /* tp_hash */  | 
740  |  |     0,                                          /* tp_call */  | 
741  |  |     0,                                          /* tp_str */  | 
742  |  |     PyObject_GenericGetAttr,                    /* tp_getattro */  | 
743  |  |     0,                                          /* tp_setattro */  | 
744  |  |     0,                                          /* tp_as_buffer */  | 
745  |  |     Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC,    /* tp_flags */  | 
746  |  |     0,                                          /* tp_doc */  | 
747  |  |     (traverseproc)gen_traverse,                 /* tp_traverse */  | 
748  |  |     0,                                          /* tp_clear */  | 
749  |  |     0,                                          /* tp_richcompare */  | 
750  |  |     offsetof(PyGenObject, gi_weakreflist),      /* tp_weaklistoffset */  | 
751  |  |     PyObject_SelfIter,                          /* tp_iter */  | 
752  |  |     (iternextfunc)gen_iternext,                 /* tp_iternext */  | 
753  |  |     gen_methods,                                /* tp_methods */  | 
754  |  |     gen_memberlist,                             /* tp_members */  | 
755  |  |     gen_getsetlist,                             /* tp_getset */  | 
756  |  |     0,                                          /* tp_base */  | 
757  |  |     0,                                          /* tp_dict */  | 
758  |  |  | 
759  |  |     0,                                          /* tp_descr_get */  | 
760  |  |     0,                                          /* tp_descr_set */  | 
761  |  |     0,                                          /* tp_dictoffset */  | 
762  |  |     0,                                          /* tp_init */  | 
763  |  |     0,                                          /* tp_alloc */  | 
764  |  |     0,                                          /* tp_new */  | 
765  |  |     0,                                          /* tp_free */  | 
766  |  |     0,                                          /* tp_is_gc */  | 
767  |  |     0,                                          /* tp_bases */  | 
768  |  |     0,                                          /* tp_mro */  | 
769  |  |     0,                                          /* tp_cache */  | 
770  |  |     0,                                          /* tp_subclasses */  | 
771  |  |     0,                                          /* tp_weaklist */  | 
772  |  |     0,                                          /* tp_del */  | 
773  |  |     0,                                          /* tp_version_tag */  | 
774  |  |     _PyGen_Finalize,                            /* tp_finalize */  | 
775  |  | };  | 
776  |  |  | 
777  |  | static PyObject *  | 
778  |  | gen_new_with_qualname(PyTypeObject *type, PyFrameObject *f,  | 
779  |  |                       PyObject *name, PyObject *qualname)  | 
780  | 228  | { | 
781  | 228  |     PyGenObject *gen = PyObject_GC_New(PyGenObject, type);  | 
782  | 228  |     if (gen == NULL) { | 
783  | 0  |         Py_DECREF(f);  | 
784  | 0  |         return NULL;  | 
785  | 0  |     }  | 
786  | 228  |     gen->gi_frame = f;  | 
787  | 228  |     f->f_gen = (PyObject *) gen;  | 
788  | 228  |     Py_INCREF(f->f_code);  | 
789  | 228  |     gen->gi_code = (PyObject *)(f->f_code);  | 
790  | 228  |     gen->gi_running = 0;  | 
791  | 228  |     gen->gi_weakreflist = NULL;  | 
792  | 228  |     gen->gi_exc_state.exc_type = NULL;  | 
793  | 228  |     gen->gi_exc_state.exc_value = NULL;  | 
794  | 228  |     gen->gi_exc_state.exc_traceback = NULL;  | 
795  | 228  |     gen->gi_exc_state.previous_item = NULL;  | 
796  | 228  |     if (name != NULL)  | 
797  | 228  |         gen->gi_name = name;  | 
798  | 0  |     else  | 
799  | 0  |         gen->gi_name = ((PyCodeObject *)gen->gi_code)->co_name;  | 
800  | 228  |     Py_INCREF(gen->gi_name);  | 
801  | 228  |     if (qualname != NULL)  | 
802  | 228  |         gen->gi_qualname = qualname;  | 
803  | 0  |     else  | 
804  | 0  |         gen->gi_qualname = gen->gi_name;  | 
805  | 228  |     Py_INCREF(gen->gi_qualname);  | 
806  | 228  |     _PyObject_GC_TRACK(gen);  | 
807  | 228  |     return (PyObject *)gen;  | 
808  | 228  | }  | 
809  |  |  | 
810  |  | PyObject *  | 
811  |  | PyGen_NewWithQualName(PyFrameObject *f, PyObject *name, PyObject *qualname)  | 
812  | 198  | { | 
813  | 198  |     return gen_new_with_qualname(&PyGen_Type, f, name, qualname);  | 
814  | 198  | }  | 
815  |  |  | 
816  |  | PyObject *  | 
817  |  | PyGen_New(PyFrameObject *f)  | 
818  | 0  | { | 
819  | 0  |     return gen_new_with_qualname(&PyGen_Type, f, NULL, NULL);  | 
820  | 0  | }  | 
821  |  |  | 
822  |  | int  | 
823  |  | PyGen_NeedsFinalizing(PyGenObject *gen)  | 
824  | 0  | { | 
825  | 0  |     PyFrameObject *f = gen->gi_frame;  | 
826  |  | 
  | 
827  | 0  |     if (f == NULL || f->f_stacktop == NULL)  | 
828  | 0  |         return 0; /* no frame or empty blockstack == no finalization */  | 
829  |  |  | 
830  |  |     /* Any (exception-handling) block type requires cleanup. */  | 
831  | 0  |     if (f->f_iblock > 0)  | 
832  | 0  |         return 1;  | 
833  |  |  | 
834  |  |     /* No blocks, it's safe to skip finalization. */  | 
835  | 0  |     return 0;  | 
836  | 0  | }  | 
837  |  |  | 
838  |  | /* Coroutine Object */  | 
839  |  |  | 
840  |  | typedef struct { | 
841  |  |     PyObject_HEAD  | 
842  |  |     PyCoroObject *cw_coroutine;  | 
843  |  | } PyCoroWrapper;  | 
844  |  |  | 
845  |  | static int  | 
846  |  | gen_is_coroutine(PyObject *o)  | 
847  | 0  | { | 
848  | 0  |     if (PyGen_CheckExact(o)) { | 
849  | 0  |         PyCodeObject *code = (PyCodeObject *)((PyGenObject*)o)->gi_code;  | 
850  | 0  |         if (code->co_flags & CO_ITERABLE_COROUTINE) { | 
851  | 0  |             return 1;  | 
852  | 0  |         }  | 
853  | 0  |     }  | 
854  | 0  |     return 0;  | 
855  | 0  | }  | 
856  |  |  | 
857  |  | /*  | 
858  |  |  *   This helper function returns an awaitable for `o`:  | 
859  |  |  *     - `o` if `o` is a coroutine-object;  | 
860  |  |  *     - `type(o)->tp_as_async->am_await(o)`  | 
861  |  |  *  | 
862  |  |  *   Raises a TypeError if it's not possible to return  | 
863  |  |  *   an awaitable and returns NULL.  | 
864  |  |  */  | 
865  |  | PyObject *  | 
866  |  | _PyCoro_GetAwaitableIter(PyObject *o)  | 
867  | 0  | { | 
868  | 0  |     unaryfunc getter = NULL;  | 
869  | 0  |     PyTypeObject *ot;  | 
870  |  | 
  | 
871  | 0  |     if (PyCoro_CheckExact(o) || gen_is_coroutine(o)) { | 
872  |  |         /* 'o' is a coroutine. */  | 
873  | 0  |         Py_INCREF(o);  | 
874  | 0  |         return o;  | 
875  | 0  |     }  | 
876  |  |  | 
877  | 0  |     ot = Py_TYPE(o);  | 
878  | 0  |     if (ot->tp_as_async != NULL) { | 
879  | 0  |         getter = ot->tp_as_async->am_await;  | 
880  | 0  |     }  | 
881  | 0  |     if (getter != NULL) { | 
882  | 0  |         PyObject *res = (*getter)(o);  | 
883  | 0  |         if (res != NULL) { | 
884  | 0  |             if (PyCoro_CheckExact(res) || gen_is_coroutine(res)) { | 
885  |  |                 /* __await__ must return an *iterator*, not  | 
886  |  |                    a coroutine or another awaitable (see PEP 492) */  | 
887  | 0  |                 PyErr_SetString(PyExc_TypeError,  | 
888  | 0  |                                 "__await__() returned a coroutine");  | 
889  | 0  |                 Py_CLEAR(res);  | 
890  | 0  |             } else if (!PyIter_Check(res)) { | 
891  | 0  |                 PyErr_Format(PyExc_TypeError,  | 
892  | 0  |                              "__await__() returned non-iterator "  | 
893  | 0  |                              "of type '%.100s'",  | 
894  | 0  |                              Py_TYPE(res)->tp_name);  | 
895  | 0  |                 Py_CLEAR(res);  | 
896  | 0  |             }  | 
897  | 0  |         }  | 
898  | 0  |         return res;  | 
899  | 0  |     }  | 
900  |  |  | 
901  | 0  |     PyErr_Format(PyExc_TypeError,  | 
902  | 0  |                  "object %.100s can't be used in 'await' expression",  | 
903  | 0  |                  ot->tp_name);  | 
904  | 0  |     return NULL;  | 
905  | 0  | }  | 
906  |  |  | 
907  |  | static PyObject *  | 
908  |  | coro_repr(PyCoroObject *coro)  | 
909  | 0  | { | 
910  | 0  |     return PyUnicode_FromFormat("<coroutine object %S at %p>", | 
911  | 0  |                                 coro->cr_qualname, coro);  | 
912  | 0  | }  | 
913  |  |  | 
914  |  | static PyObject *  | 
915  |  | coro_await(PyCoroObject *coro)  | 
916  | 0  | { | 
917  | 0  |     PyCoroWrapper *cw = PyObject_GC_New(PyCoroWrapper, &_PyCoroWrapper_Type);  | 
918  | 0  |     if (cw == NULL) { | 
919  | 0  |         return NULL;  | 
920  | 0  |     }  | 
921  | 0  |     Py_INCREF(coro);  | 
922  | 0  |     cw->cw_coroutine = coro;  | 
923  | 0  |     _PyObject_GC_TRACK(cw);  | 
924  | 0  |     return (PyObject *)cw;  | 
925  | 0  | }  | 
926  |  |  | 
927  |  | static PyObject *  | 
928  |  | coro_get_cr_await(PyCoroObject *coro, void *Py_UNUSED(ignored))  | 
929  | 0  | { | 
930  | 0  |     PyObject *yf = _PyGen_yf((PyGenObject *) coro);  | 
931  | 0  |     if (yf == NULL)  | 
932  | 0  |         Py_RETURN_NONE;  | 
933  | 0  |     return yf;  | 
934  | 0  | }  | 
935  |  |  | 
936  |  | static PyGetSetDef coro_getsetlist[] = { | 
937  |  |     {"__name__", (getter)gen_get_name, (setter)gen_set_name, | 
938  |  |      PyDoc_STR("name of the coroutine")}, | 
939  |  |     {"__qualname__", (getter)gen_get_qualname, (setter)gen_set_qualname, | 
940  |  |      PyDoc_STR("qualified name of the coroutine")}, | 
941  |  |     {"cr_await", (getter)coro_get_cr_await, NULL, | 
942  |  |      PyDoc_STR("object being awaited on, or None")}, | 
943  |  |     {NULL} /* Sentinel */ | 
944  |  | };  | 
945  |  |  | 
946  |  | static PyMemberDef coro_memberlist[] = { | 
947  |  |     {"cr_frame",     T_OBJECT, offsetof(PyCoroObject, cr_frame),    READONLY}, | 
948  |  |     {"cr_running",   T_BOOL,   offsetof(PyCoroObject, cr_running),  READONLY}, | 
949  |  |     {"cr_code",      T_OBJECT, offsetof(PyCoroObject, cr_code),     READONLY}, | 
950  |  |     {"cr_origin",    T_OBJECT, offsetof(PyCoroObject, cr_origin),   READONLY}, | 
951  |  |     {NULL}      /* Sentinel */ | 
952  |  | };  | 
953  |  |  | 
954  |  | PyDoc_STRVAR(coro_send_doc,  | 
955  |  | "send(arg) -> send 'arg' into coroutine,\n\  | 
956  |  | return next iterated value or raise StopIteration.");  | 
957  |  |  | 
958  |  | PyDoc_STRVAR(coro_throw_doc,  | 
959  |  | "throw(typ[,val[,tb]]) -> raise exception in coroutine,\n\  | 
960  |  | return next iterated value or raise StopIteration.");  | 
961  |  |  | 
962  |  | PyDoc_STRVAR(coro_close_doc,  | 
963  |  | "close() -> raise GeneratorExit inside coroutine.");  | 
964  |  |  | 
965  |  | static PyMethodDef coro_methods[] = { | 
966  |  |     {"send",(PyCFunction)_PyGen_Send, METH_O, coro_send_doc}, | 
967  |  |     {"throw",(PyCFunction)gen_throw, METH_VARARGS, coro_throw_doc}, | 
968  |  |     {"close",(PyCFunction)gen_close, METH_NOARGS, coro_close_doc}, | 
969  |  |     {NULL, NULL}        /* Sentinel */ | 
970  |  | };  | 
971  |  |  | 
972  |  | static PyAsyncMethods coro_as_async = { | 
973  |  |     (unaryfunc)coro_await,                      /* am_await */  | 
974  |  |     0,                                          /* am_aiter */  | 
975  |  |     0                                           /* am_anext */  | 
976  |  | };  | 
977  |  |  | 
978  |  | PyTypeObject PyCoro_Type = { | 
979  |  |     PyVarObject_HEAD_INIT(&PyType_Type, 0)  | 
980  |  |     "coroutine",                                /* tp_name */  | 
981  |  |     sizeof(PyCoroObject),                       /* tp_basicsize */  | 
982  |  |     0,                                          /* tp_itemsize */  | 
983  |  |     /* methods */  | 
984  |  |     (destructor)gen_dealloc,                    /* tp_dealloc */  | 
985  |  |     0,                                          /* tp_vectorcall_offset */  | 
986  |  |     0,                                          /* tp_getattr */  | 
987  |  |     0,                                          /* tp_setattr */  | 
988  |  |     &coro_as_async,                             /* tp_as_async */  | 
989  |  |     (reprfunc)coro_repr,                        /* tp_repr */  | 
990  |  |     0,                                          /* tp_as_number */  | 
991  |  |     0,                                          /* tp_as_sequence */  | 
992  |  |     0,                                          /* tp_as_mapping */  | 
993  |  |     0,                                          /* tp_hash */  | 
994  |  |     0,                                          /* tp_call */  | 
995  |  |     0,                                          /* tp_str */  | 
996  |  |     PyObject_GenericGetAttr,                    /* tp_getattro */  | 
997  |  |     0,                                          /* tp_setattro */  | 
998  |  |     0,                                          /* tp_as_buffer */  | 
999  |  |     Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC,    /* tp_flags */  | 
1000  |  |     0,                                          /* tp_doc */  | 
1001  |  |     (traverseproc)gen_traverse,                 /* tp_traverse */  | 
1002  |  |     0,                                          /* tp_clear */  | 
1003  |  |     0,                                          /* tp_richcompare */  | 
1004  |  |     offsetof(PyCoroObject, cr_weakreflist),     /* tp_weaklistoffset */  | 
1005  |  |     0,                                          /* tp_iter */  | 
1006  |  |     0,                                          /* tp_iternext */  | 
1007  |  |     coro_methods,                               /* tp_methods */  | 
1008  |  |     coro_memberlist,                            /* tp_members */  | 
1009  |  |     coro_getsetlist,                            /* tp_getset */  | 
1010  |  |     0,                                          /* tp_base */  | 
1011  |  |     0,                                          /* tp_dict */  | 
1012  |  |     0,                                          /* tp_descr_get */  | 
1013  |  |     0,                                          /* tp_descr_set */  | 
1014  |  |     0,                                          /* tp_dictoffset */  | 
1015  |  |     0,                                          /* tp_init */  | 
1016  |  |     0,                                          /* tp_alloc */  | 
1017  |  |     0,                                          /* tp_new */  | 
1018  |  |     0,                                          /* tp_free */  | 
1019  |  |     0,                                          /* tp_is_gc */  | 
1020  |  |     0,                                          /* tp_bases */  | 
1021  |  |     0,                                          /* tp_mro */  | 
1022  |  |     0,                                          /* tp_cache */  | 
1023  |  |     0,                                          /* tp_subclasses */  | 
1024  |  |     0,                                          /* tp_weaklist */  | 
1025  |  |     0,                                          /* tp_del */  | 
1026  |  |     0,                                          /* tp_version_tag */  | 
1027  |  |     _PyGen_Finalize,                            /* tp_finalize */  | 
1028  |  | };  | 
1029  |  |  | 
1030  |  | static void  | 
1031  |  | coro_wrapper_dealloc(PyCoroWrapper *cw)  | 
1032  | 0  | { | 
1033  | 0  |     _PyObject_GC_UNTRACK((PyObject *)cw);  | 
1034  | 0  |     Py_CLEAR(cw->cw_coroutine);  | 
1035  | 0  |     PyObject_GC_Del(cw);  | 
1036  | 0  | }  | 
1037  |  |  | 
1038  |  | static PyObject *  | 
1039  |  | coro_wrapper_iternext(PyCoroWrapper *cw)  | 
1040  | 0  | { | 
1041  | 0  |     return gen_send_ex((PyGenObject *)cw->cw_coroutine, NULL, 0, 0);  | 
1042  | 0  | }  | 
1043  |  |  | 
1044  |  | static PyObject *  | 
1045  |  | coro_wrapper_send(PyCoroWrapper *cw, PyObject *arg)  | 
1046  | 0  | { | 
1047  | 0  |     return gen_send_ex((PyGenObject *)cw->cw_coroutine, arg, 0, 0);  | 
1048  | 0  | }  | 
1049  |  |  | 
1050  |  | static PyObject *  | 
1051  |  | coro_wrapper_throw(PyCoroWrapper *cw, PyObject *args)  | 
1052  | 0  | { | 
1053  | 0  |     return gen_throw((PyGenObject *)cw->cw_coroutine, args);  | 
1054  | 0  | }  | 
1055  |  |  | 
1056  |  | static PyObject *  | 
1057  |  | coro_wrapper_close(PyCoroWrapper *cw, PyObject *args)  | 
1058  | 0  | { | 
1059  | 0  |     return gen_close((PyGenObject *)cw->cw_coroutine, args);  | 
1060  | 0  | }  | 
1061  |  |  | 
1062  |  | static int  | 
1063  |  | coro_wrapper_traverse(PyCoroWrapper *cw, visitproc visit, void *arg)  | 
1064  | 0  | { | 
1065  | 0  |     Py_VISIT((PyObject *)cw->cw_coroutine);  | 
1066  | 0  |     return 0;  | 
1067  | 0  | }  | 
1068  |  |  | 
1069  |  | static PyMethodDef coro_wrapper_methods[] = { | 
1070  |  |     {"send",(PyCFunction)coro_wrapper_send, METH_O, coro_send_doc}, | 
1071  |  |     {"throw",(PyCFunction)coro_wrapper_throw, METH_VARARGS, coro_throw_doc}, | 
1072  |  |     {"close",(PyCFunction)coro_wrapper_close, METH_NOARGS, coro_close_doc}, | 
1073  |  |     {NULL, NULL}        /* Sentinel */ | 
1074  |  | };  | 
1075  |  |  | 
1076  |  | PyTypeObject _PyCoroWrapper_Type = { | 
1077  |  |     PyVarObject_HEAD_INIT(&PyType_Type, 0)  | 
1078  |  |     "coroutine_wrapper",  | 
1079  |  |     sizeof(PyCoroWrapper),                      /* tp_basicsize */  | 
1080  |  |     0,                                          /* tp_itemsize */  | 
1081  |  |     (destructor)coro_wrapper_dealloc,           /* destructor tp_dealloc */  | 
1082  |  |     0,                                          /* tp_vectorcall_offset */  | 
1083  |  |     0,                                          /* tp_getattr */  | 
1084  |  |     0,                                          /* tp_setattr */  | 
1085  |  |     0,                                          /* tp_as_async */  | 
1086  |  |     0,                                          /* tp_repr */  | 
1087  |  |     0,                                          /* tp_as_number */  | 
1088  |  |     0,                                          /* tp_as_sequence */  | 
1089  |  |     0,                                          /* tp_as_mapping */  | 
1090  |  |     0,                                          /* tp_hash */  | 
1091  |  |     0,                                          /* tp_call */  | 
1092  |  |     0,                                          /* tp_str */  | 
1093  |  |     PyObject_GenericGetAttr,                    /* tp_getattro */  | 
1094  |  |     0,                                          /* tp_setattro */  | 
1095  |  |     0,                                          /* tp_as_buffer */  | 
1096  |  |     Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC,    /* tp_flags */  | 
1097  |  |     "A wrapper object implementing __await__ for coroutines.",  | 
1098  |  |     (traverseproc)coro_wrapper_traverse,        /* tp_traverse */  | 
1099  |  |     0,                                          /* tp_clear */  | 
1100  |  |     0,                                          /* tp_richcompare */  | 
1101  |  |     0,                                          /* tp_weaklistoffset */  | 
1102  |  |     PyObject_SelfIter,                          /* tp_iter */  | 
1103  |  |     (iternextfunc)coro_wrapper_iternext,        /* tp_iternext */  | 
1104  |  |     coro_wrapper_methods,                       /* tp_methods */  | 
1105  |  |     0,                                          /* tp_members */  | 
1106  |  |     0,                                          /* tp_getset */  | 
1107  |  |     0,                                          /* tp_base */  | 
1108  |  |     0,                                          /* tp_dict */  | 
1109  |  |     0,                                          /* tp_descr_get */  | 
1110  |  |     0,                                          /* tp_descr_set */  | 
1111  |  |     0,                                          /* tp_dictoffset */  | 
1112  |  |     0,                                          /* tp_init */  | 
1113  |  |     0,                                          /* tp_alloc */  | 
1114  |  |     0,                                          /* tp_new */  | 
1115  |  |     0,                                          /* tp_free */  | 
1116  |  | };  | 
1117  |  |  | 
1118  |  | static PyObject *  | 
1119  |  | compute_cr_origin(int origin_depth)  | 
1120  | 0  | { | 
1121  | 0  |     PyFrameObject *frame = PyEval_GetFrame();  | 
1122  |  |     /* First count how many frames we have */  | 
1123  | 0  |     int frame_count = 0;  | 
1124  | 0  |     for (; frame && frame_count < origin_depth; ++frame_count) { | 
1125  | 0  |         frame = frame->f_back;  | 
1126  | 0  |     }  | 
1127  |  |  | 
1128  |  |     /* Now collect them */  | 
1129  | 0  |     PyObject *cr_origin = PyTuple_New(frame_count);  | 
1130  | 0  |     if (cr_origin == NULL) { | 
1131  | 0  |         return NULL;  | 
1132  | 0  |     }  | 
1133  | 0  |     frame = PyEval_GetFrame();  | 
1134  | 0  |     for (int i = 0; i < frame_count; ++i) { | 
1135  | 0  |         PyObject *frameinfo = Py_BuildValue(  | 
1136  | 0  |             "OiO",  | 
1137  | 0  |             frame->f_code->co_filename,  | 
1138  | 0  |             PyFrame_GetLineNumber(frame),  | 
1139  | 0  |             frame->f_code->co_name);  | 
1140  | 0  |         if (!frameinfo) { | 
1141  | 0  |             Py_DECREF(cr_origin);  | 
1142  | 0  |             return NULL;  | 
1143  | 0  |         }  | 
1144  | 0  |         PyTuple_SET_ITEM(cr_origin, i, frameinfo);  | 
1145  | 0  |         frame = frame->f_back;  | 
1146  | 0  |     }  | 
1147  |  |  | 
1148  | 0  |     return cr_origin;  | 
1149  | 0  | }  | 
1150  |  |  | 
1151  |  | PyObject *  | 
1152  |  | PyCoro_New(PyFrameObject *f, PyObject *name, PyObject *qualname)  | 
1153  | 15  | { | 
1154  | 15  |     PyObject *coro = gen_new_with_qualname(&PyCoro_Type, f, name, qualname);  | 
1155  | 15  |     if (!coro) { | 
1156  | 0  |         return NULL;  | 
1157  | 0  |     }  | 
1158  |  |  | 
1159  | 15  |     PyThreadState *tstate = _PyThreadState_GET();  | 
1160  | 15  |     int origin_depth = tstate->coroutine_origin_tracking_depth;  | 
1161  |  |  | 
1162  | 15  |     if (origin_depth == 0) { | 
1163  | 15  |         ((PyCoroObject *)coro)->cr_origin = NULL;  | 
1164  | 15  |     } else { | 
1165  | 0  |         PyObject *cr_origin = compute_cr_origin(origin_depth);  | 
1166  | 0  |         ((PyCoroObject *)coro)->cr_origin = cr_origin;  | 
1167  | 0  |         if (!cr_origin) { | 
1168  | 0  |             Py_DECREF(coro);  | 
1169  | 0  |             return NULL;  | 
1170  | 0  |         }  | 
1171  | 0  |     }  | 
1172  |  |  | 
1173  | 15  |     return coro;  | 
1174  | 15  | }  | 
1175  |  |  | 
1176  |  |  | 
1177  |  | /* ========= Asynchronous Generators ========= */  | 
1178  |  |  | 
1179  |  |  | 
1180  |  | typedef enum { | 
1181  |  |     AWAITABLE_STATE_INIT,   /* new awaitable, has not yet been iterated */  | 
1182  |  |     AWAITABLE_STATE_ITER,   /* being iterated */  | 
1183  |  |     AWAITABLE_STATE_CLOSED, /* closed */  | 
1184  |  | } AwaitableState;  | 
1185  |  |  | 
1186  |  |  | 
1187  |  | typedef struct { | 
1188  |  |     PyObject_HEAD  | 
1189  |  |     PyAsyncGenObject *ags_gen;  | 
1190  |  |  | 
1191  |  |     /* Can be NULL, when in the __anext__() mode  | 
1192  |  |        (equivalent of "asend(None)") */  | 
1193  |  |     PyObject *ags_sendval;  | 
1194  |  |  | 
1195  |  |     AwaitableState ags_state;  | 
1196  |  | } PyAsyncGenASend;  | 
1197  |  |  | 
1198  |  |  | 
1199  |  | typedef struct { | 
1200  |  |     PyObject_HEAD  | 
1201  |  |     PyAsyncGenObject *agt_gen;  | 
1202  |  |  | 
1203  |  |     /* Can be NULL, when in the "aclose()" mode  | 
1204  |  |        (equivalent of "athrow(GeneratorExit)") */  | 
1205  |  |     PyObject *agt_args;  | 
1206  |  |  | 
1207  |  |     AwaitableState agt_state;  | 
1208  |  | } PyAsyncGenAThrow;  | 
1209  |  |  | 
1210  |  |  | 
1211  |  | typedef struct { | 
1212  |  |     PyObject_HEAD  | 
1213  |  |     PyObject *agw_val;  | 
1214  |  | } _PyAsyncGenWrappedValue;  | 
1215  |  |  | 
1216  |  |  | 
1217  |  | #ifndef _PyAsyncGen_MAXFREELIST  | 
1218  | 0  | #define _PyAsyncGen_MAXFREELIST 80  | 
1219  |  | #endif  | 
1220  |  |  | 
1221  |  | /* Freelists boost performance 6-10%; they also reduce memory  | 
1222  |  |    fragmentation, as _PyAsyncGenWrappedValue and PyAsyncGenASend  | 
1223  |  |    are short-living objects that are instantiated for every  | 
1224  |  |    __anext__ call.  | 
1225  |  | */  | 
1226  |  |  | 
1227  |  | static _PyAsyncGenWrappedValue *ag_value_freelist[_PyAsyncGen_MAXFREELIST];  | 
1228  |  | static int ag_value_freelist_free = 0;  | 
1229  |  |  | 
1230  |  | static PyAsyncGenASend *ag_asend_freelist[_PyAsyncGen_MAXFREELIST];  | 
1231  |  | static int ag_asend_freelist_free = 0;  | 
1232  |  |  | 
1233  |  | #define _PyAsyncGenWrappedValue_CheckExact(o) \  | 
1234  | 0  |                     (Py_TYPE(o) == &_PyAsyncGenWrappedValue_Type)  | 
1235  |  |  | 
1236  |  | #define PyAsyncGenASend_CheckExact(o) \  | 
1237  |  |                     (Py_TYPE(o) == &_PyAsyncGenASend_Type)  | 
1238  |  |  | 
1239  |  |  | 
1240  |  | static int  | 
1241  |  | async_gen_traverse(PyAsyncGenObject *gen, visitproc visit, void *arg)  | 
1242  | 0  | { | 
1243  | 0  |     Py_VISIT(gen->ag_finalizer);  | 
1244  | 0  |     return gen_traverse((PyGenObject*)gen, visit, arg);  | 
1245  | 0  | }  | 
1246  |  |  | 
1247  |  |  | 
1248  |  | static PyObject *  | 
1249  |  | async_gen_repr(PyAsyncGenObject *o)  | 
1250  | 0  | { | 
1251  | 0  |     return PyUnicode_FromFormat("<async_generator object %S at %p>", | 
1252  | 0  |                                 o->ag_qualname, o);  | 
1253  | 0  | }  | 
1254  |  |  | 
1255  |  |  | 
1256  |  | static int  | 
1257  |  | async_gen_init_hooks(PyAsyncGenObject *o)  | 
1258  | 0  | { | 
1259  | 0  |     PyThreadState *tstate;  | 
1260  | 0  |     PyObject *finalizer;  | 
1261  | 0  |     PyObject *firstiter;  | 
1262  |  | 
  | 
1263  | 0  |     if (o->ag_hooks_inited) { | 
1264  | 0  |         return 0;  | 
1265  | 0  |     }  | 
1266  |  |  | 
1267  | 0  |     o->ag_hooks_inited = 1;  | 
1268  |  | 
  | 
1269  | 0  |     tstate = _PyThreadState_GET();  | 
1270  |  | 
  | 
1271  | 0  |     finalizer = tstate->async_gen_finalizer;  | 
1272  | 0  |     if (finalizer) { | 
1273  | 0  |         Py_INCREF(finalizer);  | 
1274  | 0  |         o->ag_finalizer = finalizer;  | 
1275  | 0  |     }  | 
1276  |  | 
  | 
1277  | 0  |     firstiter = tstate->async_gen_firstiter;  | 
1278  | 0  |     if (firstiter) { | 
1279  | 0  |         PyObject *res;  | 
1280  |  | 
  | 
1281  | 0  |         Py_INCREF(firstiter);  | 
1282  | 0  |         res = PyObject_CallFunctionObjArgs(firstiter, o, NULL);  | 
1283  | 0  |         Py_DECREF(firstiter);  | 
1284  | 0  |         if (res == NULL) { | 
1285  | 0  |             return 1;  | 
1286  | 0  |         }  | 
1287  | 0  |         Py_DECREF(res);  | 
1288  | 0  |     }  | 
1289  |  |  | 
1290  | 0  |     return 0;  | 
1291  | 0  | }  | 
1292  |  |  | 
1293  |  |  | 
1294  |  | static PyObject *  | 
1295  |  | async_gen_anext(PyAsyncGenObject *o)  | 
1296  | 0  | { | 
1297  | 0  |     if (async_gen_init_hooks(o)) { | 
1298  | 0  |         return NULL;  | 
1299  | 0  |     }  | 
1300  | 0  |     return async_gen_asend_new(o, NULL);  | 
1301  | 0  | }  | 
1302  |  |  | 
1303  |  |  | 
1304  |  | static PyObject *  | 
1305  |  | async_gen_asend(PyAsyncGenObject *o, PyObject *arg)  | 
1306  | 0  | { | 
1307  | 0  |     if (async_gen_init_hooks(o)) { | 
1308  | 0  |         return NULL;  | 
1309  | 0  |     }  | 
1310  | 0  |     return async_gen_asend_new(o, arg);  | 
1311  | 0  | }  | 
1312  |  |  | 
1313  |  |  | 
1314  |  | static PyObject *  | 
1315  |  | async_gen_aclose(PyAsyncGenObject *o, PyObject *arg)  | 
1316  | 0  | { | 
1317  | 0  |     if (async_gen_init_hooks(o)) { | 
1318  | 0  |         return NULL;  | 
1319  | 0  |     }  | 
1320  | 0  |     return async_gen_athrow_new(o, NULL);  | 
1321  | 0  | }  | 
1322  |  |  | 
1323  |  | static PyObject *  | 
1324  |  | async_gen_athrow(PyAsyncGenObject *o, PyObject *args)  | 
1325  | 0  | { | 
1326  | 0  |     if (async_gen_init_hooks(o)) { | 
1327  | 0  |         return NULL;  | 
1328  | 0  |     }  | 
1329  | 0  |     return async_gen_athrow_new(o, args);  | 
1330  | 0  | }  | 
1331  |  |  | 
1332  |  |  | 
1333  |  | static PyGetSetDef async_gen_getsetlist[] = { | 
1334  |  |     {"__name__", (getter)gen_get_name, (setter)gen_set_name, | 
1335  |  |      PyDoc_STR("name of the async generator")}, | 
1336  |  |     {"__qualname__", (getter)gen_get_qualname, (setter)gen_set_qualname, | 
1337  |  |      PyDoc_STR("qualified name of the async generator")}, | 
1338  |  |     {"ag_await", (getter)coro_get_cr_await, NULL, | 
1339  |  |      PyDoc_STR("object being awaited on, or None")}, | 
1340  |  |     {NULL} /* Sentinel */ | 
1341  |  | };  | 
1342  |  |  | 
1343  |  | static PyMemberDef async_gen_memberlist[] = { | 
1344  |  |     {"ag_frame",   T_OBJECT, offsetof(PyAsyncGenObject, ag_frame),   READONLY}, | 
1345  |  |     {"ag_running", T_BOOL,   offsetof(PyAsyncGenObject, ag_running_async), | 
1346  |  |         READONLY},  | 
1347  |  |     {"ag_code",    T_OBJECT, offsetof(PyAsyncGenObject, ag_code),    READONLY}, | 
1348  |  |     {NULL}      /* Sentinel */ | 
1349  |  | };  | 
1350  |  |  | 
1351  |  | PyDoc_STRVAR(async_aclose_doc,  | 
1352  |  | "aclose() -> raise GeneratorExit inside generator.");  | 
1353  |  |  | 
1354  |  | PyDoc_STRVAR(async_asend_doc,  | 
1355  |  | "asend(v) -> send 'v' in generator.");  | 
1356  |  |  | 
1357  |  | PyDoc_STRVAR(async_athrow_doc,  | 
1358  |  | "athrow(typ[,val[,tb]]) -> raise exception in generator.");  | 
1359  |  |  | 
1360  |  | static PyMethodDef async_gen_methods[] = { | 
1361  |  |     {"asend", (PyCFunction)async_gen_asend, METH_O, async_asend_doc}, | 
1362  |  |     {"athrow",(PyCFunction)async_gen_athrow, METH_VARARGS, async_athrow_doc}, | 
1363  |  |     {"aclose", (PyCFunction)async_gen_aclose, METH_NOARGS, async_aclose_doc}, | 
1364  |  |     {NULL, NULL}        /* Sentinel */ | 
1365  |  | };  | 
1366  |  |  | 
1367  |  |  | 
1368  |  | static PyAsyncMethods async_gen_as_async = { | 
1369  |  |     0,                                          /* am_await */  | 
1370  |  |     PyObject_SelfIter,                          /* am_aiter */  | 
1371  |  |     (unaryfunc)async_gen_anext                  /* am_anext */  | 
1372  |  | };  | 
1373  |  |  | 
1374  |  |  | 
1375  |  | PyTypeObject PyAsyncGen_Type = { | 
1376  |  |     PyVarObject_HEAD_INIT(&PyType_Type, 0)  | 
1377  |  |     "async_generator",                          /* tp_name */  | 
1378  |  |     sizeof(PyAsyncGenObject),                   /* tp_basicsize */  | 
1379  |  |     0,                                          /* tp_itemsize */  | 
1380  |  |     /* methods */  | 
1381  |  |     (destructor)gen_dealloc,                    /* tp_dealloc */  | 
1382  |  |     0,                                          /* tp_vectorcall_offset */  | 
1383  |  |     0,                                          /* tp_getattr */  | 
1384  |  |     0,                                          /* tp_setattr */  | 
1385  |  |     &async_gen_as_async,                        /* tp_as_async */  | 
1386  |  |     (reprfunc)async_gen_repr,                   /* tp_repr */  | 
1387  |  |     0,                                          /* tp_as_number */  | 
1388  |  |     0,                                          /* tp_as_sequence */  | 
1389  |  |     0,                                          /* tp_as_mapping */  | 
1390  |  |     0,                                          /* tp_hash */  | 
1391  |  |     0,                                          /* tp_call */  | 
1392  |  |     0,                                          /* tp_str */  | 
1393  |  |     PyObject_GenericGetAttr,                    /* tp_getattro */  | 
1394  |  |     0,                                          /* tp_setattro */  | 
1395  |  |     0,                                          /* tp_as_buffer */  | 
1396  |  |     Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC,    /* tp_flags */  | 
1397  |  |     0,                                          /* tp_doc */  | 
1398  |  |     (traverseproc)async_gen_traverse,           /* tp_traverse */  | 
1399  |  |     0,                                          /* tp_clear */  | 
1400  |  |     0,                                          /* tp_richcompare */  | 
1401  |  |     offsetof(PyAsyncGenObject, ag_weakreflist), /* tp_weaklistoffset */  | 
1402  |  |     0,                                          /* tp_iter */  | 
1403  |  |     0,                                          /* tp_iternext */  | 
1404  |  |     async_gen_methods,                          /* tp_methods */  | 
1405  |  |     async_gen_memberlist,                       /* tp_members */  | 
1406  |  |     async_gen_getsetlist,                       /* tp_getset */  | 
1407  |  |     0,                                          /* tp_base */  | 
1408  |  |     0,                                          /* tp_dict */  | 
1409  |  |     0,                                          /* tp_descr_get */  | 
1410  |  |     0,                                          /* tp_descr_set */  | 
1411  |  |     0,                                          /* tp_dictoffset */  | 
1412  |  |     0,                                          /* tp_init */  | 
1413  |  |     0,                                          /* tp_alloc */  | 
1414  |  |     0,                                          /* tp_new */  | 
1415  |  |     0,                                          /* tp_free */  | 
1416  |  |     0,                                          /* tp_is_gc */  | 
1417  |  |     0,                                          /* tp_bases */  | 
1418  |  |     0,                                          /* tp_mro */  | 
1419  |  |     0,                                          /* tp_cache */  | 
1420  |  |     0,                                          /* tp_subclasses */  | 
1421  |  |     0,                                          /* tp_weaklist */  | 
1422  |  |     0,                                          /* tp_del */  | 
1423  |  |     0,                                          /* tp_version_tag */  | 
1424  |  |     _PyGen_Finalize,                            /* tp_finalize */  | 
1425  |  | };  | 
1426  |  |  | 
1427  |  |  | 
1428  |  | PyObject *  | 
1429  |  | PyAsyncGen_New(PyFrameObject *f, PyObject *name, PyObject *qualname)  | 
1430  | 15  | { | 
1431  | 15  |     PyAsyncGenObject *o;  | 
1432  | 15  |     o = (PyAsyncGenObject *)gen_new_with_qualname(  | 
1433  | 15  |         &PyAsyncGen_Type, f, name, qualname);  | 
1434  | 15  |     if (o == NULL) { | 
1435  | 0  |         return NULL;  | 
1436  | 0  |     }  | 
1437  | 15  |     o->ag_finalizer = NULL;  | 
1438  | 15  |     o->ag_closed = 0;  | 
1439  | 15  |     o->ag_hooks_inited = 0;  | 
1440  | 15  |     o->ag_running_async = 0;  | 
1441  | 15  |     return (PyObject*)o;  | 
1442  | 15  | }  | 
1443  |  |  | 
1444  |  |  | 
1445  |  | int  | 
1446  |  | PyAsyncGen_ClearFreeLists(void)  | 
1447  | 0  | { | 
1448  | 0  |     int ret = ag_value_freelist_free + ag_asend_freelist_free;  | 
1449  |  | 
  | 
1450  | 0  |     while (ag_value_freelist_free) { | 
1451  | 0  |         _PyAsyncGenWrappedValue *o;  | 
1452  | 0  |         o = ag_value_freelist[--ag_value_freelist_free];  | 
1453  | 0  |         assert(_PyAsyncGenWrappedValue_CheckExact(o));  | 
1454  | 0  |         PyObject_GC_Del(o);  | 
1455  | 0  |     }  | 
1456  |  | 
  | 
1457  | 0  |     while (ag_asend_freelist_free) { | 
1458  | 0  |         PyAsyncGenASend *o;  | 
1459  | 0  |         o = ag_asend_freelist[--ag_asend_freelist_free];  | 
1460  | 0  |         assert(Py_TYPE(o) == &_PyAsyncGenASend_Type);  | 
1461  | 0  |         PyObject_GC_Del(o);  | 
1462  | 0  |     }  | 
1463  |  | 
  | 
1464  | 0  |     return ret;  | 
1465  | 0  | }  | 
1466  |  |  | 
1467  |  | void  | 
1468  |  | PyAsyncGen_Fini(void)  | 
1469  | 0  | { | 
1470  | 0  |     PyAsyncGen_ClearFreeLists();  | 
1471  | 0  | }  | 
1472  |  |  | 
1473  |  |  | 
1474  |  | static PyObject *  | 
1475  |  | async_gen_unwrap_value(PyAsyncGenObject *gen, PyObject *result)  | 
1476  | 0  | { | 
1477  | 0  |     if (result == NULL) { | 
1478  | 0  |         if (!PyErr_Occurred()) { | 
1479  | 0  |             PyErr_SetNone(PyExc_StopAsyncIteration);  | 
1480  | 0  |         }  | 
1481  |  | 
  | 
1482  | 0  |         if (PyErr_ExceptionMatches(PyExc_StopAsyncIteration)  | 
1483  | 0  |             || PyErr_ExceptionMatches(PyExc_GeneratorExit)  | 
1484  | 0  |         ) { | 
1485  | 0  |             gen->ag_closed = 1;  | 
1486  | 0  |         }  | 
1487  |  | 
  | 
1488  | 0  |         gen->ag_running_async = 0;  | 
1489  | 0  |         return NULL;  | 
1490  | 0  |     }  | 
1491  |  |  | 
1492  | 0  |     if (_PyAsyncGenWrappedValue_CheckExact(result)) { | 
1493  |  |         /* async yield */  | 
1494  | 0  |         _PyGen_SetStopIterationValue(((_PyAsyncGenWrappedValue*)result)->agw_val);  | 
1495  | 0  |         Py_DECREF(result);  | 
1496  | 0  |         gen->ag_running_async = 0;  | 
1497  | 0  |         return NULL;  | 
1498  | 0  |     }  | 
1499  |  |  | 
1500  | 0  |     return result;  | 
1501  | 0  | }  | 
1502  |  |  | 
1503  |  |  | 
1504  |  | /* ---------- Async Generator ASend Awaitable ------------ */  | 
1505  |  |  | 
1506  |  |  | 
1507  |  | static void  | 
1508  |  | async_gen_asend_dealloc(PyAsyncGenASend *o)  | 
1509  | 0  | { | 
1510  | 0  |     _PyObject_GC_UNTRACK((PyObject *)o);  | 
1511  | 0  |     Py_CLEAR(o->ags_gen);  | 
1512  | 0  |     Py_CLEAR(o->ags_sendval);  | 
1513  | 0  |     if (ag_asend_freelist_free < _PyAsyncGen_MAXFREELIST) { | 
1514  | 0  |         assert(PyAsyncGenASend_CheckExact(o));  | 
1515  | 0  |         ag_asend_freelist[ag_asend_freelist_free++] = o;  | 
1516  | 0  |     } else { | 
1517  | 0  |         PyObject_GC_Del(o);  | 
1518  | 0  |     }  | 
1519  | 0  | }  | 
1520  |  |  | 
1521  |  | static int  | 
1522  |  | async_gen_asend_traverse(PyAsyncGenASend *o, visitproc visit, void *arg)  | 
1523  | 0  | { | 
1524  | 0  |     Py_VISIT(o->ags_gen);  | 
1525  | 0  |     Py_VISIT(o->ags_sendval);  | 
1526  | 0  |     return 0;  | 
1527  | 0  | }  | 
1528  |  |  | 
1529  |  |  | 
1530  |  | static PyObject *  | 
1531  |  | async_gen_asend_send(PyAsyncGenASend *o, PyObject *arg)  | 
1532  | 0  | { | 
1533  | 0  |     PyObject *result;  | 
1534  |  | 
  | 
1535  | 0  |     if (o->ags_state == AWAITABLE_STATE_CLOSED) { | 
1536  | 0  |         PyErr_SetString(  | 
1537  | 0  |             PyExc_RuntimeError,  | 
1538  | 0  |             "cannot reuse already awaited __anext__()/asend()");  | 
1539  | 0  |         return NULL;  | 
1540  | 0  |     }  | 
1541  |  |  | 
1542  | 0  |     if (o->ags_state == AWAITABLE_STATE_INIT) { | 
1543  | 0  |         if (o->ags_gen->ag_running_async) { | 
1544  | 0  |             PyErr_SetString(  | 
1545  | 0  |                 PyExc_RuntimeError,  | 
1546  | 0  |                 "anext(): asynchronous generator is already running");  | 
1547  | 0  |             return NULL;  | 
1548  | 0  |         }  | 
1549  |  |  | 
1550  | 0  |         if (arg == NULL || arg == Py_None) { | 
1551  | 0  |             arg = o->ags_sendval;  | 
1552  | 0  |         }  | 
1553  | 0  |         o->ags_state = AWAITABLE_STATE_ITER;  | 
1554  | 0  |     }  | 
1555  |  |  | 
1556  | 0  |     o->ags_gen->ag_running_async = 1;  | 
1557  | 0  |     result = gen_send_ex((PyGenObject*)o->ags_gen, arg, 0, 0);  | 
1558  | 0  |     result = async_gen_unwrap_value(o->ags_gen, result);  | 
1559  |  | 
  | 
1560  | 0  |     if (result == NULL) { | 
1561  | 0  |         o->ags_state = AWAITABLE_STATE_CLOSED;  | 
1562  | 0  |     }  | 
1563  |  | 
  | 
1564  | 0  |     return result;  | 
1565  | 0  | }  | 
1566  |  |  | 
1567  |  |  | 
1568  |  | static PyObject *  | 
1569  |  | async_gen_asend_iternext(PyAsyncGenASend *o)  | 
1570  | 0  | { | 
1571  | 0  |     return async_gen_asend_send(o, NULL);  | 
1572  | 0  | }  | 
1573  |  |  | 
1574  |  |  | 
1575  |  | static PyObject *  | 
1576  |  | async_gen_asend_throw(PyAsyncGenASend *o, PyObject *args)  | 
1577  | 0  | { | 
1578  | 0  |     PyObject *result;  | 
1579  |  | 
  | 
1580  | 0  |     if (o->ags_state == AWAITABLE_STATE_CLOSED) { | 
1581  | 0  |         PyErr_SetString(  | 
1582  | 0  |             PyExc_RuntimeError,  | 
1583  | 0  |             "cannot reuse already awaited __anext__()/asend()");  | 
1584  | 0  |         return NULL;  | 
1585  | 0  |     }  | 
1586  |  |  | 
1587  | 0  |     result = gen_throw((PyGenObject*)o->ags_gen, args);  | 
1588  | 0  |     result = async_gen_unwrap_value(o->ags_gen, result);  | 
1589  |  | 
  | 
1590  | 0  |     if (result == NULL) { | 
1591  | 0  |         o->ags_state = AWAITABLE_STATE_CLOSED;  | 
1592  | 0  |     }  | 
1593  |  | 
  | 
1594  | 0  |     return result;  | 
1595  | 0  | }  | 
1596  |  |  | 
1597  |  |  | 
1598  |  | static PyObject *  | 
1599  |  | async_gen_asend_close(PyAsyncGenASend *o, PyObject *args)  | 
1600  | 0  | { | 
1601  | 0  |     o->ags_state = AWAITABLE_STATE_CLOSED;  | 
1602  | 0  |     Py_RETURN_NONE;  | 
1603  | 0  | }  | 
1604  |  |  | 
1605  |  |  | 
1606  |  | static PyMethodDef async_gen_asend_methods[] = { | 
1607  |  |     {"send", (PyCFunction)async_gen_asend_send, METH_O, send_doc}, | 
1608  |  |     {"throw", (PyCFunction)async_gen_asend_throw, METH_VARARGS, throw_doc}, | 
1609  |  |     {"close", (PyCFunction)async_gen_asend_close, METH_NOARGS, close_doc}, | 
1610  |  |     {NULL, NULL}        /* Sentinel */ | 
1611  |  | };  | 
1612  |  |  | 
1613  |  |  | 
1614  |  | static PyAsyncMethods async_gen_asend_as_async = { | 
1615  |  |     PyObject_SelfIter,                          /* am_await */  | 
1616  |  |     0,                                          /* am_aiter */  | 
1617  |  |     0                                           /* am_anext */  | 
1618  |  | };  | 
1619  |  |  | 
1620  |  |  | 
1621  |  | PyTypeObject _PyAsyncGenASend_Type = { | 
1622  |  |     PyVarObject_HEAD_INIT(&PyType_Type, 0)  | 
1623  |  |     "async_generator_asend",                    /* tp_name */  | 
1624  |  |     sizeof(PyAsyncGenASend),                    /* tp_basicsize */  | 
1625  |  |     0,                                          /* tp_itemsize */  | 
1626  |  |     /* methods */  | 
1627  |  |     (destructor)async_gen_asend_dealloc,        /* tp_dealloc */  | 
1628  |  |     0,                                          /* tp_vectorcall_offset */  | 
1629  |  |     0,                                          /* tp_getattr */  | 
1630  |  |     0,                                          /* tp_setattr */  | 
1631  |  |     &async_gen_asend_as_async,                  /* tp_as_async */  | 
1632  |  |     0,                                          /* tp_repr */  | 
1633  |  |     0,                                          /* tp_as_number */  | 
1634  |  |     0,                                          /* tp_as_sequence */  | 
1635  |  |     0,                                          /* tp_as_mapping */  | 
1636  |  |     0,                                          /* tp_hash */  | 
1637  |  |     0,                                          /* tp_call */  | 
1638  |  |     0,                                          /* tp_str */  | 
1639  |  |     PyObject_GenericGetAttr,                    /* tp_getattro */  | 
1640  |  |     0,                                          /* tp_setattro */  | 
1641  |  |     0,                                          /* tp_as_buffer */  | 
1642  |  |     Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC,    /* tp_flags */  | 
1643  |  |     0,                                          /* tp_doc */  | 
1644  |  |     (traverseproc)async_gen_asend_traverse,     /* tp_traverse */  | 
1645  |  |     0,                                          /* tp_clear */  | 
1646  |  |     0,                                          /* tp_richcompare */  | 
1647  |  |     0,                                          /* tp_weaklistoffset */  | 
1648  |  |     PyObject_SelfIter,                          /* tp_iter */  | 
1649  |  |     (iternextfunc)async_gen_asend_iternext,     /* tp_iternext */  | 
1650  |  |     async_gen_asend_methods,                    /* tp_methods */  | 
1651  |  |     0,                                          /* tp_members */  | 
1652  |  |     0,                                          /* tp_getset */  | 
1653  |  |     0,                                          /* tp_base */  | 
1654  |  |     0,                                          /* tp_dict */  | 
1655  |  |     0,                                          /* tp_descr_get */  | 
1656  |  |     0,                                          /* tp_descr_set */  | 
1657  |  |     0,                                          /* tp_dictoffset */  | 
1658  |  |     0,                                          /* tp_init */  | 
1659  |  |     0,                                          /* tp_alloc */  | 
1660  |  |     0,                                          /* tp_new */  | 
1661  |  | };  | 
1662  |  |  | 
1663  |  |  | 
1664  |  | static PyObject *  | 
1665  |  | async_gen_asend_new(PyAsyncGenObject *gen, PyObject *sendval)  | 
1666  | 0  | { | 
1667  | 0  |     PyAsyncGenASend *o;  | 
1668  | 0  |     if (ag_asend_freelist_free) { | 
1669  | 0  |         ag_asend_freelist_free--;  | 
1670  | 0  |         o = ag_asend_freelist[ag_asend_freelist_free];  | 
1671  | 0  |         _Py_NewReference((PyObject *)o);  | 
1672  | 0  |     } else { | 
1673  | 0  |         o = PyObject_GC_New(PyAsyncGenASend, &_PyAsyncGenASend_Type);  | 
1674  | 0  |         if (o == NULL) { | 
1675  | 0  |             return NULL;  | 
1676  | 0  |         }  | 
1677  | 0  |     }  | 
1678  |  |  | 
1679  | 0  |     Py_INCREF(gen);  | 
1680  | 0  |     o->ags_gen = gen;  | 
1681  |  | 
  | 
1682  | 0  |     Py_XINCREF(sendval);  | 
1683  | 0  |     o->ags_sendval = sendval;  | 
1684  |  | 
  | 
1685  | 0  |     o->ags_state = AWAITABLE_STATE_INIT;  | 
1686  |  | 
  | 
1687  | 0  |     _PyObject_GC_TRACK((PyObject*)o);  | 
1688  | 0  |     return (PyObject*)o;  | 
1689  | 0  | }  | 
1690  |  |  | 
1691  |  |  | 
1692  |  | /* ---------- Async Generator Value Wrapper ------------ */  | 
1693  |  |  | 
1694  |  |  | 
1695  |  | static void  | 
1696  |  | async_gen_wrapped_val_dealloc(_PyAsyncGenWrappedValue *o)  | 
1697  | 0  | { | 
1698  | 0  |     _PyObject_GC_UNTRACK((PyObject *)o);  | 
1699  | 0  |     Py_CLEAR(o->agw_val);  | 
1700  | 0  |     if (ag_value_freelist_free < _PyAsyncGen_MAXFREELIST) { | 
1701  | 0  |         assert(_PyAsyncGenWrappedValue_CheckExact(o));  | 
1702  | 0  |         ag_value_freelist[ag_value_freelist_free++] = o;  | 
1703  | 0  |     } else { | 
1704  | 0  |         PyObject_GC_Del(o);  | 
1705  | 0  |     }  | 
1706  | 0  | }  | 
1707  |  |  | 
1708  |  |  | 
1709  |  | static int  | 
1710  |  | async_gen_wrapped_val_traverse(_PyAsyncGenWrappedValue *o,  | 
1711  |  |                                visitproc visit, void *arg)  | 
1712  | 0  | { | 
1713  | 0  |     Py_VISIT(o->agw_val);  | 
1714  | 0  |     return 0;  | 
1715  | 0  | }  | 
1716  |  |  | 
1717  |  |  | 
1718  |  | PyTypeObject _PyAsyncGenWrappedValue_Type = { | 
1719  |  |     PyVarObject_HEAD_INIT(&PyType_Type, 0)  | 
1720  |  |     "async_generator_wrapped_value",            /* tp_name */  | 
1721  |  |     sizeof(_PyAsyncGenWrappedValue),            /* tp_basicsize */  | 
1722  |  |     0,                                          /* tp_itemsize */  | 
1723  |  |     /* methods */  | 
1724  |  |     (destructor)async_gen_wrapped_val_dealloc,  /* tp_dealloc */  | 
1725  |  |     0,                                          /* tp_vectorcall_offset */  | 
1726  |  |     0,                                          /* tp_getattr */  | 
1727  |  |     0,                                          /* tp_setattr */  | 
1728  |  |     0,                                          /* tp_as_async */  | 
1729  |  |     0,                                          /* tp_repr */  | 
1730  |  |     0,                                          /* tp_as_number */  | 
1731  |  |     0,                                          /* tp_as_sequence */  | 
1732  |  |     0,                                          /* tp_as_mapping */  | 
1733  |  |     0,                                          /* tp_hash */  | 
1734  |  |     0,                                          /* tp_call */  | 
1735  |  |     0,                                          /* tp_str */  | 
1736  |  |     PyObject_GenericGetAttr,                    /* tp_getattro */  | 
1737  |  |     0,                                          /* tp_setattro */  | 
1738  |  |     0,                                          /* tp_as_buffer */  | 
1739  |  |     Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC,    /* tp_flags */  | 
1740  |  |     0,                                          /* tp_doc */  | 
1741  |  |     (traverseproc)async_gen_wrapped_val_traverse, /* tp_traverse */  | 
1742  |  |     0,                                          /* tp_clear */  | 
1743  |  |     0,                                          /* tp_richcompare */  | 
1744  |  |     0,                                          /* tp_weaklistoffset */  | 
1745  |  |     0,                                          /* tp_iter */  | 
1746  |  |     0,                                          /* tp_iternext */  | 
1747  |  |     0,                                          /* tp_methods */  | 
1748  |  |     0,                                          /* tp_members */  | 
1749  |  |     0,                                          /* tp_getset */  | 
1750  |  |     0,                                          /* tp_base */  | 
1751  |  |     0,                                          /* tp_dict */  | 
1752  |  |     0,                                          /* tp_descr_get */  | 
1753  |  |     0,                                          /* tp_descr_set */  | 
1754  |  |     0,                                          /* tp_dictoffset */  | 
1755  |  |     0,                                          /* tp_init */  | 
1756  |  |     0,                                          /* tp_alloc */  | 
1757  |  |     0,                                          /* tp_new */  | 
1758  |  | };  | 
1759  |  |  | 
1760  |  |  | 
1761  |  | PyObject *  | 
1762  |  | _PyAsyncGenValueWrapperNew(PyObject *val)  | 
1763  | 0  | { | 
1764  | 0  |     _PyAsyncGenWrappedValue *o;  | 
1765  | 0  |     assert(val);  | 
1766  |  | 
  | 
1767  | 0  |     if (ag_value_freelist_free) { | 
1768  | 0  |         ag_value_freelist_free--;  | 
1769  | 0  |         o = ag_value_freelist[ag_value_freelist_free];  | 
1770  | 0  |         assert(_PyAsyncGenWrappedValue_CheckExact(o));  | 
1771  | 0  |         _Py_NewReference((PyObject*)o);  | 
1772  | 0  |     } else { | 
1773  | 0  |         o = PyObject_GC_New(_PyAsyncGenWrappedValue,  | 
1774  | 0  |                             &_PyAsyncGenWrappedValue_Type);  | 
1775  | 0  |         if (o == NULL) { | 
1776  | 0  |             return NULL;  | 
1777  | 0  |         }  | 
1778  | 0  |     }  | 
1779  | 0  |     o->agw_val = val;  | 
1780  | 0  |     Py_INCREF(val);  | 
1781  | 0  |     _PyObject_GC_TRACK((PyObject*)o);  | 
1782  | 0  |     return (PyObject*)o;  | 
1783  | 0  | }  | 
1784  |  |  | 
1785  |  |  | 
1786  |  | /* ---------- Async Generator AThrow awaitable ------------ */  | 
1787  |  |  | 
1788  |  |  | 
1789  |  | static void  | 
1790  |  | async_gen_athrow_dealloc(PyAsyncGenAThrow *o)  | 
1791  | 0  | { | 
1792  | 0  |     _PyObject_GC_UNTRACK((PyObject *)o);  | 
1793  | 0  |     Py_CLEAR(o->agt_gen);  | 
1794  | 0  |     Py_CLEAR(o->agt_args);  | 
1795  | 0  |     PyObject_GC_Del(o);  | 
1796  | 0  | }  | 
1797  |  |  | 
1798  |  |  | 
1799  |  | static int  | 
1800  |  | async_gen_athrow_traverse(PyAsyncGenAThrow *o, visitproc visit, void *arg)  | 
1801  | 0  | { | 
1802  | 0  |     Py_VISIT(o->agt_gen);  | 
1803  | 0  |     Py_VISIT(o->agt_args);  | 
1804  | 0  |     return 0;  | 
1805  | 0  | }  | 
1806  |  |  | 
1807  |  |  | 
1808  |  | static PyObject *  | 
1809  |  | async_gen_athrow_send(PyAsyncGenAThrow *o, PyObject *arg)  | 
1810  | 0  | { | 
1811  | 0  |     PyGenObject *gen = (PyGenObject*)o->agt_gen;  | 
1812  | 0  |     PyFrameObject *f = gen->gi_frame;  | 
1813  | 0  |     PyObject *retval;  | 
1814  |  | 
  | 
1815  | 0  |     if (o->agt_state == AWAITABLE_STATE_CLOSED) { | 
1816  | 0  |         PyErr_SetString(  | 
1817  | 0  |             PyExc_RuntimeError,  | 
1818  | 0  |             "cannot reuse already awaited aclose()/athrow()");  | 
1819  | 0  |         return NULL;  | 
1820  | 0  |     }  | 
1821  |  |  | 
1822  | 0  |     if (f == NULL || f->f_stacktop == NULL) { | 
1823  | 0  |         o->agt_state = AWAITABLE_STATE_CLOSED;  | 
1824  | 0  |         PyErr_SetNone(PyExc_StopIteration);  | 
1825  | 0  |         return NULL;  | 
1826  | 0  |     }  | 
1827  |  |  | 
1828  | 0  |     if (o->agt_state == AWAITABLE_STATE_INIT) { | 
1829  | 0  |         if (o->agt_gen->ag_running_async) { | 
1830  | 0  |             o->agt_state = AWAITABLE_STATE_CLOSED;  | 
1831  | 0  |             if (o->agt_args == NULL) { | 
1832  | 0  |                 PyErr_SetString(  | 
1833  | 0  |                     PyExc_RuntimeError,  | 
1834  | 0  |                     "aclose(): asynchronous generator is already running");  | 
1835  | 0  |             }  | 
1836  | 0  |             else { | 
1837  | 0  |                 PyErr_SetString(  | 
1838  | 0  |                     PyExc_RuntimeError,  | 
1839  | 0  |                     "athrow(): asynchronous generator is already running");  | 
1840  | 0  |             }  | 
1841  | 0  |             return NULL;  | 
1842  | 0  |         }  | 
1843  |  |  | 
1844  | 0  |         if (o->agt_gen->ag_closed) { | 
1845  | 0  |             o->agt_state = AWAITABLE_STATE_CLOSED;  | 
1846  | 0  |             PyErr_SetNone(PyExc_StopAsyncIteration);  | 
1847  | 0  |             return NULL;  | 
1848  | 0  |         }  | 
1849  |  |  | 
1850  | 0  |         if (arg != Py_None) { | 
1851  | 0  |             PyErr_SetString(PyExc_RuntimeError, NON_INIT_CORO_MSG);  | 
1852  | 0  |             return NULL;  | 
1853  | 0  |         }  | 
1854  |  |  | 
1855  | 0  |         o->agt_state = AWAITABLE_STATE_ITER;  | 
1856  | 0  |         o->agt_gen->ag_running_async = 1;  | 
1857  |  | 
  | 
1858  | 0  |         if (o->agt_args == NULL) { | 
1859  |  |             /* aclose() mode */  | 
1860  | 0  |             o->agt_gen->ag_closed = 1;  | 
1861  |  | 
  | 
1862  | 0  |             retval = _gen_throw((PyGenObject *)gen,  | 
1863  | 0  |                                 0,  /* Do not close generator when  | 
1864  |  |                                        PyExc_GeneratorExit is passed */  | 
1865  | 0  |                                 PyExc_GeneratorExit, NULL, NULL);  | 
1866  |  | 
  | 
1867  | 0  |             if (retval && _PyAsyncGenWrappedValue_CheckExact(retval)) { | 
1868  | 0  |                 Py_DECREF(retval);  | 
1869  | 0  |                 goto yield_close;  | 
1870  | 0  |             }  | 
1871  | 0  |         } else { | 
1872  | 0  |             PyObject *typ;  | 
1873  | 0  |             PyObject *tb = NULL;  | 
1874  | 0  |             PyObject *val = NULL;  | 
1875  |  | 
  | 
1876  | 0  |             if (!PyArg_UnpackTuple(o->agt_args, "athrow", 1, 3,  | 
1877  | 0  |                                    &typ, &val, &tb)) { | 
1878  | 0  |                 return NULL;  | 
1879  | 0  |             }  | 
1880  |  |  | 
1881  | 0  |             retval = _gen_throw((PyGenObject *)gen,  | 
1882  | 0  |                                 0,  /* Do not close generator when  | 
1883  |  |                                        PyExc_GeneratorExit is passed */  | 
1884  | 0  |                                 typ, val, tb);  | 
1885  | 0  |             retval = async_gen_unwrap_value(o->agt_gen, retval);  | 
1886  | 0  |         }  | 
1887  | 0  |         if (retval == NULL) { | 
1888  | 0  |             goto check_error;  | 
1889  | 0  |         }  | 
1890  | 0  |         return retval;  | 
1891  | 0  |     }  | 
1892  |  |  | 
1893  | 0  |     assert(o->agt_state == AWAITABLE_STATE_ITER);  | 
1894  |  | 
  | 
1895  | 0  |     retval = gen_send_ex((PyGenObject *)gen, arg, 0, 0);  | 
1896  | 0  |     if (o->agt_args) { | 
1897  | 0  |         return async_gen_unwrap_value(o->agt_gen, retval);  | 
1898  | 0  |     } else { | 
1899  |  |         /* aclose() mode */  | 
1900  | 0  |         if (retval) { | 
1901  | 0  |             if (_PyAsyncGenWrappedValue_CheckExact(retval)) { | 
1902  | 0  |                 Py_DECREF(retval);  | 
1903  | 0  |                 goto yield_close;  | 
1904  | 0  |             }  | 
1905  | 0  |             else { | 
1906  | 0  |                 return retval;  | 
1907  | 0  |             }  | 
1908  | 0  |         }  | 
1909  | 0  |         else { | 
1910  | 0  |             goto check_error;  | 
1911  | 0  |         }  | 
1912  | 0  |     }  | 
1913  |  |  | 
1914  | 0  | yield_close:  | 
1915  | 0  |     o->agt_gen->ag_running_async = 0;  | 
1916  | 0  |     o->agt_state = AWAITABLE_STATE_CLOSED;  | 
1917  | 0  |     PyErr_SetString(  | 
1918  | 0  |         PyExc_RuntimeError, ASYNC_GEN_IGNORED_EXIT_MSG);  | 
1919  | 0  |     return NULL;  | 
1920  |  |  | 
1921  | 0  | check_error:  | 
1922  | 0  |     o->agt_gen->ag_running_async = 0;  | 
1923  | 0  |     o->agt_state = AWAITABLE_STATE_CLOSED;  | 
1924  | 0  |     if (PyErr_ExceptionMatches(PyExc_StopAsyncIteration) ||  | 
1925  | 0  |             PyErr_ExceptionMatches(PyExc_GeneratorExit))  | 
1926  | 0  |     { | 
1927  | 0  |         if (o->agt_args == NULL) { | 
1928  |  |             /* when aclose() is called we don't want to propagate  | 
1929  |  |                StopAsyncIteration or GeneratorExit; just raise  | 
1930  |  |                StopIteration, signalling that this 'aclose()' await  | 
1931  |  |                is done.  | 
1932  |  |             */  | 
1933  | 0  |             PyErr_Clear();  | 
1934  | 0  |             PyErr_SetNone(PyExc_StopIteration);  | 
1935  | 0  |         }  | 
1936  | 0  |     }  | 
1937  | 0  |     return NULL;  | 
1938  | 0  | }  | 
1939  |  |  | 
1940  |  |  | 
1941  |  | static PyObject *  | 
1942  |  | async_gen_athrow_throw(PyAsyncGenAThrow *o, PyObject *args)  | 
1943  | 0  | { | 
1944  | 0  |     PyObject *retval;  | 
1945  |  | 
  | 
1946  | 0  |     if (o->agt_state == AWAITABLE_STATE_CLOSED) { | 
1947  | 0  |         PyErr_SetString(  | 
1948  | 0  |             PyExc_RuntimeError,  | 
1949  | 0  |             "cannot reuse already awaited aclose()/athrow()");  | 
1950  | 0  |         return NULL;  | 
1951  | 0  |     }  | 
1952  |  |  | 
1953  | 0  |     retval = gen_throw((PyGenObject*)o->agt_gen, args);  | 
1954  | 0  |     if (o->agt_args) { | 
1955  | 0  |         return async_gen_unwrap_value(o->agt_gen, retval);  | 
1956  | 0  |     } else { | 
1957  |  |         /* aclose() mode */  | 
1958  | 0  |         if (retval && _PyAsyncGenWrappedValue_CheckExact(retval)) { | 
1959  | 0  |             o->agt_gen->ag_running_async = 0;  | 
1960  | 0  |             o->agt_state = AWAITABLE_STATE_CLOSED;  | 
1961  | 0  |             Py_DECREF(retval);  | 
1962  | 0  |             PyErr_SetString(PyExc_RuntimeError, ASYNC_GEN_IGNORED_EXIT_MSG);  | 
1963  | 0  |             return NULL;  | 
1964  | 0  |         }  | 
1965  | 0  |         if (PyErr_ExceptionMatches(PyExc_StopAsyncIteration) ||  | 
1966  | 0  |             PyErr_ExceptionMatches(PyExc_GeneratorExit))  | 
1967  | 0  |         { | 
1968  |  |             /* when aclose() is called we don't want to propagate  | 
1969  |  |                StopAsyncIteration or GeneratorExit; just raise  | 
1970  |  |                StopIteration, signalling that this 'aclose()' await  | 
1971  |  |                is done.  | 
1972  |  |             */  | 
1973  | 0  |             PyErr_Clear();  | 
1974  | 0  |             PyErr_SetNone(PyExc_StopIteration);  | 
1975  | 0  |         }  | 
1976  | 0  |         return retval;  | 
1977  | 0  |     }  | 
1978  | 0  | }  | 
1979  |  |  | 
1980  |  |  | 
1981  |  | static PyObject *  | 
1982  |  | async_gen_athrow_iternext(PyAsyncGenAThrow *o)  | 
1983  | 0  | { | 
1984  | 0  |     return async_gen_athrow_send(o, Py_None);  | 
1985  | 0  | }  | 
1986  |  |  | 
1987  |  |  | 
1988  |  | static PyObject *  | 
1989  |  | async_gen_athrow_close(PyAsyncGenAThrow *o, PyObject *args)  | 
1990  | 0  | { | 
1991  | 0  |     o->agt_state = AWAITABLE_STATE_CLOSED;  | 
1992  | 0  |     Py_RETURN_NONE;  | 
1993  | 0  | }  | 
1994  |  |  | 
1995  |  |  | 
1996  |  | static PyMethodDef async_gen_athrow_methods[] = { | 
1997  |  |     {"send", (PyCFunction)async_gen_athrow_send, METH_O, send_doc}, | 
1998  |  |     {"throw", (PyCFunction)async_gen_athrow_throw, METH_VARARGS, throw_doc}, | 
1999  |  |     {"close", (PyCFunction)async_gen_athrow_close, METH_NOARGS, close_doc}, | 
2000  |  |     {NULL, NULL}        /* Sentinel */ | 
2001  |  | };  | 
2002  |  |  | 
2003  |  |  | 
2004  |  | static PyAsyncMethods async_gen_athrow_as_async = { | 
2005  |  |     PyObject_SelfIter,                          /* am_await */  | 
2006  |  |     0,                                          /* am_aiter */  | 
2007  |  |     0                                           /* am_anext */  | 
2008  |  | };  | 
2009  |  |  | 
2010  |  |  | 
2011  |  | PyTypeObject _PyAsyncGenAThrow_Type = { | 
2012  |  |     PyVarObject_HEAD_INIT(&PyType_Type, 0)  | 
2013  |  |     "async_generator_athrow",                   /* tp_name */  | 
2014  |  |     sizeof(PyAsyncGenAThrow),                   /* tp_basicsize */  | 
2015  |  |     0,                                          /* tp_itemsize */  | 
2016  |  |     /* methods */  | 
2017  |  |     (destructor)async_gen_athrow_dealloc,       /* tp_dealloc */  | 
2018  |  |     0,                                          /* tp_vectorcall_offset */  | 
2019  |  |     0,                                          /* tp_getattr */  | 
2020  |  |     0,                                          /* tp_setattr */  | 
2021  |  |     &async_gen_athrow_as_async,                 /* tp_as_async */  | 
2022  |  |     0,                                          /* tp_repr */  | 
2023  |  |     0,                                          /* tp_as_number */  | 
2024  |  |     0,                                          /* tp_as_sequence */  | 
2025  |  |     0,                                          /* tp_as_mapping */  | 
2026  |  |     0,                                          /* tp_hash */  | 
2027  |  |     0,                                          /* tp_call */  | 
2028  |  |     0,                                          /* tp_str */  | 
2029  |  |     PyObject_GenericGetAttr,                    /* tp_getattro */  | 
2030  |  |     0,                                          /* tp_setattro */  | 
2031  |  |     0,                                          /* tp_as_buffer */  | 
2032  |  |     Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC,    /* tp_flags */  | 
2033  |  |     0,                                          /* tp_doc */  | 
2034  |  |     (traverseproc)async_gen_athrow_traverse,    /* tp_traverse */  | 
2035  |  |     0,                                          /* tp_clear */  | 
2036  |  |     0,                                          /* tp_richcompare */  | 
2037  |  |     0,                                          /* tp_weaklistoffset */  | 
2038  |  |     PyObject_SelfIter,                          /* tp_iter */  | 
2039  |  |     (iternextfunc)async_gen_athrow_iternext,    /* tp_iternext */  | 
2040  |  |     async_gen_athrow_methods,                   /* tp_methods */  | 
2041  |  |     0,                                          /* tp_members */  | 
2042  |  |     0,                                          /* tp_getset */  | 
2043  |  |     0,                                          /* tp_base */  | 
2044  |  |     0,                                          /* tp_dict */  | 
2045  |  |     0,                                          /* tp_descr_get */  | 
2046  |  |     0,                                          /* tp_descr_set */  | 
2047  |  |     0,                                          /* tp_dictoffset */  | 
2048  |  |     0,                                          /* tp_init */  | 
2049  |  |     0,                                          /* tp_alloc */  | 
2050  |  |     0,                                          /* tp_new */  | 
2051  |  | };  | 
2052  |  |  | 
2053  |  |  | 
2054  |  | static PyObject *  | 
2055  |  | async_gen_athrow_new(PyAsyncGenObject *gen, PyObject *args)  | 
2056  | 0  | { | 
2057  | 0  |     PyAsyncGenAThrow *o;  | 
2058  | 0  |     o = PyObject_GC_New(PyAsyncGenAThrow, &_PyAsyncGenAThrow_Type);  | 
2059  | 0  |     if (o == NULL) { | 
2060  | 0  |         return NULL;  | 
2061  | 0  |     }  | 
2062  | 0  |     o->agt_gen = gen;  | 
2063  | 0  |     o->agt_args = args;  | 
2064  | 0  |     o->agt_state = AWAITABLE_STATE_INIT;  | 
2065  | 0  |     Py_INCREF(gen);  | 
2066  | 0  |     Py_XINCREF(args);  | 
2067  | 0  |     _PyObject_GC_TRACK((PyObject*)o);  | 
2068  | 0  |     return (PyObject*)o;  | 
2069  | 0  | }  |