diff options
Diffstat (limited to 'Modules')
-rw-r--r-- | Modules/_testcapimodule.c | 97 | ||||
-rw-r--r-- | Modules/parsermodule.c | 115 |
2 files changed, 200 insertions, 12 deletions
diff --git a/Modules/_testcapimodule.c b/Modules/_testcapimodule.c index d77d1db..77167b2 100644 --- a/Modules/_testcapimodule.c +++ b/Modules/_testcapimodule.c @@ -3944,6 +3944,98 @@ static PyTypeObject matmulType = { }; +typedef struct { + PyObject_HEAD + PyObject *ao_iterator; +} awaitObject; + + +static PyObject * +awaitObject_new(PyTypeObject *type, PyObject *args, PyObject *kwds) +{ + PyObject *v; + awaitObject *ao; + + if (!PyArg_UnpackTuple(args, "awaitObject", 1, 1, &v)) + return NULL; + + ao = (awaitObject *)type->tp_alloc(type, 0); + if (ao == NULL) { + return NULL; + } + + Py_INCREF(v); + ao->ao_iterator = v; + + return (PyObject *)ao; +} + + +static void +awaitObject_dealloc(awaitObject *ao) +{ + Py_CLEAR(ao->ao_iterator); + Py_TYPE(ao)->tp_free(ao); +} + + +static PyObject * +awaitObject_await(awaitObject *ao) +{ + Py_INCREF(ao->ao_iterator); + return ao->ao_iterator; +} + +static PyAsyncMethods awaitType_as_async = { + (getawaitablefunc)awaitObject_await, /* am_await */ + 0, /* am_aiter */ + 0 /* am_anext */ +}; + + +static PyTypeObject awaitType = { + PyVarObject_HEAD_INIT(NULL, 0) + "awaitType", + sizeof(awaitObject), /* tp_basicsize */ + 0, /* tp_itemsize */ + (destructor)awaitObject_dealloc, /* destructor tp_dealloc */ + 0, /* tp_print */ + 0, /* tp_getattr */ + 0, /* tp_setattr */ + &awaitType_as_async, /* tp_as_async */ + 0, /* tp_repr */ + 0, /* tp_as_number */ + 0, /* tp_as_sequence */ + 0, /* tp_as_mapping */ + 0, /* tp_hash */ + 0, /* tp_call */ + 0, /* tp_str */ + PyObject_GenericGetAttr, /* tp_getattro */ + PyObject_GenericSetAttr, /* tp_setattro */ + 0, /* tp_as_buffer */ + 0, /* tp_flags */ + "C level type with tp_as_async", + 0, /* traverseproc tp_traverse */ + 0, /* tp_clear */ + 0, /* tp_richcompare */ + 0, /* tp_weaklistoffset */ + 0, /* tp_iter */ + 0, /* tp_iternext */ + 0, /* tp_methods */ + 0, /* tp_members */ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + awaitObject_new, /* tp_new */ + PyObject_Del, /* tp_free */ +}; + + static struct PyModuleDef _testcapimodule = { PyModuleDef_HEAD_INIT, "_testcapi", @@ -3977,6 +4069,11 @@ PyInit__testcapi(void) Py_INCREF(&matmulType); PyModule_AddObject(m, "matmulType", (PyObject *)&matmulType); + if (PyType_Ready(&awaitType) < 0) + return NULL; + Py_INCREF(&awaitType); + PyModule_AddObject(m, "awaitType", (PyObject *)&awaitType); + PyModule_AddObject(m, "CHAR_MAX", PyLong_FromLong(CHAR_MAX)); PyModule_AddObject(m, "CHAR_MIN", PyLong_FromLong(CHAR_MIN)); PyModule_AddObject(m, "UCHAR_MAX", PyLong_FromLong(UCHAR_MAX)); diff --git a/Modules/parsermodule.c b/Modules/parsermodule.c index 828f46b..876e57d 100644 --- a/Modules/parsermodule.c +++ b/Modules/parsermodule.c @@ -1041,6 +1041,8 @@ VALIDATER(testlist_comp); VALIDATER(yield_expr); VALIDATER(or_test); VALIDATER(test_nocond); VALIDATER(lambdef_nocond); VALIDATER(yield_arg); +VALIDATER(async_funcdef); VALIDATER(async_stmt); +VALIDATER(atom_expr); #undef VALIDATER @@ -1608,6 +1610,7 @@ validate_compound_stmt(node *tree) || (ntype == try_stmt) || (ntype == with_stmt) || (ntype == funcdef) + || (ntype == async_stmt) || (ntype == classdef) || (ntype == decorated)) res = validate_node(tree); @@ -2440,27 +2443,60 @@ validate_factor(node *tree) /* power: * - * power: atom trailer* ('**' factor)* + * power: atom_expr trailer* ['**' factor] */ static int validate_power(node *tree) { - int pos = 1; int nch = NCH(tree); int res = (validate_ntype(tree, power) && (nch >= 1) - && validate_atom(CHILD(tree, 0))); + && validate_atom_expr(CHILD(tree, 0))); - while (res && (pos < nch) && (TYPE(CHILD(tree, pos)) == trailer)) - res = validate_trailer(CHILD(tree, pos++)); - if (res && (pos < nch)) { - if (!is_even(nch - pos)) { + if (nch > 1) { + if (nch != 3) { err_string("illegal number of nodes for 'power'"); return (0); } - for ( ; res && (pos < (nch - 1)); pos += 2) - res = (validate_doublestar(CHILD(tree, pos)) - && validate_factor(CHILD(tree, pos + 1))); + res = (validate_doublestar(CHILD(tree, 1)) + && validate_factor(CHILD(tree, 2))); } + + return (res); +} + + +/* atom_expr: + * + * atom_expr: [AWAIT] atom trailer* + */ +static int +validate_atom_expr(node *tree) +{ + int start = 0; + int nch = NCH(tree); + int res; + int pos; + + res = validate_ntype(tree, atom_expr) && (nch >= 1); + if (!res) { + return (res); + } + + if (TYPE(CHILD(tree, 0)) == AWAIT) { + start = 1; + if (nch < 2) { + err_string("illegal number of nodes for 'atom_expr'"); + return (0); + } + } + + res = validate_atom(CHILD(tree, start)); + if (res) { + pos = start + 1; + while (res && (pos < nch) && (TYPE(CHILD(tree, pos)) == trailer)) + res = validate_trailer(CHILD(tree, pos++)); + } + return (res); } @@ -2482,9 +2518,9 @@ validate_atom(node *tree) if (res && (nch == 3)) { if (TYPE(CHILD(tree, 1))==yield_expr) - res = validate_yield_expr(CHILD(tree, 1)); + res = validate_yield_expr(CHILD(tree, 1)); else - res = validate_testlist_comp(CHILD(tree, 1)); + res = validate_testlist_comp(CHILD(tree, 1)); } break; case LSQB: @@ -2658,6 +2694,55 @@ validate_funcdef(node *tree) return res; } +/* async_funcdef: ASYNC funcdef */ + +static int +validate_async_funcdef(node *tree) +{ + int nch = NCH(tree); + int res = validate_ntype(tree, async_funcdef); + if (res) { + if (nch == 2) { + res = (validate_ntype(CHILD(tree, 0), ASYNC) + && validate_funcdef(CHILD(tree, 1))); + } + else { + res = 0; + err_string("illegal number of children for async_funcdef"); + } + } + return res; +} + + +/* async_stmt: ASYNC (funcdef | with_stmt | for_stmt) */ + +static int +validate_async_stmt(node *tree) +{ + int nch = NCH(tree); + int res = (validate_ntype(tree, async_stmt) + && validate_ntype(CHILD(tree, 0), ASYNC)); + + if (nch != 2) { + res = 0; + err_string("illegal number of children for async_stmt"); + } else { + if (TYPE(CHILD(tree, 1)) == funcdef) { + res = validate_funcdef(CHILD(tree, 1)); + } + else if (TYPE(CHILD(tree, 1)) == with_stmt) { + res = validate_with_stmt(CHILD(tree, 1)); + } + else if (TYPE(CHILD(tree, 1)) == for_stmt) { + res = validate_for(CHILD(tree, 1)); + } + } + + return res; +} + + /* decorated * decorators (classdef | funcdef) @@ -3085,6 +3170,12 @@ validate_node(node *tree) /* * Definition nodes. */ + case async_funcdef: + res = validate_async_funcdef(tree); + break; + case async_stmt: + res = validate_async_stmt(tree); + break; case funcdef: res = validate_funcdef(tree); break; |