Skip to content

Commit 3a9df11

Browse files
committed
Add API function to access code object of generator.
1 parent d68ce2c commit 3a9df11

4 files changed

Lines changed: 25 additions & 0 deletions

File tree

Include/cpython/genobject.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,7 @@ PyAPI_FUNC(PyObject *) PyGen_NewWithQualName(PyFrameObject *,
4444
PyAPI_FUNC(int) _PyGen_SetStopIterationValue(PyObject *);
4545
PyAPI_FUNC(int) _PyGen_FetchStopIterationValue(PyObject **);
4646
PyAPI_FUNC(void) _PyGen_Finalize(PyObject *self);
47+
PyAPI_FUNC(PyCodeObject *) PyGen_GetCode(PyGenObject *gen);
4748

4849

4950
/* --- PyCoroObject ------------------------------------------------------- */

Lib/test/test_capi/test_misc.py

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1214,6 +1214,11 @@ def test_pendingcalls_non_threaded(self):
12141214
self.pendingcalls_submit(l, n)
12151215
self.pendingcalls_wait(l, n)
12161216

1217+
def test_gen_get_code(self):
1218+
def genf(): yield
1219+
gen = genf()
1220+
self.assertEqual(_testcapi.gen_get_code(gen), gen.gi_code)
1221+
12171222

12181223
class SubinterpreterTest(unittest.TestCase):
12191224

Modules/_testcapimodule.c

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2943,6 +2943,16 @@ eval_get_func_desc(PyObject *self, PyObject *func)
29432943
return PyUnicode_FromString(PyEval_GetFuncDesc(func));
29442944
}
29452945

2946+
static PyObject *
2947+
gen_get_code(PyObject *self, PyObject *gen)
2948+
{
2949+
if (!PyGen_Check(gen)) {
2950+
PyErr_SetString(PyExc_TypeError, "argument must be a generator object");
2951+
return NULL;
2952+
}
2953+
return (PyObject *)PyGen_GetCode((PyGenObject *)gen);
2954+
}
2955+
29462956
static PyObject *
29472957
get_feature_macros(PyObject *self, PyObject *Py_UNUSED(args))
29482958
{
@@ -3346,6 +3356,7 @@ static PyMethodDef TestMethods[] = {
33463356
{"frame_getvarstring", test_frame_getvarstring, METH_VARARGS, NULL},
33473357
{"eval_get_func_name", eval_get_func_name, METH_O, NULL},
33483358
{"eval_get_func_desc", eval_get_func_desc, METH_O, NULL},
3359+
{"gen_get_code", gen_get_code, METH_O, NULL},
33493360
{"get_feature_macros", get_feature_macros, METH_NOARGS, NULL},
33503361
{"test_code_api", test_code_api, METH_NOARGS, NULL},
33513362
{"settrace_to_record", settrace_to_record, METH_O, NULL},

Objects/genobject.c

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,14 @@ _PyGen_GetCode(PyGenObject *gen) {
3131
return frame->f_code;
3232
}
3333

34+
PyCodeObject *
35+
PyGen_GetCode(PyGenObject *gen) {
36+
assert(PyGen_Check(gen));
37+
PyCodeObject *res = _PyGen_GetCode(gen);
38+
Py_INCREF(res);
39+
return res;
40+
}
41+
3442
static inline int
3543
exc_state_traverse(_PyErr_StackItem *exc_state, visitproc visit, void *arg)
3644
{

0 commit comments

Comments
 (0)