mirror of
				https://github.com/python/cpython.git
				synced 2025-11-03 19:34:08 +00:00 
			
		
		
		
	bpo-45292: [PEP-654] add except* (GH-29581)
This commit is contained in:
		
							parent
							
								
									850aefc2c6
								
							
						
					
					
						commit
						d60457a667
					
				
					 34 changed files with 7070 additions and 3332 deletions
				
			
		
							
								
								
									
										229
									
								
								Python/Python-ast.c
									
										
									
										generated
									
									
									
								
							
							
						
						
									
										229
									
								
								Python/Python-ast.c
									
										
									
										generated
									
									
									
								
							| 
						 | 
				
			
			@ -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)");
 | 
			
		||||
| 
						 | 
				
			
			@ -2379,6 +2391,28 @@ _PyAST_Try(asdl_stmt_seq * body, asdl_excepthandler_seq * handlers,
 | 
			
		|||
    return p;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
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;
 | 
			
		||||
    }
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue