diff options
author | Irit Katriel <1055913+iritkatriel@users.noreply.github.com> | 2021-12-14 16:48:15 +0000 |
---|---|---|
committer | GitHub <noreply@github.com> | 2021-12-14 16:48:15 +0000 |
commit | d60457a6673cf0263213c2f2be02c633ec2e2038 (patch) | |
tree | 04461db9079cf30a98c5a4070098f795275aa910 /Python/Python-ast.c | |
parent | 850aefc2c651110a784cd5478af9774b1f6287a3 (diff) | |
download | cpython-git-d60457a6673cf0263213c2f2be02c633ec2e2038.tar.gz |
bpo-45292: [PEP-654] add except* (GH-29581)
Diffstat (limited to 'Python/Python-ast.c')
-rw-r--r-- | Python/Python-ast.c | 229 |
1 files changed, 229 insertions, 0 deletions
diff --git a/Python/Python-ast.c b/Python/Python-ast.c index ce6e6a93ea..1670184820 100644 --- a/Python/Python-ast.c +++ b/Python/Python-ast.c @@ -146,6 +146,7 @@ void _PyAST_Fini(PyInterpreterState *interp) Py_CLEAR(state->Sub_singleton); Py_CLEAR(state->Sub_type); Py_CLEAR(state->Subscript_type); + Py_CLEAR(state->TryStar_type); Py_CLEAR(state->Try_type); Py_CLEAR(state->Tuple_type); Py_CLEAR(state->TypeIgnore_type); @@ -486,6 +487,12 @@ static const char * const Try_fields[]={ "orelse", "finalbody", }; +static const char * const TryStar_fields[]={ + "body", + "handlers", + "orelse", + "finalbody", +}; static const char * const Assert_fields[]={ "test", "msg", @@ -1139,6 +1146,7 @@ init_types(struct ast_state *state) " | Match(expr subject, match_case* cases)\n" " | Raise(expr? exc, expr? cause)\n" " | Try(stmt* body, excepthandler* handlers, stmt* orelse, stmt* finalbody)\n" + " | TryStar(stmt* body, excepthandler* handlers, stmt* orelse, stmt* finalbody)\n" " | Assert(expr test, expr? msg)\n" " | Import(alias* names)\n" " | ImportFrom(identifier? module, alias* names, int? level)\n" @@ -1254,6 +1262,10 @@ init_types(struct ast_state *state) state->Try_type = make_type(state, "Try", state->stmt_type, Try_fields, 4, "Try(stmt* body, excepthandler* handlers, stmt* orelse, stmt* finalbody)"); if (!state->Try_type) return 0; + state->TryStar_type = make_type(state, "TryStar", state->stmt_type, + TryStar_fields, 4, + "TryStar(stmt* body, excepthandler* handlers, stmt* orelse, stmt* finalbody)"); + if (!state->TryStar_type) return 0; state->Assert_type = make_type(state, "Assert", state->stmt_type, Assert_fields, 2, "Assert(expr test, expr? msg)"); @@ -2380,6 +2392,28 @@ _PyAST_Try(asdl_stmt_seq * body, asdl_excepthandler_seq * handlers, } stmt_ty +_PyAST_TryStar(asdl_stmt_seq * body, asdl_excepthandler_seq * handlers, + asdl_stmt_seq * orelse, asdl_stmt_seq * finalbody, int lineno, + int col_offset, int end_lineno, int end_col_offset, PyArena + *arena) +{ + stmt_ty p; + p = (stmt_ty)_PyArena_Malloc(arena, sizeof(*p)); + if (!p) + return NULL; + p->kind = TryStar_kind; + p->v.TryStar.body = body; + p->v.TryStar.handlers = handlers; + p->v.TryStar.orelse = orelse; + p->v.TryStar.finalbody = finalbody; + p->lineno = lineno; + p->col_offset = col_offset; + p->end_lineno = end_lineno; + p->end_col_offset = end_col_offset; + return p; +} + +stmt_ty _PyAST_Assert(expr_ty test, expr_ty msg, int lineno, int col_offset, int end_lineno, int end_col_offset, PyArena *arena) { @@ -4049,6 +4083,34 @@ ast2obj_stmt(struct ast_state *state, void* _o) goto failed; Py_DECREF(value); break; + case TryStar_kind: + tp = (PyTypeObject *)state->TryStar_type; + result = PyType_GenericNew(tp, NULL, NULL); + if (!result) goto failed; + value = ast2obj_list(state, (asdl_seq*)o->v.TryStar.body, ast2obj_stmt); + if (!value) goto failed; + if (PyObject_SetAttr(result, state->body, value) == -1) + goto failed; + Py_DECREF(value); + value = ast2obj_list(state, (asdl_seq*)o->v.TryStar.handlers, + ast2obj_excepthandler); + if (!value) goto failed; + if (PyObject_SetAttr(result, state->handlers, value) == -1) + goto failed; + Py_DECREF(value); + value = ast2obj_list(state, (asdl_seq*)o->v.TryStar.orelse, + ast2obj_stmt); + if (!value) goto failed; + if (PyObject_SetAttr(result, state->orelse, value) == -1) + goto failed; + Py_DECREF(value); + value = ast2obj_list(state, (asdl_seq*)o->v.TryStar.finalbody, + ast2obj_stmt); + if (!value) goto failed; + if (PyObject_SetAttr(result, state->finalbody, value) == -1) + goto failed; + Py_DECREF(value); + break; case Assert_kind: tp = (PyTypeObject *)state->Assert_type; result = PyType_GenericNew(tp, NULL, NULL); @@ -7477,6 +7539,170 @@ obj2ast_stmt(struct ast_state *state, PyObject* obj, stmt_ty* out, PyArena* if (*out == NULL) goto failed; return 0; } + tp = state->TryStar_type; + isinstance = PyObject_IsInstance(obj, tp); + if (isinstance == -1) { + return 1; + } + if (isinstance) { + asdl_stmt_seq* body; + asdl_excepthandler_seq* handlers; + asdl_stmt_seq* orelse; + asdl_stmt_seq* finalbody; + + if (_PyObject_LookupAttr(obj, state->body, &tmp) < 0) { + return 1; + } + if (tmp == NULL) { + PyErr_SetString(PyExc_TypeError, "required field \"body\" missing from TryStar"); + return 1; + } + else { + int res; + Py_ssize_t len; + Py_ssize_t i; + if (!PyList_Check(tmp)) { + PyErr_Format(PyExc_TypeError, "TryStar field \"body\" must be a list, not a %.200s", _PyType_Name(Py_TYPE(tmp))); + goto failed; + } + len = PyList_GET_SIZE(tmp); + body = _Py_asdl_stmt_seq_new(len, arena); + if (body == NULL) goto failed; + for (i = 0; i < len; i++) { + stmt_ty val; + PyObject *tmp2 = PyList_GET_ITEM(tmp, i); + Py_INCREF(tmp2); + if (Py_EnterRecursiveCall(" while traversing 'TryStar' node")) { + goto failed; + } + res = obj2ast_stmt(state, tmp2, &val, arena); + Py_LeaveRecursiveCall(); + Py_DECREF(tmp2); + if (res != 0) goto failed; + if (len != PyList_GET_SIZE(tmp)) { + PyErr_SetString(PyExc_RuntimeError, "TryStar field \"body\" changed size during iteration"); + goto failed; + } + asdl_seq_SET(body, i, val); + } + Py_CLEAR(tmp); + } + if (_PyObject_LookupAttr(obj, state->handlers, &tmp) < 0) { + return 1; + } + if (tmp == NULL) { + PyErr_SetString(PyExc_TypeError, "required field \"handlers\" missing from TryStar"); + return 1; + } + else { + int res; + Py_ssize_t len; + Py_ssize_t i; + if (!PyList_Check(tmp)) { + PyErr_Format(PyExc_TypeError, "TryStar field \"handlers\" must be a list, not a %.200s", _PyType_Name(Py_TYPE(tmp))); + goto failed; + } + len = PyList_GET_SIZE(tmp); + handlers = _Py_asdl_excepthandler_seq_new(len, arena); + if (handlers == NULL) goto failed; + for (i = 0; i < len; i++) { + excepthandler_ty val; + PyObject *tmp2 = PyList_GET_ITEM(tmp, i); + Py_INCREF(tmp2); + if (Py_EnterRecursiveCall(" while traversing 'TryStar' node")) { + goto failed; + } + res = obj2ast_excepthandler(state, tmp2, &val, arena); + Py_LeaveRecursiveCall(); + Py_DECREF(tmp2); + if (res != 0) goto failed; + if (len != PyList_GET_SIZE(tmp)) { + PyErr_SetString(PyExc_RuntimeError, "TryStar field \"handlers\" changed size during iteration"); + goto failed; + } + asdl_seq_SET(handlers, i, val); + } + Py_CLEAR(tmp); + } + if (_PyObject_LookupAttr(obj, state->orelse, &tmp) < 0) { + return 1; + } + if (tmp == NULL) { + PyErr_SetString(PyExc_TypeError, "required field \"orelse\" missing from TryStar"); + return 1; + } + else { + int res; + Py_ssize_t len; + Py_ssize_t i; + if (!PyList_Check(tmp)) { + PyErr_Format(PyExc_TypeError, "TryStar field \"orelse\" must be a list, not a %.200s", _PyType_Name(Py_TYPE(tmp))); + goto failed; + } + len = PyList_GET_SIZE(tmp); + orelse = _Py_asdl_stmt_seq_new(len, arena); + if (orelse == NULL) goto failed; + for (i = 0; i < len; i++) { + stmt_ty val; + PyObject *tmp2 = PyList_GET_ITEM(tmp, i); + Py_INCREF(tmp2); + if (Py_EnterRecursiveCall(" while traversing 'TryStar' node")) { + goto failed; + } + res = obj2ast_stmt(state, tmp2, &val, arena); + Py_LeaveRecursiveCall(); + Py_DECREF(tmp2); + if (res != 0) goto failed; + if (len != PyList_GET_SIZE(tmp)) { + PyErr_SetString(PyExc_RuntimeError, "TryStar field \"orelse\" changed size during iteration"); + goto failed; + } + asdl_seq_SET(orelse, i, val); + } + Py_CLEAR(tmp); + } + if (_PyObject_LookupAttr(obj, state->finalbody, &tmp) < 0) { + return 1; + } + if (tmp == NULL) { + PyErr_SetString(PyExc_TypeError, "required field \"finalbody\" missing from TryStar"); + return 1; + } + else { + int res; + Py_ssize_t len; + Py_ssize_t i; + if (!PyList_Check(tmp)) { + PyErr_Format(PyExc_TypeError, "TryStar field \"finalbody\" must be a list, not a %.200s", _PyType_Name(Py_TYPE(tmp))); + goto failed; + } + len = PyList_GET_SIZE(tmp); + finalbody = _Py_asdl_stmt_seq_new(len, arena); + if (finalbody == NULL) goto failed; + for (i = 0; i < len; i++) { + stmt_ty val; + PyObject *tmp2 = PyList_GET_ITEM(tmp, i); + Py_INCREF(tmp2); + if (Py_EnterRecursiveCall(" while traversing 'TryStar' node")) { + goto failed; + } + res = obj2ast_stmt(state, tmp2, &val, arena); + Py_LeaveRecursiveCall(); + Py_DECREF(tmp2); + if (res != 0) goto failed; + if (len != PyList_GET_SIZE(tmp)) { + PyErr_SetString(PyExc_RuntimeError, "TryStar field \"finalbody\" changed size during iteration"); + goto failed; + } + asdl_seq_SET(finalbody, i, val); + } + Py_CLEAR(tmp); + } + *out = _PyAST_TryStar(body, handlers, orelse, finalbody, lineno, + col_offset, end_lineno, end_col_offset, arena); + if (*out == NULL) goto failed; + return 0; + } tp = state->Assert_type; isinstance = PyObject_IsInstance(obj, tp); if (isinstance == -1) { @@ -11687,6 +11913,9 @@ astmodule_exec(PyObject *m) if (PyModule_AddObjectRef(m, "Try", state->Try_type) < 0) { return -1; } + if (PyModule_AddObjectRef(m, "TryStar", state->TryStar_type) < 0) { + return -1; + } if (PyModule_AddObjectRef(m, "Assert", state->Assert_type) < 0) { return -1; } |