annotate Objects/genobject.c @ 87690:66c1c9f32567 default tip

Add use_weakref option to functools.lru_cache The use_weakref option makes lru_cache create weak references to the function arguments when creating the cache key, which prevents them from staying in the memory forever even after all other references to them are gone. This is a proof of concept for http://bugs.python.org/issue19859
author Radomir Dopieralski <devel@sheep.art.pl>
date Tue, 03 Dec 2013 16:02:48 +0100
parents 862ab99ab570
children
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
32175
8ee5a56b8031 Patch #957398: Add public API for Generator Object/Type.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
1 /* Generator object implementation */
8ee5a56b8031 Patch #957398: Add public API for Generator Object/Type.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
2
8ee5a56b8031 Patch #957398: Add public API for Generator Object/Type.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
3 #include "Python.h"
8ee5a56b8031 Patch #957398: Add public API for Generator Object/Type.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
4 #include "frameobject.h"
8ee5a56b8031 Patch #957398: Add public API for Generator Object/Type.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
5 #include "structmember.h"
37879
f731859e9b3b Merge p3yk branch with the trunk up to revision 45595. This breaks a fair
Thomas Wouters <thomas@python.org>
parents: 36866
diff changeset
6 #include "opcode.h"
32175
8ee5a56b8031 Patch #957398: Add public API for Generator Object/Type.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
7
74356
d64ac9ab4cd0 Implement PEP 380 - 'yield from' (closes #11682)
Nick Coghlan <ncoghlan@gmail.com>
parents: 73011
diff changeset
8 static PyObject *gen_close(PyGenObject *gen, PyObject *args);
d64ac9ab4cd0 Implement PEP 380 - 'yield from' (closes #11682)
Nick Coghlan <ncoghlan@gmail.com>
parents: 73011
diff changeset
9
32175
8ee5a56b8031 Patch #957398: Add public API for Generator Object/Type.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
10 static int
8ee5a56b8031 Patch #957398: Add public API for Generator Object/Type.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
11 gen_traverse(PyGenObject *gen, visitproc visit, void *arg)
8ee5a56b8031 Patch #957398: Add public API for Generator Object/Type.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
12 {
61466
cab14be0ada1 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 52892
diff changeset
13 Py_VISIT((PyObject *)gen->gi_frame);
cab14be0ada1 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 52892
diff changeset
14 Py_VISIT(gen->gi_code);
cab14be0ada1 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 52892
diff changeset
15 return 0;
32175
8ee5a56b8031 Patch #957398: Add public API for Generator Object/Type.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
16 }
8ee5a56b8031 Patch #957398: Add public API for Generator Object/Type.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
17
85046
862ab99ab570 Issue #17934: Add a clear() method to frame objects, to help clean up expensive details (local variables) and break reference cycles.
Antoine Pitrou <solipsis@pitrou.net>
parents: 84911
diff changeset
18 void
862ab99ab570 Issue #17934: Add a clear() method to frame objects, to help clean up expensive details (local variables) and break reference cycles.
Antoine Pitrou <solipsis@pitrou.net>
parents: 84911
diff changeset
19 _PyGen_Finalize(PyObject *self)
84911
3f994367a979 Issue #18112: PEP 442 implementation (safe object finalization).
Antoine Pitrou <solipsis@pitrou.net>
parents: 83771
diff changeset
20 {
3f994367a979 Issue #18112: PEP 442 implementation (safe object finalization).
Antoine Pitrou <solipsis@pitrou.net>
parents: 83771
diff changeset
21 PyGenObject *gen = (PyGenObject *)self;
3f994367a979 Issue #18112: PEP 442 implementation (safe object finalization).
Antoine Pitrou <solipsis@pitrou.net>
parents: 83771
diff changeset
22 PyObject *res;
3f994367a979 Issue #18112: PEP 442 implementation (safe object finalization).
Antoine Pitrou <solipsis@pitrou.net>
parents: 83771
diff changeset
23 PyObject *error_type, *error_value, *error_traceback;
3f994367a979 Issue #18112: PEP 442 implementation (safe object finalization).
Antoine Pitrou <solipsis@pitrou.net>
parents: 83771
diff changeset
24
3f994367a979 Issue #18112: PEP 442 implementation (safe object finalization).
Antoine Pitrou <solipsis@pitrou.net>
parents: 83771
diff changeset
25 if (gen->gi_frame == NULL || gen->gi_frame->f_stacktop == NULL)
3f994367a979 Issue #18112: PEP 442 implementation (safe object finalization).
Antoine Pitrou <solipsis@pitrou.net>
parents: 83771
diff changeset
26 /* Generator isn't paused, so no need to close */
3f994367a979 Issue #18112: PEP 442 implementation (safe object finalization).
Antoine Pitrou <solipsis@pitrou.net>
parents: 83771
diff changeset
27 return;
3f994367a979 Issue #18112: PEP 442 implementation (safe object finalization).
Antoine Pitrou <solipsis@pitrou.net>
parents: 83771
diff changeset
28
3f994367a979 Issue #18112: PEP 442 implementation (safe object finalization).
Antoine Pitrou <solipsis@pitrou.net>
parents: 83771
diff changeset
29 /* Save the current exception, if any. */
3f994367a979 Issue #18112: PEP 442 implementation (safe object finalization).
Antoine Pitrou <solipsis@pitrou.net>
parents: 83771
diff changeset
30 PyErr_Fetch(&error_type, &error_value, &error_traceback);
3f994367a979 Issue #18112: PEP 442 implementation (safe object finalization).
Antoine Pitrou <solipsis@pitrou.net>
parents: 83771
diff changeset
31
3f994367a979 Issue #18112: PEP 442 implementation (safe object finalization).
Antoine Pitrou <solipsis@pitrou.net>
parents: 83771
diff changeset
32 res = gen_close(gen, NULL);
3f994367a979 Issue #18112: PEP 442 implementation (safe object finalization).
Antoine Pitrou <solipsis@pitrou.net>
parents: 83771
diff changeset
33
3f994367a979 Issue #18112: PEP 442 implementation (safe object finalization).
Antoine Pitrou <solipsis@pitrou.net>
parents: 83771
diff changeset
34 if (res == NULL)
3f994367a979 Issue #18112: PEP 442 implementation (safe object finalization).
Antoine Pitrou <solipsis@pitrou.net>
parents: 83771
diff changeset
35 PyErr_WriteUnraisable(self);
3f994367a979 Issue #18112: PEP 442 implementation (safe object finalization).
Antoine Pitrou <solipsis@pitrou.net>
parents: 83771
diff changeset
36 else
3f994367a979 Issue #18112: PEP 442 implementation (safe object finalization).
Antoine Pitrou <solipsis@pitrou.net>
parents: 83771
diff changeset
37 Py_DECREF(res);
3f994367a979 Issue #18112: PEP 442 implementation (safe object finalization).
Antoine Pitrou <solipsis@pitrou.net>
parents: 83771
diff changeset
38
3f994367a979 Issue #18112: PEP 442 implementation (safe object finalization).
Antoine Pitrou <solipsis@pitrou.net>
parents: 83771
diff changeset
39 /* Restore the saved exception. */
3f994367a979 Issue #18112: PEP 442 implementation (safe object finalization).
Antoine Pitrou <solipsis@pitrou.net>
parents: 83771
diff changeset
40 PyErr_Restore(error_type, error_value, error_traceback);
3f994367a979 Issue #18112: PEP 442 implementation (safe object finalization).
Antoine Pitrou <solipsis@pitrou.net>
parents: 83771
diff changeset
41 }
3f994367a979 Issue #18112: PEP 442 implementation (safe object finalization).
Antoine Pitrou <solipsis@pitrou.net>
parents: 83771
diff changeset
42
3f994367a979 Issue #18112: PEP 442 implementation (safe object finalization).
Antoine Pitrou <solipsis@pitrou.net>
parents: 83771
diff changeset
43 static void
32175
8ee5a56b8031 Patch #957398: Add public API for Generator Object/Type.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
44 gen_dealloc(PyGenObject *gen)
8ee5a56b8031 Patch #957398: Add public API for Generator Object/Type.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
45 {
61466
cab14be0ada1 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 52892
diff changeset
46 PyObject *self = (PyObject *) gen;
35298
b2fe5f8fcfdd PEP 342 implementation. Per Guido's comments, the generator throw()
Phillip J. Eby <pje@telecommunity.com>
parents: 33386
diff changeset
47
61466
cab14be0ada1 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 52892
diff changeset
48 _PyObject_GC_UNTRACK(gen);
35298
b2fe5f8fcfdd PEP 342 implementation. Per Guido's comments, the generator throw()
Phillip J. Eby <pje@telecommunity.com>
parents: 33386
diff changeset
49
61466
cab14be0ada1 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 52892
diff changeset
50 if (gen->gi_weakreflist != NULL)
cab14be0ada1 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 52892
diff changeset
51 PyObject_ClearWeakRefs(self);
35298
b2fe5f8fcfdd PEP 342 implementation. Per Guido's comments, the generator throw()
Phillip J. Eby <pje@telecommunity.com>
parents: 33386
diff changeset
52
83771
edefd3450834 Backout c89febab4648 following private feedback by Guido.
Antoine Pitrou <solipsis@pitrou.net>
parents: 83688
diff changeset
53 _PyObject_GC_TRACK(self);
edefd3450834 Backout c89febab4648 following private feedback by Guido.
Antoine Pitrou <solipsis@pitrou.net>
parents: 83688
diff changeset
54
84911
3f994367a979 Issue #18112: PEP 442 implementation (safe object finalization).
Antoine Pitrou <solipsis@pitrou.net>
parents: 83771
diff changeset
55 if (PyObject_CallFinalizerFromDealloc(self))
3f994367a979 Issue #18112: PEP 442 implementation (safe object finalization).
Antoine Pitrou <solipsis@pitrou.net>
parents: 83771
diff changeset
56 return; /* resurrected. :( */
83771
edefd3450834 Backout c89febab4648 following private feedback by Guido.
Antoine Pitrou <solipsis@pitrou.net>
parents: 83688
diff changeset
57
edefd3450834 Backout c89febab4648 following private feedback by Guido.
Antoine Pitrou <solipsis@pitrou.net>
parents: 83688
diff changeset
58 _PyObject_GC_UNTRACK(self);
edefd3450834 Backout c89febab4648 following private feedback by Guido.
Antoine Pitrou <solipsis@pitrou.net>
parents: 83688
diff changeset
59 Py_CLEAR(gen->gi_frame);
61466
cab14be0ada1 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 52892
diff changeset
60 Py_CLEAR(gen->gi_code);
cab14be0ada1 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 52892
diff changeset
61 PyObject_GC_Del(gen);
32175
8ee5a56b8031 Patch #957398: Add public API for Generator Object/Type.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
62 }
8ee5a56b8031 Patch #957398: Add public API for Generator Object/Type.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
63
8ee5a56b8031 Patch #957398: Add public API for Generator Object/Type.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
64 static PyObject *
35298
b2fe5f8fcfdd PEP 342 implementation. Per Guido's comments, the generator throw()
Phillip J. Eby <pje@telecommunity.com>
parents: 33386
diff changeset
65 gen_send_ex(PyGenObject *gen, PyObject *arg, int exc)
32175
8ee5a56b8031 Patch #957398: Add public API for Generator Object/Type.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
66 {
83771
edefd3450834 Backout c89febab4648 following private feedback by Guido.
Antoine Pitrou <solipsis@pitrou.net>
parents: 83688
diff changeset
67 PyThreadState *tstate = PyThreadState_GET();
61466
cab14be0ada1 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 52892
diff changeset
68 PyFrameObject *f = gen->gi_frame;
83771
edefd3450834 Backout c89febab4648 following private feedback by Guido.
Antoine Pitrou <solipsis@pitrou.net>
parents: 83688
diff changeset
69 PyObject *result;
32175
8ee5a56b8031 Patch #957398: Add public API for Generator Object/Type.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
70
61466
cab14be0ada1 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 52892
diff changeset
71 if (gen->gi_running) {
cab14be0ada1 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 52892
diff changeset
72 PyErr_SetString(PyExc_ValueError,
cab14be0ada1 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 52892
diff changeset
73 "generator already executing");
cab14be0ada1 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 52892
diff changeset
74 return NULL;
cab14be0ada1 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 52892
diff changeset
75 }
83771
edefd3450834 Backout c89febab4648 following private feedback by Guido.
Antoine Pitrou <solipsis@pitrou.net>
parents: 83688
diff changeset
76 if (f == NULL || f->f_stacktop == NULL) {
edefd3450834 Backout c89febab4648 following private feedback by Guido.
Antoine Pitrou <solipsis@pitrou.net>
parents: 83688
diff changeset
77 /* Only set exception if called from send() */
61466
cab14be0ada1 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 52892
diff changeset
78 if (arg && !exc)
cab14be0ada1 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 52892
diff changeset
79 PyErr_SetNone(PyExc_StopIteration);
cab14be0ada1 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 52892
diff changeset
80 return NULL;
cab14be0ada1 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 52892
diff changeset
81 }
35298
b2fe5f8fcfdd PEP 342 implementation. Per Guido's comments, the generator throw()
Phillip J. Eby <pje@telecommunity.com>
parents: 33386
diff changeset
82
83771
edefd3450834 Backout c89febab4648 following private feedback by Guido.
Antoine Pitrou <solipsis@pitrou.net>
parents: 83688
diff changeset
83 if (f->f_lasti == -1) {
edefd3450834 Backout c89febab4648 following private feedback by Guido.
Antoine Pitrou <solipsis@pitrou.net>
parents: 83688
diff changeset
84 if (arg && arg != Py_None) {
edefd3450834 Backout c89febab4648 following private feedback by Guido.
Antoine Pitrou <solipsis@pitrou.net>
parents: 83688
diff changeset
85 PyErr_SetString(PyExc_TypeError,
edefd3450834 Backout c89febab4648 following private feedback by Guido.
Antoine Pitrou <solipsis@pitrou.net>
parents: 83688
diff changeset
86 "can't send non-None value to a "
edefd3450834 Backout c89febab4648 following private feedback by Guido.
Antoine Pitrou <solipsis@pitrou.net>
parents: 83688
diff changeset
87 "just-started generator");
edefd3450834 Backout c89febab4648 following private feedback by Guido.
Antoine Pitrou <solipsis@pitrou.net>
parents: 83688
diff changeset
88 return NULL;
edefd3450834 Backout c89febab4648 following private feedback by Guido.
Antoine Pitrou <solipsis@pitrou.net>
parents: 83688
diff changeset
89 }
edefd3450834 Backout c89febab4648 following private feedback by Guido.
Antoine Pitrou <solipsis@pitrou.net>
parents: 83688
diff changeset
90 } else {
edefd3450834 Backout c89febab4648 following private feedback by Guido.
Antoine Pitrou <solipsis@pitrou.net>
parents: 83688
diff changeset
91 /* Push arg onto the frame's value stack */
edefd3450834 Backout c89febab4648 following private feedback by Guido.
Antoine Pitrou <solipsis@pitrou.net>
parents: 83688
diff changeset
92 result = arg ? arg : Py_None;
edefd3450834 Backout c89febab4648 following private feedback by Guido.
Antoine Pitrou <solipsis@pitrou.net>
parents: 83688
diff changeset
93 Py_INCREF(result);
edefd3450834 Backout c89febab4648 following private feedback by Guido.
Antoine Pitrou <solipsis@pitrou.net>
parents: 83688
diff changeset
94 *(f->f_stacktop++) = result;
edefd3450834 Backout c89febab4648 following private feedback by Guido.
Antoine Pitrou <solipsis@pitrou.net>
parents: 83688
diff changeset
95 }
edefd3450834 Backout c89febab4648 following private feedback by Guido.
Antoine Pitrou <solipsis@pitrou.net>
parents: 83688
diff changeset
96
edefd3450834 Backout c89febab4648 following private feedback by Guido.
Antoine Pitrou <solipsis@pitrou.net>
parents: 83688
diff changeset
97 /* Generators always return to their most recent caller, not
edefd3450834 Backout c89febab4648 following private feedback by Guido.
Antoine Pitrou <solipsis@pitrou.net>
parents: 83688
diff changeset
98 * necessarily their creator. */
edefd3450834 Backout c89febab4648 following private feedback by Guido.
Antoine Pitrou <solipsis@pitrou.net>
parents: 83688
diff changeset
99 Py_XINCREF(tstate->frame);
edefd3450834 Backout c89febab4648 following private feedback by Guido.
Antoine Pitrou <solipsis@pitrou.net>
parents: 83688
diff changeset
100 assert(f->f_back == NULL);
edefd3450834 Backout c89febab4648 following private feedback by Guido.
Antoine Pitrou <solipsis@pitrou.net>
parents: 83688
diff changeset
101 f->f_back = tstate->frame;
edefd3450834 Backout c89febab4648 following private feedback by Guido.
Antoine Pitrou <solipsis@pitrou.net>
parents: 83688
diff changeset
102
edefd3450834 Backout c89febab4648 following private feedback by Guido.
Antoine Pitrou <solipsis@pitrou.net>
parents: 83688
diff changeset
103 gen->gi_running = 1;
edefd3450834 Backout c89febab4648 following private feedback by Guido.
Antoine Pitrou <solipsis@pitrou.net>
parents: 83688
diff changeset
104 result = PyEval_EvalFrameEx(f, exc);
edefd3450834 Backout c89febab4648 following private feedback by Guido.
Antoine Pitrou <solipsis@pitrou.net>
parents: 83688
diff changeset
105 gen->gi_running = 0;
edefd3450834 Backout c89febab4648 following private feedback by Guido.
Antoine Pitrou <solipsis@pitrou.net>
parents: 83688
diff changeset
106
edefd3450834 Backout c89febab4648 following private feedback by Guido.
Antoine Pitrou <solipsis@pitrou.net>
parents: 83688
diff changeset
107 /* Don't keep the reference to f_back any longer than necessary. It
edefd3450834 Backout c89febab4648 following private feedback by Guido.
Antoine Pitrou <solipsis@pitrou.net>
parents: 83688
diff changeset
108 * may keep a chain of frames alive or it could create a reference
edefd3450834 Backout c89febab4648 following private feedback by Guido.
Antoine Pitrou <solipsis@pitrou.net>
parents: 83688
diff changeset
109 * cycle. */
edefd3450834 Backout c89febab4648 following private feedback by Guido.
Antoine Pitrou <solipsis@pitrou.net>
parents: 83688
diff changeset
110 assert(f->f_back == tstate->frame);
edefd3450834 Backout c89febab4648 following private feedback by Guido.
Antoine Pitrou <solipsis@pitrou.net>
parents: 83688
diff changeset
111 Py_CLEAR(f->f_back);
edefd3450834 Backout c89febab4648 following private feedback by Guido.
Antoine Pitrou <solipsis@pitrou.net>
parents: 83688
diff changeset
112
edefd3450834 Backout c89febab4648 following private feedback by Guido.
Antoine Pitrou <solipsis@pitrou.net>
parents: 83688
diff changeset
113 /* If the generator just returned (as opposed to yielding), signal
edefd3450834 Backout c89febab4648 following private feedback by Guido.
Antoine Pitrou <solipsis@pitrou.net>
parents: 83688
diff changeset
114 * that the generator is exhausted. */
edefd3450834 Backout c89febab4648 following private feedback by Guido.
Antoine Pitrou <solipsis@pitrou.net>
parents: 83688
diff changeset
115 if (result && f->f_stacktop == NULL) {
edefd3450834 Backout c89febab4648 following private feedback by Guido.
Antoine Pitrou <solipsis@pitrou.net>
parents: 83688
diff changeset
116 if (result == Py_None) {
edefd3450834 Backout c89febab4648 following private feedback by Guido.
Antoine Pitrou <solipsis@pitrou.net>
parents: 83688
diff changeset
117 /* Delay exception instantiation if we can */
edefd3450834 Backout c89febab4648 following private feedback by Guido.
Antoine Pitrou <solipsis@pitrou.net>
parents: 83688
diff changeset
118 PyErr_SetNone(PyExc_StopIteration);
edefd3450834 Backout c89febab4648 following private feedback by Guido.
Antoine Pitrou <solipsis@pitrou.net>
parents: 83688
diff changeset
119 } else {
edefd3450834 Backout c89febab4648 following private feedback by Guido.
Antoine Pitrou <solipsis@pitrou.net>
parents: 83688
diff changeset
120 PyObject *e = PyObject_CallFunctionObjArgs(
edefd3450834 Backout c89febab4648 following private feedback by Guido.
Antoine Pitrou <solipsis@pitrou.net>
parents: 83688
diff changeset
121 PyExc_StopIteration, result, NULL);
edefd3450834 Backout c89febab4648 following private feedback by Guido.
Antoine Pitrou <solipsis@pitrou.net>
parents: 83688
diff changeset
122 if (e != NULL) {
edefd3450834 Backout c89febab4648 following private feedback by Guido.
Antoine Pitrou <solipsis@pitrou.net>
parents: 83688
diff changeset
123 PyErr_SetObject(PyExc_StopIteration, e);
edefd3450834 Backout c89febab4648 following private feedback by Guido.
Antoine Pitrou <solipsis@pitrou.net>
parents: 83688
diff changeset
124 Py_DECREF(e);
edefd3450834 Backout c89febab4648 following private feedback by Guido.
Antoine Pitrou <solipsis@pitrou.net>
parents: 83688
diff changeset
125 }
edefd3450834 Backout c89febab4648 following private feedback by Guido.
Antoine Pitrou <solipsis@pitrou.net>
parents: 83688
diff changeset
126 }
edefd3450834 Backout c89febab4648 following private feedback by Guido.
Antoine Pitrou <solipsis@pitrou.net>
parents: 83688
diff changeset
127 Py_CLEAR(result);
edefd3450834 Backout c89febab4648 following private feedback by Guido.
Antoine Pitrou <solipsis@pitrou.net>
parents: 83688
diff changeset
128 }
edefd3450834 Backout c89febab4648 following private feedback by Guido.
Antoine Pitrou <solipsis@pitrou.net>
parents: 83688
diff changeset
129
edefd3450834 Backout c89febab4648 following private feedback by Guido.
Antoine Pitrou <solipsis@pitrou.net>
parents: 83688
diff changeset
130 if (!result || f->f_stacktop == NULL) {
edefd3450834 Backout c89febab4648 following private feedback by Guido.
Antoine Pitrou <solipsis@pitrou.net>
parents: 83688
diff changeset
131 /* generator can't be rerun, so release the frame */
edefd3450834 Backout c89febab4648 following private feedback by Guido.
Antoine Pitrou <solipsis@pitrou.net>
parents: 83688
diff changeset
132 /* first clean reference cycle through stored exception traceback */
edefd3450834 Backout c89febab4648 following private feedback by Guido.
Antoine Pitrou <solipsis@pitrou.net>
parents: 83688
diff changeset
133 PyObject *t, *v, *tb;
edefd3450834 Backout c89febab4648 following private feedback by Guido.
Antoine Pitrou <solipsis@pitrou.net>
parents: 83688
diff changeset
134 t = f->f_exc_type;
edefd3450834 Backout c89febab4648 following private feedback by Guido.
Antoine Pitrou <solipsis@pitrou.net>
parents: 83688
diff changeset
135 v = f->f_exc_value;
edefd3450834 Backout c89febab4648 following private feedback by Guido.
Antoine Pitrou <solipsis@pitrou.net>
parents: 83688
diff changeset
136 tb = f->f_exc_traceback;
edefd3450834 Backout c89febab4648 following private feedback by Guido.
Antoine Pitrou <solipsis@pitrou.net>
parents: 83688
diff changeset
137 f->f_exc_type = NULL;
edefd3450834 Backout c89febab4648 following private feedback by Guido.
Antoine Pitrou <solipsis@pitrou.net>
parents: 83688
diff changeset
138 f->f_exc_value = NULL;
edefd3450834 Backout c89febab4648 following private feedback by Guido.
Antoine Pitrou <solipsis@pitrou.net>
parents: 83688
diff changeset
139 f->f_exc_traceback = NULL;
edefd3450834 Backout c89febab4648 following private feedback by Guido.
Antoine Pitrou <solipsis@pitrou.net>
parents: 83688
diff changeset
140 Py_XDECREF(t);
edefd3450834 Backout c89febab4648 following private feedback by Guido.
Antoine Pitrou <solipsis@pitrou.net>
parents: 83688
diff changeset
141 Py_XDECREF(v);
edefd3450834 Backout c89febab4648 following private feedback by Guido.
Antoine Pitrou <solipsis@pitrou.net>
parents: 83688
diff changeset
142 Py_XDECREF(tb);
85046
862ab99ab570 Issue #17934: Add a clear() method to frame objects, to help clean up expensive details (local variables) and break reference cycles.
Antoine Pitrou <solipsis@pitrou.net>
parents: 84911
diff changeset
143 gen->gi_frame->f_gen = NULL;
83771
edefd3450834 Backout c89febab4648 following private feedback by Guido.
Antoine Pitrou <solipsis@pitrou.net>
parents: 83688
diff changeset
144 gen->gi_frame = NULL;
edefd3450834 Backout c89febab4648 following private feedback by Guido.
Antoine Pitrou <solipsis@pitrou.net>
parents: 83688
diff changeset
145 Py_DECREF(f);
edefd3450834 Backout c89febab4648 following private feedback by Guido.
Antoine Pitrou <solipsis@pitrou.net>
parents: 83688
diff changeset
146 }
edefd3450834 Backout c89febab4648 following private feedback by Guido.
Antoine Pitrou <solipsis@pitrou.net>
parents: 83688
diff changeset
147
edefd3450834 Backout c89febab4648 following private feedback by Guido.
Antoine Pitrou <solipsis@pitrou.net>
parents: 83688
diff changeset
148 return result;
32175
8ee5a56b8031 Patch #957398: Add public API for Generator Object/Type.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
149 }
8ee5a56b8031 Patch #957398: Add public API for Generator Object/Type.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
150
35298
b2fe5f8fcfdd PEP 342 implementation. Per Guido's comments, the generator throw()
Phillip J. Eby <pje@telecommunity.com>
parents: 33386
diff changeset
151 PyDoc_STRVAR(send_doc,
37879
f731859e9b3b Merge p3yk branch with the trunk up to revision 45595. This breaks a fair
Thomas Wouters <thomas@python.org>
parents: 36866
diff changeset
152 "send(arg) -> send 'arg' into generator,\n\
f731859e9b3b Merge p3yk branch with the trunk up to revision 45595. This breaks a fair
Thomas Wouters <thomas@python.org>
parents: 36866
diff changeset
153 return next yielded value or raise StopIteration.");
35298
b2fe5f8fcfdd PEP 342 implementation. Per Guido's comments, the generator throw()
Phillip J. Eby <pje@telecommunity.com>
parents: 33386
diff changeset
154
75714
72556ff86828 perform yield from delegation by repeating YIELD_FROM opcode (closes #14230)
Benjamin Peterson <benjamin@python.org>
parents: 75481
diff changeset
155 PyObject *
72556ff86828 perform yield from delegation by repeating YIELD_FROM opcode (closes #14230)
Benjamin Peterson <benjamin@python.org>
parents: 75481
diff changeset
156 _PyGen_Send(PyGenObject *gen, PyObject *arg)
35298
b2fe5f8fcfdd PEP 342 implementation. Per Guido's comments, the generator throw()
Phillip J. Eby <pje@telecommunity.com>
parents: 33386
diff changeset
157 {
61466
cab14be0ada1 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 52892
diff changeset
158 return gen_send_ex(gen, arg, 0);
35298
b2fe5f8fcfdd PEP 342 implementation. Per Guido's comments, the generator throw()
Phillip J. Eby <pje@telecommunity.com>
parents: 33386
diff changeset
159 }
b2fe5f8fcfdd PEP 342 implementation. Per Guido's comments, the generator throw()
Phillip J. Eby <pje@telecommunity.com>
parents: 33386
diff changeset
160
b2fe5f8fcfdd PEP 342 implementation. Per Guido's comments, the generator throw()
Phillip J. Eby <pje@telecommunity.com>
parents: 33386
diff changeset
161 PyDoc_STRVAR(close_doc,
76738
b8c1cabcd115 close() doesn't take any args (closes #14717)
Benjamin Peterson <benjamin@python.org>
parents: 73010
diff changeset
162 "close() -> raise GeneratorExit inside generator.");
35298
b2fe5f8fcfdd PEP 342 implementation. Per Guido's comments, the generator throw()
Phillip J. Eby <pje@telecommunity.com>
parents: 33386
diff changeset
163
74356
d64ac9ab4cd0 Implement PEP 380 - 'yield from' (closes #11682)
Nick Coghlan <ncoghlan@gmail.com>
parents: 73011
diff changeset
164 /*
d64ac9ab4cd0 Implement PEP 380 - 'yield from' (closes #11682)
Nick Coghlan <ncoghlan@gmail.com>
parents: 73011
diff changeset
165 * This helper function is used by gen_close and gen_throw to
d64ac9ab4cd0 Implement PEP 380 - 'yield from' (closes #11682)
Nick Coghlan <ncoghlan@gmail.com>
parents: 73011
diff changeset
166 * close a subiterator being delegated to by yield-from.
d64ac9ab4cd0 Implement PEP 380 - 'yield from' (closes #11682)
Nick Coghlan <ncoghlan@gmail.com>
parents: 73011
diff changeset
167 */
d64ac9ab4cd0 Implement PEP 380 - 'yield from' (closes #11682)
Nick Coghlan <ncoghlan@gmail.com>
parents: 73011
diff changeset
168
83771
edefd3450834 Backout c89febab4648 following private feedback by Guido.
Antoine Pitrou <solipsis@pitrou.net>
parents: 83688
diff changeset
169 static int
edefd3450834 Backout c89febab4648 following private feedback by Guido.
Antoine Pitrou <solipsis@pitrou.net>
parents: 83688
diff changeset
170 gen_close_iter(PyObject *yf)
edefd3450834 Backout c89febab4648 following private feedback by Guido.
Antoine Pitrou <solipsis@pitrou.net>
parents: 83688
diff changeset
171 {
edefd3450834 Backout c89febab4648 following private feedback by Guido.
Antoine Pitrou <solipsis@pitrou.net>
parents: 83688
diff changeset
172 PyObject *retval = NULL;
edefd3450834 Backout c89febab4648 following private feedback by Guido.
Antoine Pitrou <solipsis@pitrou.net>
parents: 83688
diff changeset
173 _Py_IDENTIFIER(close);
edefd3450834 Backout c89febab4648 following private feedback by Guido.
Antoine Pitrou <solipsis@pitrou.net>
parents: 83688
diff changeset
174
edefd3450834 Backout c89febab4648 following private feedback by Guido.
Antoine Pitrou <solipsis@pitrou.net>
parents: 83688
diff changeset
175 if (PyGen_CheckExact(yf)) {
edefd3450834 Backout c89febab4648 following private feedback by Guido.
Antoine Pitrou <solipsis@pitrou.net>
parents: 83688
diff changeset
176 retval = gen_close((PyGenObject *)yf, NULL);
edefd3450834 Backout c89febab4648 following private feedback by Guido.
Antoine Pitrou <solipsis@pitrou.net>
parents: 83688
diff changeset
177 if (retval == NULL)
edefd3450834 Backout c89febab4648 following private feedback by Guido.
Antoine Pitrou <solipsis@pitrou.net>
parents: 83688
diff changeset
178 return -1;
edefd3450834 Backout c89febab4648 following private feedback by Guido.
Antoine Pitrou <solipsis@pitrou.net>
parents: 83688
diff changeset
179 } else {
edefd3450834 Backout c89febab4648 following private feedback by Guido.
Antoine Pitrou <solipsis@pitrou.net>
parents: 83688
diff changeset
180 PyObject *meth = _PyObject_GetAttrId(yf, &PyId_close);
edefd3450834 Backout c89febab4648 following private feedback by Guido.
Antoine Pitrou <solipsis@pitrou.net>
parents: 83688
diff changeset
181 if (meth == NULL) {
edefd3450834 Backout c89febab4648 following private feedback by Guido.
Antoine Pitrou <solipsis@pitrou.net>
parents: 83688
diff changeset
182 if (!PyErr_ExceptionMatches(PyExc_AttributeError))
edefd3450834 Backout c89febab4648 following private feedback by Guido.
Antoine Pitrou <solipsis@pitrou.net>
parents: 83688
diff changeset
183 PyErr_WriteUnraisable(yf);
edefd3450834 Backout c89febab4648 following private feedback by Guido.
Antoine Pitrou <solipsis@pitrou.net>
parents: 83688
diff changeset
184 PyErr_Clear();
edefd3450834 Backout c89febab4648 following private feedback by Guido.
Antoine Pitrou <solipsis@pitrou.net>
parents: 83688
diff changeset
185 } else {
edefd3450834 Backout c89febab4648 following private feedback by Guido.
Antoine Pitrou <solipsis@pitrou.net>
parents: 83688
diff changeset
186 retval = PyObject_CallFunction(meth, "");
edefd3450834 Backout c89febab4648 following private feedback by Guido.
Antoine Pitrou <solipsis@pitrou.net>
parents: 83688
diff changeset
187 Py_DECREF(meth);
edefd3450834 Backout c89febab4648 following private feedback by Guido.
Antoine Pitrou <solipsis@pitrou.net>
parents: 83688
diff changeset
188 if (retval == NULL)
edefd3450834 Backout c89febab4648 following private feedback by Guido.
Antoine Pitrou <solipsis@pitrou.net>
parents: 83688
diff changeset
189 return -1;
edefd3450834 Backout c89febab4648 following private feedback by Guido.
Antoine Pitrou <solipsis@pitrou.net>
parents: 83688
diff changeset
190 }
edefd3450834 Backout c89febab4648 following private feedback by Guido.
Antoine Pitrou <solipsis@pitrou.net>
parents: 83688
diff changeset
191 }
edefd3450834 Backout c89febab4648 following private feedback by Guido.
Antoine Pitrou <solipsis@pitrou.net>
parents: 83688
diff changeset
192 Py_XDECREF(retval);
edefd3450834 Backout c89febab4648 following private feedback by Guido.
Antoine Pitrou <solipsis@pitrou.net>
parents: 83688
diff changeset
193 return 0;
edefd3450834 Backout c89febab4648 following private feedback by Guido.
Antoine Pitrou <solipsis@pitrou.net>
parents: 83688
diff changeset
194 }
edefd3450834 Backout c89febab4648 following private feedback by Guido.
Antoine Pitrou <solipsis@pitrou.net>
parents: 83688
diff changeset
195
75714
72556ff86828 perform yield from delegation by repeating YIELD_FROM opcode (closes #14230)
Benjamin Peterson <benjamin@python.org>
parents: 75481
diff changeset
196 static PyObject *
72556ff86828 perform yield from delegation by repeating YIELD_FROM opcode (closes #14230)
Benjamin Peterson <benjamin@python.org>
parents: 75481
diff changeset
197 gen_yf(PyGenObject *gen)
72556ff86828 perform yield from delegation by repeating YIELD_FROM opcode (closes #14230)
Benjamin Peterson <benjamin@python.org>
parents: 75481
diff changeset
198 {
83771
edefd3450834 Backout c89febab4648 following private feedback by Guido.
Antoine Pitrou <solipsis@pitrou.net>
parents: 83688
diff changeset
199 PyObject *yf = NULL;
75714
72556ff86828 perform yield from delegation by repeating YIELD_FROM opcode (closes #14230)
Benjamin Peterson <benjamin@python.org>
parents: 75481
diff changeset
200 PyFrameObject *f = gen->gi_frame;
83771
edefd3450834 Backout c89febab4648 following private feedback by Guido.
Antoine Pitrou <solipsis@pitrou.net>
parents: 83688
diff changeset
201
edefd3450834 Backout c89febab4648 following private feedback by Guido.
Antoine Pitrou <solipsis@pitrou.net>
parents: 83688
diff changeset
202 if (f && f->f_stacktop) {
edefd3450834 Backout c89febab4648 following private feedback by Guido.
Antoine Pitrou <solipsis@pitrou.net>
parents: 83688
diff changeset
203 PyObject *bytecode = f->f_code->co_code;
edefd3450834 Backout c89febab4648 following private feedback by Guido.
Antoine Pitrou <solipsis@pitrou.net>
parents: 83688
diff changeset
204 unsigned char *code = (unsigned char *)PyBytes_AS_STRING(bytecode);
edefd3450834 Backout c89febab4648 following private feedback by Guido.
Antoine Pitrou <solipsis@pitrou.net>
parents: 83688
diff changeset
205
edefd3450834 Backout c89febab4648 following private feedback by Guido.
Antoine Pitrou <solipsis@pitrou.net>
parents: 83688
diff changeset
206 if (code[f->f_lasti + 1] != YIELD_FROM)
edefd3450834 Backout c89febab4648 following private feedback by Guido.
Antoine Pitrou <solipsis@pitrou.net>
parents: 83688
diff changeset
207 return NULL;
edefd3450834 Backout c89febab4648 following private feedback by Guido.
Antoine Pitrou <solipsis@pitrou.net>
parents: 83688
diff changeset
208 yf = f->f_stacktop[-1];
edefd3450834 Backout c89febab4648 following private feedback by Guido.
Antoine Pitrou <solipsis@pitrou.net>
parents: 83688
diff changeset
209 Py_INCREF(yf);
edefd3450834 Backout c89febab4648 following private feedback by Guido.
Antoine Pitrou <solipsis@pitrou.net>
parents: 83688
diff changeset
210 }
edefd3450834 Backout c89febab4648 following private feedback by Guido.
Antoine Pitrou <solipsis@pitrou.net>
parents: 83688
diff changeset
211
edefd3450834 Backout c89febab4648 following private feedback by Guido.
Antoine Pitrou <solipsis@pitrou.net>
parents: 83688
diff changeset
212 return yf;
75714
72556ff86828 perform yield from delegation by repeating YIELD_FROM opcode (closes #14230)
Benjamin Peterson <benjamin@python.org>
parents: 75481
diff changeset
213 }
74356
d64ac9ab4cd0 Implement PEP 380 - 'yield from' (closes #11682)
Nick Coghlan <ncoghlan@gmail.com>
parents: 73011
diff changeset
214
35298
b2fe5f8fcfdd PEP 342 implementation. Per Guido's comments, the generator throw()
Phillip J. Eby <pje@telecommunity.com>
parents: 33386
diff changeset
215 static PyObject *
b2fe5f8fcfdd PEP 342 implementation. Per Guido's comments, the generator throw()
Phillip J. Eby <pje@telecommunity.com>
parents: 33386
diff changeset
216 gen_close(PyGenObject *gen, PyObject *args)
b2fe5f8fcfdd PEP 342 implementation. Per Guido's comments, the generator throw()
Phillip J. Eby <pje@telecommunity.com>
parents: 33386
diff changeset
217 {
83771
edefd3450834 Backout c89febab4648 following private feedback by Guido.
Antoine Pitrou <solipsis@pitrou.net>
parents: 83688
diff changeset
218 PyObject *retval;
edefd3450834 Backout c89febab4648 following private feedback by Guido.
Antoine Pitrou <solipsis@pitrou.net>
parents: 83688
diff changeset
219 PyObject *yf = gen_yf(gen);
edefd3450834 Backout c89febab4648 following private feedback by Guido.
Antoine Pitrou <solipsis@pitrou.net>
parents: 83688
diff changeset
220 int err = 0;
74356
d64ac9ab4cd0 Implement PEP 380 - 'yield from' (closes #11682)
Nick Coghlan <ncoghlan@gmail.com>
parents: 73011
diff changeset
221
83771
edefd3450834 Backout c89febab4648 following private feedback by Guido.
Antoine Pitrou <solipsis@pitrou.net>
parents: 83688
diff changeset
222 if (yf) {
edefd3450834 Backout c89febab4648 following private feedback by Guido.
Antoine Pitrou <solipsis@pitrou.net>
parents: 83688
diff changeset
223 gen->gi_running = 1;
edefd3450834 Backout c89febab4648 following private feedback by Guido.
Antoine Pitrou <solipsis@pitrou.net>
parents: 83688
diff changeset
224 err = gen_close_iter(yf);
edefd3450834 Backout c89febab4648 following private feedback by Guido.
Antoine Pitrou <solipsis@pitrou.net>
parents: 83688
diff changeset
225 gen->gi_running = 0;
edefd3450834 Backout c89febab4648 following private feedback by Guido.
Antoine Pitrou <solipsis@pitrou.net>
parents: 83688
diff changeset
226 Py_DECREF(yf);
edefd3450834 Backout c89febab4648 following private feedback by Guido.
Antoine Pitrou <solipsis@pitrou.net>
parents: 83688
diff changeset
227 }
edefd3450834 Backout c89febab4648 following private feedback by Guido.
Antoine Pitrou <solipsis@pitrou.net>
parents: 83688
diff changeset
228 if (err == 0)
edefd3450834 Backout c89febab4648 following private feedback by Guido.
Antoine Pitrou <solipsis@pitrou.net>
parents: 83688
diff changeset
229 PyErr_SetNone(PyExc_GeneratorExit);
edefd3450834 Backout c89febab4648 following private feedback by Guido.
Antoine Pitrou <solipsis@pitrou.net>
parents: 83688
diff changeset
230 retval = gen_send_ex(gen, Py_None, 1);
edefd3450834 Backout c89febab4648 following private feedback by Guido.
Antoine Pitrou <solipsis@pitrou.net>
parents: 83688
diff changeset
231 if (retval) {
edefd3450834 Backout c89febab4648 following private feedback by Guido.
Antoine Pitrou <solipsis@pitrou.net>
parents: 83688
diff changeset
232 Py_DECREF(retval);
edefd3450834 Backout c89febab4648 following private feedback by Guido.
Antoine Pitrou <solipsis@pitrou.net>
parents: 83688
diff changeset
233 PyErr_SetString(PyExc_RuntimeError,
edefd3450834 Backout c89febab4648 following private feedback by Guido.
Antoine Pitrou <solipsis@pitrou.net>
parents: 83688
diff changeset
234 "generator ignored GeneratorExit");
61466
cab14be0ada1 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 52892
diff changeset
235 return NULL;
cab14be0ada1 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 52892
diff changeset
236 }
83771
edefd3450834 Backout c89febab4648 following private feedback by Guido.
Antoine Pitrou <solipsis@pitrou.net>
parents: 83688
diff changeset
237 if (PyErr_ExceptionMatches(PyExc_StopIteration)
edefd3450834 Backout c89febab4648 following private feedback by Guido.
Antoine Pitrou <solipsis@pitrou.net>
parents: 83688
diff changeset
238 || PyErr_ExceptionMatches(PyExc_GeneratorExit)) {
edefd3450834 Backout c89febab4648 following private feedback by Guido.
Antoine Pitrou <solipsis@pitrou.net>
parents: 83688
diff changeset
239 PyErr_Clear(); /* ignore these errors */
edefd3450834 Backout c89febab4648 following private feedback by Guido.
Antoine Pitrou <solipsis@pitrou.net>
parents: 83688
diff changeset
240 Py_INCREF(Py_None);
edefd3450834 Backout c89febab4648 following private feedback by Guido.
Antoine Pitrou <solipsis@pitrou.net>
parents: 83688
diff changeset
241 return Py_None;
edefd3450834 Backout c89febab4648 following private feedback by Guido.
Antoine Pitrou <solipsis@pitrou.net>
parents: 83688
diff changeset
242 }
edefd3450834 Backout c89febab4648 following private feedback by Guido.
Antoine Pitrou <solipsis@pitrou.net>
parents: 83688
diff changeset
243 return NULL;
edefd3450834 Backout c89febab4648 following private feedback by Guido.
Antoine Pitrou <solipsis@pitrou.net>
parents: 83688
diff changeset
244 }
edefd3450834 Backout c89febab4648 following private feedback by Guido.
Antoine Pitrou <solipsis@pitrou.net>
parents: 83688
diff changeset
245
edefd3450834 Backout c89febab4648 following private feedback by Guido.
Antoine Pitrou <solipsis@pitrou.net>
parents: 83688
diff changeset
246
35298
b2fe5f8fcfdd PEP 342 implementation. Per Guido's comments, the generator throw()
Phillip J. Eby <pje@telecommunity.com>
parents: 33386
diff changeset
247 PyDoc_STRVAR(throw_doc,
37879
f731859e9b3b Merge p3yk branch with the trunk up to revision 45595. This breaks a fair
Thomas Wouters <thomas@python.org>
parents: 36866
diff changeset
248 "throw(typ[,val[,tb]]) -> raise exception in generator,\n\
f731859e9b3b Merge p3yk branch with the trunk up to revision 45595. This breaks a fair
Thomas Wouters <thomas@python.org>
parents: 36866
diff changeset
249 return next yielded value or raise StopIteration.");
35298
b2fe5f8fcfdd PEP 342 implementation. Per Guido's comments, the generator throw()
Phillip J. Eby <pje@telecommunity.com>
parents: 33386
diff changeset
250
b2fe5f8fcfdd PEP 342 implementation. Per Guido's comments, the generator throw()
Phillip J. Eby <pje@telecommunity.com>
parents: 33386
diff changeset
251 static PyObject *
37879
f731859e9b3b Merge p3yk branch with the trunk up to revision 45595. This breaks a fair
Thomas Wouters <thomas@python.org>
parents: 36866
diff changeset
252 gen_throw(PyGenObject *gen, PyObject *args)
35298
b2fe5f8fcfdd PEP 342 implementation. Per Guido's comments, the generator throw()
Phillip J. Eby <pje@telecommunity.com>
parents: 33386
diff changeset
253 {
61466
cab14be0ada1 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 52892
diff changeset
254 PyObject *typ;
cab14be0ada1 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 52892
diff changeset
255 PyObject *tb = NULL;
cab14be0ada1 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 52892
diff changeset
256 PyObject *val = NULL;
75714
72556ff86828 perform yield from delegation by repeating YIELD_FROM opcode (closes #14230)
Benjamin Peterson <benjamin@python.org>
parents: 75481
diff changeset
257 PyObject *yf = gen_yf(gen);
77477
438b861e2edb Issue #13783: PEP 380 cleanup part 2, using the new identifier APIs in the generator implementation
Nick Coghlan <ncoghlan@gmail.com>
parents: 77476
diff changeset
258 _Py_IDENTIFIER(throw);
35298
b2fe5f8fcfdd PEP 342 implementation. Per Guido's comments, the generator throw()
Phillip J. Eby <pje@telecommunity.com>
parents: 33386
diff changeset
259
61466
cab14be0ada1 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 52892
diff changeset
260 if (!PyArg_UnpackTuple(args, "throw", 1, 3, &typ, &val, &tb))
cab14be0ada1 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 52892
diff changeset
261 return NULL;
35298
b2fe5f8fcfdd PEP 342 implementation. Per Guido's comments, the generator throw()
Phillip J. Eby <pje@telecommunity.com>
parents: 33386
diff changeset
262
74356
d64ac9ab4cd0 Implement PEP 380 - 'yield from' (closes #11682)
Nick Coghlan <ncoghlan@gmail.com>
parents: 73011
diff changeset
263 if (yf) {
d64ac9ab4cd0 Implement PEP 380 - 'yield from' (closes #11682)
Nick Coghlan <ncoghlan@gmail.com>
parents: 73011
diff changeset
264 PyObject *ret;
d64ac9ab4cd0 Implement PEP 380 - 'yield from' (closes #11682)
Nick Coghlan <ncoghlan@gmail.com>
parents: 73011
diff changeset
265 int err;
d64ac9ab4cd0 Implement PEP 380 - 'yield from' (closes #11682)
Nick Coghlan <ncoghlan@gmail.com>
parents: 73011
diff changeset
266 if (PyErr_GivenExceptionMatches(typ, PyExc_GeneratorExit)) {
75714
72556ff86828 perform yield from delegation by repeating YIELD_FROM opcode (closes #14230)
Benjamin Peterson <benjamin@python.org>
parents: 75481
diff changeset
267 gen->gi_running = 1;
83771
edefd3450834 Backout c89febab4648 following private feedback by Guido.
Antoine Pitrou <solipsis@pitrou.net>
parents: 83688
diff changeset
268 err = gen_close_iter(yf);
75714
72556ff86828 perform yield from delegation by repeating YIELD_FROM opcode (closes #14230)
Benjamin Peterson <benjamin@python.org>
parents: 75481
diff changeset
269 gen->gi_running = 0;
74356
d64ac9ab4cd0 Implement PEP 380 - 'yield from' (closes #11682)
Nick Coghlan <ncoghlan@gmail.com>
parents: 73011
diff changeset
270 Py_DECREF(yf);
d64ac9ab4cd0 Implement PEP 380 - 'yield from' (closes #11682)
Nick Coghlan <ncoghlan@gmail.com>
parents: 73011
diff changeset
271 if (err < 0)
d64ac9ab4cd0 Implement PEP 380 - 'yield from' (closes #11682)
Nick Coghlan <ncoghlan@gmail.com>
parents: 73011
diff changeset
272 return gen_send_ex(gen, Py_None, 1);
d64ac9ab4cd0 Implement PEP 380 - 'yield from' (closes #11682)
Nick Coghlan <ncoghlan@gmail.com>
parents: 73011
diff changeset
273 goto throw_here;
d64ac9ab4cd0 Implement PEP 380 - 'yield from' (closes #11682)
Nick Coghlan <ncoghlan@gmail.com>
parents: 73011
diff changeset
274 }
d64ac9ab4cd0 Implement PEP 380 - 'yield from' (closes #11682)
Nick Coghlan <ncoghlan@gmail.com>
parents: 73011
diff changeset
275 if (PyGen_CheckExact(yf)) {
75714
72556ff86828 perform yield from delegation by repeating YIELD_FROM opcode (closes #14230)
Benjamin Peterson <benjamin@python.org>
parents: 75481
diff changeset
276 gen->gi_running = 1;
74356
d64ac9ab4cd0 Implement PEP 380 - 'yield from' (closes #11682)
Nick Coghlan <ncoghlan@gmail.com>
parents: 73011
diff changeset
277 ret = gen_throw((PyGenObject *)yf, args);
75714
72556ff86828 perform yield from delegation by repeating YIELD_FROM opcode (closes #14230)
Benjamin Peterson <benjamin@python.org>
parents: 75481
diff changeset
278 gen->gi_running = 0;
74356
d64ac9ab4cd0 Implement PEP 380 - 'yield from' (closes #11682)
Nick Coghlan <ncoghlan@gmail.com>
parents: 73011
diff changeset
279 } else {
77477
438b861e2edb Issue #13783: PEP 380 cleanup part 2, using the new identifier APIs in the generator implementation
Nick Coghlan <ncoghlan@gmail.com>
parents: 77476
diff changeset
280 PyObject *meth = _PyObject_GetAttrId(yf, &PyId_throw);
74356
d64ac9ab4cd0 Implement PEP 380 - 'yield from' (closes #11682)
Nick Coghlan <ncoghlan@gmail.com>
parents: 73011
diff changeset
281 if (meth == NULL) {
d64ac9ab4cd0 Implement PEP 380 - 'yield from' (closes #11682)
Nick Coghlan <ncoghlan@gmail.com>
parents: 73011
diff changeset
282 if (!PyErr_ExceptionMatches(PyExc_AttributeError)) {
d64ac9ab4cd0 Implement PEP 380 - 'yield from' (closes #11682)
Nick Coghlan <ncoghlan@gmail.com>
parents: 73011
diff changeset
283 Py_DECREF(yf);
d64ac9ab4cd0 Implement PEP 380 - 'yield from' (closes #11682)
Nick Coghlan <ncoghlan@gmail.com>
parents: 73011
diff changeset
284 return NULL;
d64ac9ab4cd0 Implement PEP 380 - 'yield from' (closes #11682)
Nick Coghlan <ncoghlan@gmail.com>
parents: 73011
diff changeset
285 }
d64ac9ab4cd0 Implement PEP 380 - 'yield from' (closes #11682)
Nick Coghlan <ncoghlan@gmail.com>
parents: 73011
diff changeset
286 PyErr_Clear();
d64ac9ab4cd0 Implement PEP 380 - 'yield from' (closes #11682)
Nick Coghlan <ncoghlan@gmail.com>
parents: 73011
diff changeset
287 Py_DECREF(yf);
d64ac9ab4cd0 Implement PEP 380 - 'yield from' (closes #11682)
Nick Coghlan <ncoghlan@gmail.com>
parents: 73011
diff changeset
288 goto throw_here;
d64ac9ab4cd0 Implement PEP 380 - 'yield from' (closes #11682)
Nick Coghlan <ncoghlan@gmail.com>
parents: 73011
diff changeset
289 }
75714
72556ff86828 perform yield from delegation by repeating YIELD_FROM opcode (closes #14230)
Benjamin Peterson <benjamin@python.org>
parents: 75481
diff changeset
290 gen->gi_running = 1;
74356
d64ac9ab4cd0 Implement PEP 380 - 'yield from' (closes #11682)
Nick Coghlan <ncoghlan@gmail.com>
parents: 73011
diff changeset
291 ret = PyObject_CallObject(meth, args);
75714
72556ff86828 perform yield from delegation by repeating YIELD_FROM opcode (closes #14230)
Benjamin Peterson <benjamin@python.org>
parents: 75481
diff changeset
292 gen->gi_running = 0;
74356
d64ac9ab4cd0 Implement PEP 380 - 'yield from' (closes #11682)
Nick Coghlan <ncoghlan@gmail.com>
parents: 73011
diff changeset
293 Py_DECREF(meth);
d64ac9ab4cd0 Implement PEP 380 - 'yield from' (closes #11682)
Nick Coghlan <ncoghlan@gmail.com>
parents: 73011
diff changeset
294 }
d64ac9ab4cd0 Implement PEP 380 - 'yield from' (closes #11682)
Nick Coghlan <ncoghlan@gmail.com>
parents: 73011
diff changeset
295 Py_DECREF(yf);
d64ac9ab4cd0 Implement PEP 380 - 'yield from' (closes #11682)
Nick Coghlan <ncoghlan@gmail.com>
parents: 73011
diff changeset
296 if (!ret) {
d64ac9ab4cd0 Implement PEP 380 - 'yield from' (closes #11682)
Nick Coghlan <ncoghlan@gmail.com>
parents: 73011
diff changeset
297 PyObject *val;
75714
72556ff86828 perform yield from delegation by repeating YIELD_FROM opcode (closes #14230)
Benjamin Peterson <benjamin@python.org>
parents: 75481
diff changeset
298 /* Pop subiterator from stack */
72556ff86828 perform yield from delegation by repeating YIELD_FROM opcode (closes #14230)
Benjamin Peterson <benjamin@python.org>
parents: 75481
diff changeset
299 ret = *(--gen->gi_frame->f_stacktop);
72556ff86828 perform yield from delegation by repeating YIELD_FROM opcode (closes #14230)
Benjamin Peterson <benjamin@python.org>
parents: 75481
diff changeset
300 assert(ret == yf);
72556ff86828 perform yield from delegation by repeating YIELD_FROM opcode (closes #14230)
Benjamin Peterson <benjamin@python.org>
parents: 75481
diff changeset
301 Py_DECREF(ret);
72556ff86828 perform yield from delegation by repeating YIELD_FROM opcode (closes #14230)
Benjamin Peterson <benjamin@python.org>
parents: 75481
diff changeset
302 /* Termination repetition of YIELD_FROM */
72556ff86828 perform yield from delegation by repeating YIELD_FROM opcode (closes #14230)
Benjamin Peterson <benjamin@python.org>
parents: 75481
diff changeset
303 gen->gi_frame->f_lasti++;
77476
cfbf6aa5c9e3 Issue #13783: the PEP 380 implementation no longer expands the public C API
Nick Coghlan <ncoghlan@gmail.com>
parents: 76740
diff changeset
304 if (_PyGen_FetchStopIterationValue(&val) == 0) {
74356
d64ac9ab4cd0 Implement PEP 380 - 'yield from' (closes #11682)
Nick Coghlan <ncoghlan@gmail.com>
parents: 73011
diff changeset
305 ret = gen_send_ex(gen, val, 0);
d64ac9ab4cd0 Implement PEP 380 - 'yield from' (closes #11682)
Nick Coghlan <ncoghlan@gmail.com>
parents: 73011
diff changeset
306 Py_DECREF(val);
d64ac9ab4cd0 Implement PEP 380 - 'yield from' (closes #11682)
Nick Coghlan <ncoghlan@gmail.com>
parents: 73011
diff changeset
307 } else {
d64ac9ab4cd0 Implement PEP 380 - 'yield from' (closes #11682)
Nick Coghlan <ncoghlan@gmail.com>
parents: 73011
diff changeset
308 ret = gen_send_ex(gen, Py_None, 1);
d64ac9ab4cd0 Implement PEP 380 - 'yield from' (closes #11682)
Nick Coghlan <ncoghlan@gmail.com>
parents: 73011
diff changeset
309 }
d64ac9ab4cd0 Implement PEP 380 - 'yield from' (closes #11682)
Nick Coghlan <ncoghlan@gmail.com>
parents: 73011
diff changeset
310 }
d64ac9ab4cd0 Implement PEP 380 - 'yield from' (closes #11682)
Nick Coghlan <ncoghlan@gmail.com>
parents: 73011
diff changeset
311 return ret;
d64ac9ab4cd0 Implement PEP 380 - 'yield from' (closes #11682)
Nick Coghlan <ncoghlan@gmail.com>
parents: 73011
diff changeset
312 }
d64ac9ab4cd0 Implement PEP 380 - 'yield from' (closes #11682)
Nick Coghlan <ncoghlan@gmail.com>
parents: 73011
diff changeset
313
d64ac9ab4cd0 Implement PEP 380 - 'yield from' (closes #11682)
Nick Coghlan <ncoghlan@gmail.com>
parents: 73011
diff changeset
314 throw_here:
61466
cab14be0ada1 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 52892
diff changeset
315 /* First, check the traceback argument, replacing None with
cab14be0ada1 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 52892
diff changeset
316 NULL. */
73010
9c79a25f4a8b adjust braces a bit
Benjamin Peterson <benjamin@python.org>
parents: 72972
diff changeset
317 if (tb == Py_None) {
61466
cab14be0ada1 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 52892
diff changeset
318 tb = NULL;
73010
9c79a25f4a8b adjust braces a bit
Benjamin Peterson <benjamin@python.org>
parents: 72972
diff changeset
319 }
61466
cab14be0ada1 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 52892
diff changeset
320 else if (tb != NULL && !PyTraceBack_Check(tb)) {
cab14be0ada1 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 52892
diff changeset
321 PyErr_SetString(PyExc_TypeError,
cab14be0ada1 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 52892
diff changeset
322 "throw() third argument must be a traceback object");
cab14be0ada1 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 52892
diff changeset
323 return NULL;
cab14be0ada1 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 52892
diff changeset
324 }
35298
b2fe5f8fcfdd PEP 342 implementation. Per Guido's comments, the generator throw()
Phillip J. Eby <pje@telecommunity.com>
parents: 33386
diff changeset
325
61466
cab14be0ada1 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 52892
diff changeset
326 Py_INCREF(typ);
cab14be0ada1 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 52892
diff changeset
327 Py_XINCREF(val);
cab14be0ada1 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 52892
diff changeset
328 Py_XINCREF(tb);
35298
b2fe5f8fcfdd PEP 342 implementation. Per Guido's comments, the generator throw()
Phillip J. Eby <pje@telecommunity.com>
parents: 33386
diff changeset
329
73010
9c79a25f4a8b adjust braces a bit
Benjamin Peterson <benjamin@python.org>
parents: 72972
diff changeset
330 if (PyExceptionClass_Check(typ))
61466
cab14be0ada1 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 52892
diff changeset
331 PyErr_NormalizeException(&typ, &val, &tb);
35298
b2fe5f8fcfdd PEP 342 implementation. Per Guido's comments, the generator throw()
Phillip J. Eby <pje@telecommunity.com>
parents: 33386
diff changeset
332
61466
cab14be0ada1 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 52892
diff changeset
333 else if (PyExceptionInstance_Check(typ)) {
cab14be0ada1 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 52892
diff changeset
334 /* Raising an instance. The value should be a dummy. */
cab14be0ada1 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 52892
diff changeset
335 if (val && val != Py_None) {
cab14be0ada1 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 52892
diff changeset
336 PyErr_SetString(PyExc_TypeError,
cab14be0ada1 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 52892
diff changeset
337 "instance exception may not have a separate value");
cab14be0ada1 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 52892
diff changeset
338 goto failed_throw;
cab14be0ada1 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 52892
diff changeset
339 }
cab14be0ada1 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 52892
diff changeset
340 else {
cab14be0ada1 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 52892
diff changeset
341 /* Normalize to raise <class>, <instance> */
cab14be0ada1 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 52892
diff changeset
342 Py_XDECREF(val);
cab14be0ada1 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 52892
diff changeset
343 val = typ;
cab14be0ada1 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 52892
diff changeset
344 typ = PyExceptionInstance_Class(typ);
cab14be0ada1 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 52892
diff changeset
345 Py_INCREF(typ);
72972
dcf5cc88d5c9 Issue #13188: When called without an explicit traceback argument,
Antoine Pitrou <solipsis@pitrou.net>
parents: 71980
diff changeset
346
73010
9c79a25f4a8b adjust braces a bit
Benjamin Peterson <benjamin@python.org>
parents: 72972
diff changeset
347 if (tb == NULL)
72972
dcf5cc88d5c9 Issue #13188: When called without an explicit traceback argument,
Antoine Pitrou <solipsis@pitrou.net>
parents: 71980
diff changeset
348 /* Returns NULL if there's no traceback */
dcf5cc88d5c9 Issue #13188: When called without an explicit traceback argument,
Antoine Pitrou <solipsis@pitrou.net>
parents: 71980
diff changeset
349 tb = PyException_GetTraceback(val);
61466
cab14be0ada1 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 52892
diff changeset
350 }
cab14be0ada1 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 52892
diff changeset
351 }
cab14be0ada1 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 52892
diff changeset
352 else {
cab14be0ada1 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 52892
diff changeset
353 /* Not something you can raise. throw() fails. */
cab14be0ada1 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 52892
diff changeset
354 PyErr_Format(PyExc_TypeError,
cab14be0ada1 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 52892
diff changeset
355 "exceptions must be classes or instances "
cab14be0ada1 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 52892
diff changeset
356 "deriving from BaseException, not %s",
74356
d64ac9ab4cd0 Implement PEP 380 - 'yield from' (closes #11682)
Nick Coghlan <ncoghlan@gmail.com>
parents: 73011
diff changeset
357 Py_TYPE(typ)->tp_name);
61466
cab14be0ada1 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 52892
diff changeset
358 goto failed_throw;
cab14be0ada1 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 52892
diff changeset
359 }
35298
b2fe5f8fcfdd PEP 342 implementation. Per Guido's comments, the generator throw()
Phillip J. Eby <pje@telecommunity.com>
parents: 33386
diff changeset
360
61466
cab14be0ada1 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 52892
diff changeset
361 PyErr_Restore(typ, val, tb);
cab14be0ada1 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 52892
diff changeset
362 return gen_send_ex(gen, Py_None, 1);
35298
b2fe5f8fcfdd PEP 342 implementation. Per Guido's comments, the generator throw()
Phillip J. Eby <pje@telecommunity.com>
parents: 33386
diff changeset
363
b2fe5f8fcfdd PEP 342 implementation. Per Guido's comments, the generator throw()
Phillip J. Eby <pje@telecommunity.com>
parents: 33386
diff changeset
364 failed_throw:
61466
cab14be0ada1 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 52892
diff changeset
365 /* Didn't use our arguments, so restore their original refcounts */
cab14be0ada1 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 52892
diff changeset
366 Py_DECREF(typ);
cab14be0ada1 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 52892
diff changeset
367 Py_XDECREF(val);
cab14be0ada1 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 52892
diff changeset
368 Py_XDECREF(tb);
cab14be0ada1 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 52892
diff changeset
369 return NULL;
35298
b2fe5f8fcfdd PEP 342 implementation. Per Guido's comments, the generator throw()
Phillip J. Eby <pje@telecommunity.com>
parents: 33386
diff changeset
370 }
b2fe5f8fcfdd PEP 342 implementation. Per Guido's comments, the generator throw()
Phillip J. Eby <pje@telecommunity.com>
parents: 33386
diff changeset
371
b2fe5f8fcfdd PEP 342 implementation. Per Guido's comments, the generator throw()
Phillip J. Eby <pje@telecommunity.com>
parents: 33386
diff changeset
372
b2fe5f8fcfdd PEP 342 implementation. Per Guido's comments, the generator throw()
Phillip J. Eby <pje@telecommunity.com>
parents: 33386
diff changeset
373 static PyObject *
b2fe5f8fcfdd PEP 342 implementation. Per Guido's comments, the generator throw()
Phillip J. Eby <pje@telecommunity.com>
parents: 33386
diff changeset
374 gen_iternext(PyGenObject *gen)
b2fe5f8fcfdd PEP 342 implementation. Per Guido's comments, the generator throw()
Phillip J. Eby <pje@telecommunity.com>
parents: 33386
diff changeset
375 {
74356
d64ac9ab4cd0 Implement PEP 380 - 'yield from' (closes #11682)
Nick Coghlan <ncoghlan@gmail.com>
parents: 73011
diff changeset
376 PyObject *val = NULL;
d64ac9ab4cd0 Implement PEP 380 - 'yield from' (closes #11682)
Nick Coghlan <ncoghlan@gmail.com>
parents: 73011
diff changeset
377 PyObject *ret;
75714
72556ff86828 perform yield from delegation by repeating YIELD_FROM opcode (closes #14230)
Benjamin Peterson <benjamin@python.org>
parents: 75481
diff changeset
378 ret = gen_send_ex(gen, val, 0);
74356
d64ac9ab4cd0 Implement PEP 380 - 'yield from' (closes #11682)
Nick Coghlan <ncoghlan@gmail.com>
parents: 73011
diff changeset
379 Py_XDECREF(val);
d64ac9ab4cd0 Implement PEP 380 - 'yield from' (closes #11682)
Nick Coghlan <ncoghlan@gmail.com>
parents: 73011
diff changeset
380 return ret;
35298
b2fe5f8fcfdd PEP 342 implementation. Per Guido's comments, the generator throw()
Phillip J. Eby <pje@telecommunity.com>
parents: 33386
diff changeset
381 }
b2fe5f8fcfdd PEP 342 implementation. Per Guido's comments, the generator throw()
Phillip J. Eby <pje@telecommunity.com>
parents: 33386
diff changeset
382
74356
d64ac9ab4cd0 Implement PEP 380 - 'yield from' (closes #11682)
Nick Coghlan <ncoghlan@gmail.com>
parents: 73011
diff changeset
383 /*
d64ac9ab4cd0 Implement PEP 380 - 'yield from' (closes #11682)
Nick Coghlan <ncoghlan@gmail.com>
parents: 73011
diff changeset
384 * If StopIteration exception is set, fetches its 'value'
d64ac9ab4cd0 Implement PEP 380 - 'yield from' (closes #11682)
Nick Coghlan <ncoghlan@gmail.com>
parents: 73011
diff changeset
385 * attribute if any, otherwise sets pvalue to None.
d64ac9ab4cd0 Implement PEP 380 - 'yield from' (closes #11682)
Nick Coghlan <ncoghlan@gmail.com>
parents: 73011
diff changeset
386 *
d64ac9ab4cd0 Implement PEP 380 - 'yield from' (closes #11682)
Nick Coghlan <ncoghlan@gmail.com>
parents: 73011
diff changeset
387 * Returns 0 if no exception or StopIteration is set.
d64ac9ab4cd0 Implement PEP 380 - 'yield from' (closes #11682)
Nick Coghlan <ncoghlan@gmail.com>
parents: 73011
diff changeset
388 * If any other exception is set, returns -1 and leaves
d64ac9ab4cd0 Implement PEP 380 - 'yield from' (closes #11682)
Nick Coghlan <ncoghlan@gmail.com>
parents: 73011
diff changeset
389 * pvalue unchanged.
d64ac9ab4cd0 Implement PEP 380 - 'yield from' (closes #11682)
Nick Coghlan <ncoghlan@gmail.com>
parents: 73011
diff changeset
390 */
d64ac9ab4cd0 Implement PEP 380 - 'yield from' (closes #11682)
Nick Coghlan <ncoghlan@gmail.com>
parents: 73011
diff changeset
391
d64ac9ab4cd0 Implement PEP 380 - 'yield from' (closes #11682)
Nick Coghlan <ncoghlan@gmail.com>
parents: 73011
diff changeset
392 int
77476
cfbf6aa5c9e3 Issue #13783: the PEP 380 implementation no longer expands the public C API
Nick Coghlan <ncoghlan@gmail.com>
parents: 76740
diff changeset
393 _PyGen_FetchStopIterationValue(PyObject **pvalue) {
74356
d64ac9ab4cd0 Implement PEP 380 - 'yield from' (closes #11682)
Nick Coghlan <ncoghlan@gmail.com>
parents: 73011
diff changeset
394 PyObject *et, *ev, *tb;
d64ac9ab4cd0 Implement PEP 380 - 'yield from' (closes #11682)
Nick Coghlan <ncoghlan@gmail.com>
parents: 73011
diff changeset
395 PyObject *value = NULL;
75714
72556ff86828 perform yield from delegation by repeating YIELD_FROM opcode (closes #14230)
Benjamin Peterson <benjamin@python.org>
parents: 75481
diff changeset
396
74356
d64ac9ab4cd0 Implement PEP 380 - 'yield from' (closes #11682)
Nick Coghlan <ncoghlan@gmail.com>
parents: 73011
diff changeset
397 if (PyErr_ExceptionMatches(PyExc_StopIteration)) {
d64ac9ab4cd0 Implement PEP 380 - 'yield from' (closes #11682)
Nick Coghlan <ncoghlan@gmail.com>
parents: 73011
diff changeset
398 PyErr_Fetch(&et, &ev, &tb);
d64ac9ab4cd0 Implement PEP 380 - 'yield from' (closes #11682)
Nick Coghlan <ncoghlan@gmail.com>
parents: 73011
diff changeset
399 Py_XDECREF(et);
d64ac9ab4cd0 Implement PEP 380 - 'yield from' (closes #11682)
Nick Coghlan <ncoghlan@gmail.com>
parents: 73011
diff changeset
400 Py_XDECREF(tb);
d64ac9ab4cd0 Implement PEP 380 - 'yield from' (closes #11682)
Nick Coghlan <ncoghlan@gmail.com>
parents: 73011
diff changeset
401 if (ev) {
d64ac9ab4cd0 Implement PEP 380 - 'yield from' (closes #11682)
Nick Coghlan <ncoghlan@gmail.com>
parents: 73011
diff changeset
402 value = ((PyStopIterationObject *)ev)->value;
74366
9e9c1be433d7 Fix a crash when the return value of a subgenerator is a temporary
Amaury Forgeot d'Arc <amauryfa@gmail.com>
parents: 74356
diff changeset
403 Py_INCREF(value);
74356
d64ac9ab4cd0 Implement PEP 380 - 'yield from' (closes #11682)
Nick Coghlan <ncoghlan@gmail.com>
parents: 73011
diff changeset
404 Py_DECREF(ev);
d64ac9ab4cd0 Implement PEP 380 - 'yield from' (closes #11682)
Nick Coghlan <ncoghlan@gmail.com>
parents: 73011
diff changeset
405 }
d64ac9ab4cd0 Implement PEP 380 - 'yield from' (closes #11682)
Nick Coghlan <ncoghlan@gmail.com>
parents: 73011
diff changeset
406 } else if (PyErr_Occurred()) {
d64ac9ab4cd0 Implement PEP 380 - 'yield from' (closes #11682)
Nick Coghlan <ncoghlan@gmail.com>
parents: 73011
diff changeset
407 return -1;
d64ac9ab4cd0 Implement PEP 380 - 'yield from' (closes #11682)
Nick Coghlan <ncoghlan@gmail.com>
parents: 73011
diff changeset
408 }
d64ac9ab4cd0 Implement PEP 380 - 'yield from' (closes #11682)
Nick Coghlan <ncoghlan@gmail.com>
parents: 73011
diff changeset
409 if (value == NULL) {
d64ac9ab4cd0 Implement PEP 380 - 'yield from' (closes #11682)
Nick Coghlan <ncoghlan@gmail.com>
parents: 73011
diff changeset
410 value = Py_None;
74366
9e9c1be433d7 Fix a crash when the return value of a subgenerator is a temporary
Amaury Forgeot d'Arc <amauryfa@gmail.com>
parents: 74356
diff changeset
411 Py_INCREF(value);
74356
d64ac9ab4cd0 Implement PEP 380 - 'yield from' (closes #11682)
Nick Coghlan <ncoghlan@gmail.com>
parents: 73011
diff changeset
412 }
d64ac9ab4cd0 Implement PEP 380 - 'yield from' (closes #11682)
Nick Coghlan <ncoghlan@gmail.com>
parents: 73011
diff changeset
413 *pvalue = value;
d64ac9ab4cd0 Implement PEP 380 - 'yield from' (closes #11682)
Nick Coghlan <ncoghlan@gmail.com>
parents: 73011
diff changeset
414 return 0;
d64ac9ab4cd0 Implement PEP 380 - 'yield from' (closes #11682)
Nick Coghlan <ncoghlan@gmail.com>
parents: 73011
diff changeset
415 }
35298
b2fe5f8fcfdd PEP 342 implementation. Per Guido's comments, the generator throw()
Phillip J. Eby <pje@telecommunity.com>
parents: 33386
diff changeset
416
47082
b630729571e6 Merged revisions 63208-63209,63211-63212,63214-63217,63219-63224,63226-63227,63229-63232,63234-63235,63237-63239,63241,63243-63246,63250-63254,63256-63259,63261,63263-63264,63266-63267,63269-63270,63272-63273,63275-63276,63278,63280-63281,63283-63284,63286-63287,63289-63290,63292-63293,63295-63296,63298-63299,63301-63302,63304-63305,63307,63309-63314,63316-63322,63324-63325,63327-63335,63337-63338,63340-63342,63344-63346,63348 via svnmerge from
Alexandre Vassalotti <alexandre@peadrop.com>
parents: 44999
diff changeset
417 static PyObject *
b630729571e6 Merged revisions 63208-63209,63211-63212,63214-63217,63219-63224,63226-63227,63229-63232,63234-63235,63237-63239,63241,63243-63246,63250-63254,63256-63259,63261,63263-63264,63266-63267,63269-63270,63272-63273,63275-63276,63278,63280-63281,63283-63284,63286-63287,63289-63290,63292-63293,63295-63296,63298-63299,63301-63302,63304-63305,63307,63309-63314,63316-63322,63324-63325,63327-63335,63337-63338,63340-63342,63344-63346,63348 via svnmerge from
Alexandre Vassalotti <alexandre@peadrop.com>
parents: 44999
diff changeset
418 gen_repr(PyGenObject *gen)
b630729571e6 Merged revisions 63208-63209,63211-63212,63214-63217,63219-63224,63226-63227,63229-63232,63234-63235,63237-63239,63241,63243-63246,63250-63254,63256-63259,63261,63263-63264,63266-63267,63269-63270,63272-63273,63275-63276,63278,63280-63281,63283-63284,63286-63287,63289-63290,63292-63293,63295-63296,63298-63299,63301-63302,63304-63305,63307,63309-63314,63316-63322,63324-63325,63327-63335,63337-63338,63340-63342,63344-63346,63348 via svnmerge from
Alexandre Vassalotti <alexandre@peadrop.com>
parents: 44999
diff changeset
419 {
61466
cab14be0ada1 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 52892
diff changeset
420 return PyUnicode_FromFormat("<generator object %S at %p>",
cab14be0ada1 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 52892
diff changeset
421 ((PyCodeObject *)gen->gi_code)->co_name,
cab14be0ada1 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 52892
diff changeset
422 gen);
47082
b630729571e6 Merged revisions 63208-63209,63211-63212,63214-63217,63219-63224,63226-63227,63229-63232,63234-63235,63237-63239,63241,63243-63246,63250-63254,63256-63259,63261,63263-63264,63266-63267,63269-63270,63272-63273,63275-63276,63278,63280-63281,63283-63284,63286-63287,63289-63290,63292-63293,63295-63296,63298-63299,63301-63302,63304-63305,63307,63309-63314,63316-63322,63324-63325,63327-63335,63337-63338,63340-63342,63344-63346,63348 via svnmerge from
Alexandre Vassalotti <alexandre@peadrop.com>
parents: 44999
diff changeset
423 }
b630729571e6 Merged revisions 63208-63209,63211-63212,63214-63217,63219-63224,63226-63227,63229-63232,63234-63235,63237-63239,63241,63243-63246,63250-63254,63256-63259,63261,63263-63264,63266-63267,63269-63270,63272-63273,63275-63276,63278,63280-63281,63283-63284,63286-63287,63289-63290,63292-63293,63295-63296,63298-63299,63301-63302,63304-63305,63307,63309-63314,63316-63322,63324-63325,63327-63335,63337-63338,63340-63342,63344-63346,63348 via svnmerge from
Alexandre Vassalotti <alexandre@peadrop.com>
parents: 44999
diff changeset
424
b630729571e6 Merged revisions 63208-63209,63211-63212,63214-63217,63219-63224,63226-63227,63229-63232,63234-63235,63237-63239,63241,63243-63246,63250-63254,63256-63259,63261,63263-63264,63266-63267,63269-63270,63272-63273,63275-63276,63278,63280-63281,63283-63284,63286-63287,63289-63290,63292-63293,63295-63296,63298-63299,63301-63302,63304-63305,63307,63309-63314,63316-63322,63324-63325,63327-63335,63337-63338,63340-63342,63344-63346,63348 via svnmerge from
Alexandre Vassalotti <alexandre@peadrop.com>
parents: 44999
diff changeset
425
b630729571e6 Merged revisions 63208-63209,63211-63212,63214-63217,63219-63224,63226-63227,63229-63232,63234-63235,63237-63239,63241,63243-63246,63250-63254,63256-63259,63261,63263-63264,63266-63267,63269-63270,63272-63273,63275-63276,63278,63280-63281,63283-63284,63286-63287,63289-63290,63292-63293,63295-63296,63298-63299,63301-63302,63304-63305,63307,63309-63314,63316-63322,63324-63325,63327-63335,63337-63338,63340-63342,63344-63346,63348 via svnmerge from
Alexandre Vassalotti <alexandre@peadrop.com>
parents: 44999
diff changeset
426 static PyObject *
b630729571e6 Merged revisions 63208-63209,63211-63212,63214-63217,63219-63224,63226-63227,63229-63232,63234-63235,63237-63239,63241,63243-63246,63250-63254,63256-63259,63261,63263-63264,63266-63267,63269-63270,63272-63273,63275-63276,63278,63280-63281,63283-63284,63286-63287,63289-63290,63292-63293,63295-63296,63298-63299,63301-63302,63304-63305,63307,63309-63314,63316-63322,63324-63325,63327-63335,63337-63338,63340-63342,63344-63346,63348 via svnmerge from
Alexandre Vassalotti <alexandre@peadrop.com>
parents: 44999
diff changeset
427 gen_get_name(PyGenObject *gen)
b630729571e6 Merged revisions 63208-63209,63211-63212,63214-63217,63219-63224,63226-63227,63229-63232,63234-63235,63237-63239,63241,63243-63246,63250-63254,63256-63259,63261,63263-63264,63266-63267,63269-63270,63272-63273,63275-63276,63278,63280-63281,63283-63284,63286-63287,63289-63290,63292-63293,63295-63296,63298-63299,63301-63302,63304-63305,63307,63309-63314,63316-63322,63324-63325,63327-63335,63337-63338,63340-63342,63344-63346,63348 via svnmerge from
Alexandre Vassalotti <alexandre@peadrop.com>
parents: 44999
diff changeset
428 {
61466
cab14be0ada1 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 52892
diff changeset
429 PyObject *name = ((PyCodeObject *)gen->gi_code)->co_name;
cab14be0ada1 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 52892
diff changeset
430 Py_INCREF(name);
cab14be0ada1 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 52892
diff changeset
431 return name;
47082
b630729571e6 Merged revisions 63208-63209,63211-63212,63214-63217,63219-63224,63226-63227,63229-63232,63234-63235,63237-63239,63241,63243-63246,63250-63254,63256-63259,63261,63263-63264,63266-63267,63269-63270,63272-63273,63275-63276,63278,63280-63281,63283-63284,63286-63287,63289-63290,63292-63293,63295-63296,63298-63299,63301-63302,63304-63305,63307,63309-63314,63316-63322,63324-63325,63327-63335,63337-63338,63340-63342,63344-63346,63348 via svnmerge from
Alexandre Vassalotti <alexandre@peadrop.com>
parents: 44999
diff changeset
432 }
b630729571e6 Merged revisions 63208-63209,63211-63212,63214-63217,63219-63224,63226-63227,63229-63232,63234-63235,63237-63239,63241,63243-63246,63250-63254,63256-63259,63261,63263-63264,63266-63267,63269-63270,63272-63273,63275-63276,63278,63280-63281,63283-63284,63286-63287,63289-63290,63292-63293,63295-63296,63298-63299,63301-63302,63304-63305,63307,63309-63314,63316-63322,63324-63325,63327-63335,63337-63338,63340-63342,63344-63346,63348 via svnmerge from
Alexandre Vassalotti <alexandre@peadrop.com>
parents: 44999
diff changeset
433
b630729571e6 Merged revisions 63208-63209,63211-63212,63214-63217,63219-63224,63226-63227,63229-63232,63234-63235,63237-63239,63241,63243-63246,63250-63254,63256-63259,63261,63263-63264,63266-63267,63269-63270,63272-63273,63275-63276,63278,63280-63281,63283-63284,63286-63287,63289-63290,63292-63293,63295-63296,63298-63299,63301-63302,63304-63305,63307,63309-63314,63316-63322,63324-63325,63327-63335,63337-63338,63340-63342,63344-63346,63348 via svnmerge from
Alexandre Vassalotti <alexandre@peadrop.com>
parents: 44999
diff changeset
434
b630729571e6 Merged revisions 63208-63209,63211-63212,63214-63217,63219-63224,63226-63227,63229-63232,63234-63235,63237-63239,63241,63243-63246,63250-63254,63256-63259,63261,63263-63264,63266-63267,63269-63270,63272-63273,63275-63276,63278,63280-63281,63283-63284,63286-63287,63289-63290,63292-63293,63295-63296,63298-63299,63301-63302,63304-63305,63307,63309-63314,63316-63322,63324-63325,63327-63335,63337-63338,63340-63342,63344-63346,63348 via svnmerge from
Alexandre Vassalotti <alexandre@peadrop.com>
parents: 44999
diff changeset
435 PyDoc_STRVAR(gen__name__doc__,
b630729571e6 Merged revisions 63208-63209,63211-63212,63214-63217,63219-63224,63226-63227,63229-63232,63234-63235,63237-63239,63241,63243-63246,63250-63254,63256-63259,63261,63263-63264,63266-63267,63269-63270,63272-63273,63275-63276,63278,63280-63281,63283-63284,63286-63287,63289-63290,63292-63293,63295-63296,63298-63299,63301-63302,63304-63305,63307,63309-63314,63316-63322,63324-63325,63327-63335,63337-63338,63340-63342,63344-63346,63348 via svnmerge from
Alexandre Vassalotti <alexandre@peadrop.com>
parents: 44999
diff changeset
436 "Return the name of the generator's associated code object.");
b630729571e6 Merged revisions 63208-63209,63211-63212,63214-63217,63219-63224,63226-63227,63229-63232,63234-63235,63237-63239,63241,63243-63246,63250-63254,63256-63259,63261,63263-63264,63266-63267,63269-63270,63272-63273,63275-63276,63278,63280-63281,63283-63284,63286-63287,63289-63290,63292-63293,63295-63296,63298-63299,63301-63302,63304-63305,63307,63309-63314,63316-63322,63324-63325,63327-63335,63337-63338,63340-63342,63344-63346,63348 via svnmerge from
Alexandre Vassalotti <alexandre@peadrop.com>
parents: 44999
diff changeset
437
b630729571e6 Merged revisions 63208-63209,63211-63212,63214-63217,63219-63224,63226-63227,63229-63232,63234-63235,63237-63239,63241,63243-63246,63250-63254,63256-63259,63261,63263-63264,63266-63267,63269-63270,63272-63273,63275-63276,63278,63280-63281,63283-63284,63286-63287,63289-63290,63292-63293,63295-63296,63298-63299,63301-63302,63304-63305,63307,63309-63314,63316-63322,63324-63325,63327-63335,63337-63338,63340-63342,63344-63346,63348 via svnmerge from
Alexandre Vassalotti <alexandre@peadrop.com>
parents: 44999
diff changeset
438 static PyGetSetDef gen_getsetlist[] = {
61466
cab14be0ada1 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 52892
diff changeset
439 {"__name__", (getter)gen_get_name, NULL, gen__name__doc__},
cab14be0ada1 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 52892
diff changeset
440 {NULL}
47082
b630729571e6 Merged revisions 63208-63209,63211-63212,63214-63217,63219-63224,63226-63227,63229-63232,63234-63235,63237-63239,63241,63243-63246,63250-63254,63256-63259,63261,63263-63264,63266-63267,63269-63270,63272-63273,63275-63276,63278,63280-63281,63283-63284,63286-63287,63289-63290,63292-63293,63295-63296,63298-63299,63301-63302,63304-63305,63307,63309-63314,63316-63322,63324-63325,63327-63335,63337-63338,63340-63342,63344-63346,63348 via svnmerge from
Alexandre Vassalotti <alexandre@peadrop.com>
parents: 44999
diff changeset
441 };
b630729571e6 Merged revisions 63208-63209,63211-63212,63214-63217,63219-63224,63226-63227,63229-63232,63234-63235,63237-63239,63241,63243-63246,63250-63254,63256-63259,63261,63263-63264,63266-63267,63269-63270,63272-63273,63275-63276,63278,63280-63281,63283-63284,63286-63287,63289-63290,63292-63293,63295-63296,63298-63299,63301-63302,63304-63305,63307,63309-63314,63316-63322,63324-63325,63327-63335,63337-63338,63340-63342,63344-63346,63348 via svnmerge from
Alexandre Vassalotti <alexandre@peadrop.com>
parents: 44999
diff changeset
442
b630729571e6 Merged revisions 63208-63209,63211-63212,63214-63217,63219-63224,63226-63227,63229-63232,63234-63235,63237-63239,63241,63243-63246,63250-63254,63256-63259,63261,63263-63264,63266-63267,63269-63270,63272-63273,63275-63276,63278,63280-63281,63283-63284,63286-63287,63289-63290,63292-63293,63295-63296,63298-63299,63301-63302,63304-63305,63307,63309-63314,63316-63322,63324-63325,63327-63335,63337-63338,63340-63342,63344-63346,63348 via svnmerge from
Alexandre Vassalotti <alexandre@peadrop.com>
parents: 44999
diff changeset
443
32175
8ee5a56b8031 Patch #957398: Add public API for Generator Object/Type.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
444 static PyMemberDef gen_memberlist[] = {
61466
cab14be0ada1 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 52892
diff changeset
445 {"gi_frame", T_OBJECT, offsetof(PyGenObject, gi_frame), READONLY},
75481
c8d1df9ac987 make gi_running a boolean
Benjamin Peterson <benjamin@python.org>
parents: 75480
diff changeset
446 {"gi_running", T_BOOL, offsetof(PyGenObject, gi_running), READONLY},
61466
cab14be0ada1 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 52892
diff changeset
447 {"gi_code", T_OBJECT, offsetof(PyGenObject, gi_code), READONLY},
cab14be0ada1 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 52892
diff changeset
448 {NULL} /* Sentinel */
32175
8ee5a56b8031 Patch #957398: Add public API for Generator Object/Type.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
449 };
8ee5a56b8031 Patch #957398: Add public API for Generator Object/Type.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
450
35298
b2fe5f8fcfdd PEP 342 implementation. Per Guido's comments, the generator throw()
Phillip J. Eby <pje@telecommunity.com>
parents: 33386
diff changeset
451 static PyMethodDef gen_methods[] = {
75714
72556ff86828 perform yield from delegation by repeating YIELD_FROM opcode (closes #14230)
Benjamin Peterson <benjamin@python.org>
parents: 75481
diff changeset
452 {"send",(PyCFunction)_PyGen_Send, METH_O, send_doc},
61466
cab14be0ada1 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 52892
diff changeset
453 {"throw",(PyCFunction)gen_throw, METH_VARARGS, throw_doc},
cab14be0ada1 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 52892
diff changeset
454 {"close",(PyCFunction)gen_close, METH_NOARGS, close_doc},
cab14be0ada1 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 52892
diff changeset
455 {NULL, NULL} /* Sentinel */
35298
b2fe5f8fcfdd PEP 342 implementation. Per Guido's comments, the generator throw()
Phillip J. Eby <pje@telecommunity.com>
parents: 33386
diff changeset
456 };
b2fe5f8fcfdd PEP 342 implementation. Per Guido's comments, the generator throw()
Phillip J. Eby <pje@telecommunity.com>
parents: 33386
diff changeset
457
32175
8ee5a56b8031 Patch #957398: Add public API for Generator Object/Type.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
458 PyTypeObject PyGen_Type = {
61466
cab14be0ada1 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 52892
diff changeset
459 PyVarObject_HEAD_INIT(&PyType_Type, 0)
cab14be0ada1 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 52892
diff changeset
460 "generator", /* tp_name */
cab14be0ada1 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 52892
diff changeset
461 sizeof(PyGenObject), /* tp_basicsize */
cab14be0ada1 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 52892
diff changeset
462 0, /* tp_itemsize */
cab14be0ada1 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 52892
diff changeset
463 /* methods */
cab14be0ada1 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 52892
diff changeset
464 (destructor)gen_dealloc, /* tp_dealloc */
cab14be0ada1 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 52892
diff changeset
465 0, /* tp_print */
cab14be0ada1 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 52892
diff changeset
466 0, /* tp_getattr */
cab14be0ada1 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 52892
diff changeset
467 0, /* tp_setattr */
cab14be0ada1 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 52892
diff changeset
468 0, /* tp_reserved */
cab14be0ada1 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 52892
diff changeset
469 (reprfunc)gen_repr, /* tp_repr */
cab14be0ada1 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 52892
diff changeset
470 0, /* tp_as_number */
cab14be0ada1 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 52892
diff changeset
471 0, /* tp_as_sequence */
cab14be0ada1 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 52892
diff changeset
472 0, /* tp_as_mapping */
cab14be0ada1 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 52892
diff changeset
473 0, /* tp_hash */
cab14be0ada1 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 52892
diff changeset
474 0, /* tp_call */
cab14be0ada1 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 52892
diff changeset
475 0, /* tp_str */
cab14be0ada1 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 52892
diff changeset
476 PyObject_GenericGetAttr, /* tp_getattro */
cab14be0ada1 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 52892
diff changeset
477 0, /* tp_setattro */
cab14be0ada1 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 52892
diff changeset
478 0, /* tp_as_buffer */
84911
3f994367a979 Issue #18112: PEP 442 implementation (safe object finalization).
Antoine Pitrou <solipsis@pitrou.net>
parents: 83771
diff changeset
479 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC |
3f994367a979 Issue #18112: PEP 442 implementation (safe object finalization).
Antoine Pitrou <solipsis@pitrou.net>
parents: 83771
diff changeset
480 Py_TPFLAGS_HAVE_FINALIZE, /* tp_flags */
61466
cab14be0ada1 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 52892
diff changeset
481 0, /* tp_doc */
cab14be0ada1 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 52892
diff changeset
482 (traverseproc)gen_traverse, /* tp_traverse */
cab14be0ada1 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 52892
diff changeset
483 0, /* tp_clear */
cab14be0ada1 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 52892
diff changeset
484 0, /* tp_richcompare */
cab14be0ada1 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 52892
diff changeset
485 offsetof(PyGenObject, gi_weakreflist), /* tp_weaklistoffset */
cab14be0ada1 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 52892
diff changeset
486 PyObject_SelfIter, /* tp_iter */
cab14be0ada1 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 52892
diff changeset
487 (iternextfunc)gen_iternext, /* tp_iternext */
cab14be0ada1 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 52892
diff changeset
488 gen_methods, /* tp_methods */
cab14be0ada1 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 52892
diff changeset
489 gen_memberlist, /* tp_members */
cab14be0ada1 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 52892
diff changeset
490 gen_getsetlist, /* tp_getset */
cab14be0ada1 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 52892
diff changeset
491 0, /* tp_base */
cab14be0ada1 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 52892
diff changeset
492 0, /* tp_dict */
37879
f731859e9b3b Merge p3yk branch with the trunk up to revision 45595. This breaks a fair
Thomas Wouters <thomas@python.org>
parents: 36866
diff changeset
493
61466
cab14be0ada1 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 52892
diff changeset
494 0, /* tp_descr_get */
cab14be0ada1 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 52892
diff changeset
495 0, /* tp_descr_set */
cab14be0ada1 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 52892
diff changeset
496 0, /* tp_dictoffset */
cab14be0ada1 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 52892
diff changeset
497 0, /* tp_init */
cab14be0ada1 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 52892
diff changeset
498 0, /* tp_alloc */
cab14be0ada1 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 52892
diff changeset
499 0, /* tp_new */
cab14be0ada1 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 52892
diff changeset
500 0, /* tp_free */
cab14be0ada1 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 52892
diff changeset
501 0, /* tp_is_gc */
cab14be0ada1 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 52892
diff changeset
502 0, /* tp_bases */
cab14be0ada1 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 52892
diff changeset
503 0, /* tp_mro */
cab14be0ada1 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 52892
diff changeset
504 0, /* tp_cache */
cab14be0ada1 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 52892
diff changeset
505 0, /* tp_subclasses */
cab14be0ada1 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 52892
diff changeset
506 0, /* tp_weaklist */
84911
3f994367a979 Issue #18112: PEP 442 implementation (safe object finalization).
Antoine Pitrou <solipsis@pitrou.net>
parents: 83771
diff changeset
507 0, /* tp_del */
3f994367a979 Issue #18112: PEP 442 implementation (safe object finalization).
Antoine Pitrou <solipsis@pitrou.net>
parents: 83771
diff changeset
508 0, /* tp_version_tag */
85046
862ab99ab570 Issue #17934: Add a clear() method to frame objects, to help clean up expensive details (local variables) and break reference cycles.
Antoine Pitrou <solipsis@pitrou.net>
parents: 84911
diff changeset
509 _PyGen_Finalize, /* tp_finalize */
32175
8ee5a56b8031 Patch #957398: Add public API for Generator Object/Type.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
510 };
8ee5a56b8031 Patch #957398: Add public API for Generator Object/Type.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
511
8ee5a56b8031 Patch #957398: Add public API for Generator Object/Type.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
512 PyObject *
8ee5a56b8031 Patch #957398: Add public API for Generator Object/Type.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
513 PyGen_New(PyFrameObject *f)
8ee5a56b8031 Patch #957398: Add public API for Generator Object/Type.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
514 {
61466
cab14be0ada1 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 52892
diff changeset
515 PyGenObject *gen = PyObject_GC_New(PyGenObject, &PyGen_Type);
cab14be0ada1 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 52892
diff changeset
516 if (gen == NULL) {
cab14be0ada1 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 52892
diff changeset
517 Py_DECREF(f);
cab14be0ada1 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 52892
diff changeset
518 return NULL;
cab14be0ada1 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 52892
diff changeset
519 }
cab14be0ada1 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 52892
diff changeset
520 gen->gi_frame = f;
85046
862ab99ab570 Issue #17934: Add a clear() method to frame objects, to help clean up expensive details (local variables) and break reference cycles.
Antoine Pitrou <solipsis@pitrou.net>
parents: 84911
diff changeset
521 f->f_gen = (PyObject *) gen;
61466
cab14be0ada1 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 52892
diff changeset
522 Py_INCREF(f->f_code);
cab14be0ada1 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 52892
diff changeset
523 gen->gi_code = (PyObject *)(f->f_code);
cab14be0ada1 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 52892
diff changeset
524 gen->gi_running = 0;
cab14be0ada1 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 52892
diff changeset
525 gen->gi_weakreflist = NULL;
cab14be0ada1 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 52892
diff changeset
526 _PyObject_GC_TRACK(gen);
cab14be0ada1 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 52892
diff changeset
527 return (PyObject *)gen;
32175
8ee5a56b8031 Patch #957398: Add public API for Generator Object/Type.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
528 }
37879
f731859e9b3b Merge p3yk branch with the trunk up to revision 45595. This breaks a fair
Thomas Wouters <thomas@python.org>
parents: 36866
diff changeset
529
f731859e9b3b Merge p3yk branch with the trunk up to revision 45595. This breaks a fair
Thomas Wouters <thomas@python.org>
parents: 36866
diff changeset
530 int
f731859e9b3b Merge p3yk branch with the trunk up to revision 45595. This breaks a fair
Thomas Wouters <thomas@python.org>
parents: 36866
diff changeset
531 PyGen_NeedsFinalizing(PyGenObject *gen)
f731859e9b3b Merge p3yk branch with the trunk up to revision 45595. This breaks a fair
Thomas Wouters <thomas@python.org>
parents: 36866
diff changeset
532 {
83771
edefd3450834 Backout c89febab4648 following private feedback by Guido.
Antoine Pitrou <solipsis@pitrou.net>
parents: 83688
diff changeset
533 int i;
edefd3450834 Backout c89febab4648 following private feedback by Guido.
Antoine Pitrou <solipsis@pitrou.net>
parents: 83688
diff changeset
534 PyFrameObject *f = gen->gi_frame;
edefd3450834 Backout c89febab4648 following private feedback by Guido.
Antoine Pitrou <solipsis@pitrou.net>
parents: 83688
diff changeset
535
edefd3450834 Backout c89febab4648 following private feedback by Guido.
Antoine Pitrou <solipsis@pitrou.net>
parents: 83688
diff changeset
536 if (f == NULL || f->f_stacktop == NULL)
edefd3450834 Backout c89febab4648 following private feedback by Guido.
Antoine Pitrou <solipsis@pitrou.net>
parents: 83688
diff changeset
537 return 0; /* no frame or empty blockstack == no finalization */
edefd3450834 Backout c89febab4648 following private feedback by Guido.
Antoine Pitrou <solipsis@pitrou.net>
parents: 83688
diff changeset
538
edefd3450834 Backout c89febab4648 following private feedback by Guido.
Antoine Pitrou <solipsis@pitrou.net>
parents: 83688
diff changeset
539 /* Any block type besides a loop requires cleanup. */
edefd3450834 Backout c89febab4648 following private feedback by Guido.
Antoine Pitrou <solipsis@pitrou.net>
parents: 83688
diff changeset
540 for (i = 0; i < f->f_iblock; i++)
edefd3450834 Backout c89febab4648 following private feedback by Guido.
Antoine Pitrou <solipsis@pitrou.net>
parents: 83688
diff changeset
541 if (f->f_blockstack[i].b_type != SETUP_LOOP)
edefd3450834 Backout c89febab4648 following private feedback by Guido.
Antoine Pitrou <solipsis@pitrou.net>
parents: 83688
diff changeset
542 return 1;
edefd3450834 Backout c89febab4648 following private feedback by Guido.
Antoine Pitrou <solipsis@pitrou.net>
parents: 83688
diff changeset
543
edefd3450834 Backout c89febab4648 following private feedback by Guido.
Antoine Pitrou <solipsis@pitrou.net>
parents: 83688
diff changeset
544 /* No blocks except loops, it's safe to skip finalization. */
61466
cab14be0ada1 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 52892
diff changeset
545 return 0;
37879
f731859e9b3b Merge p3yk branch with the trunk up to revision 45595. This breaks a fair
Thomas Wouters <thomas@python.org>
parents: 36866
diff changeset
546 }