unify TryExcept and TryFinally (closes #12199)
This commit is contained in:
parent
f7d08e8522
commit
43af12b0b4
|
@ -66,10 +66,9 @@ struct _mod {
|
||||||
enum _stmt_kind {FunctionDef_kind=1, ClassDef_kind=2, Return_kind=3,
|
enum _stmt_kind {FunctionDef_kind=1, ClassDef_kind=2, Return_kind=3,
|
||||||
Delete_kind=4, Assign_kind=5, AugAssign_kind=6, For_kind=7,
|
Delete_kind=4, Assign_kind=5, AugAssign_kind=6, For_kind=7,
|
||||||
While_kind=8, If_kind=9, With_kind=10, Raise_kind=11,
|
While_kind=8, If_kind=9, With_kind=10, Raise_kind=11,
|
||||||
TryExcept_kind=12, TryFinally_kind=13, Assert_kind=14,
|
Try_kind=12, Assert_kind=13, Import_kind=14,
|
||||||
Import_kind=15, ImportFrom_kind=16, Global_kind=17,
|
ImportFrom_kind=15, Global_kind=16, Nonlocal_kind=17,
|
||||||
Nonlocal_kind=18, Expr_kind=19, Pass_kind=20, Break_kind=21,
|
Expr_kind=18, Pass_kind=19, Break_kind=20, Continue_kind=21};
|
||||||
Continue_kind=22};
|
|
||||||
struct _stmt {
|
struct _stmt {
|
||||||
enum _stmt_kind kind;
|
enum _stmt_kind kind;
|
||||||
union {
|
union {
|
||||||
|
@ -143,12 +142,8 @@ struct _stmt {
|
||||||
asdl_seq *body;
|
asdl_seq *body;
|
||||||
asdl_seq *handlers;
|
asdl_seq *handlers;
|
||||||
asdl_seq *orelse;
|
asdl_seq *orelse;
|
||||||
} TryExcept;
|
|
||||||
|
|
||||||
struct {
|
|
||||||
asdl_seq *body;
|
|
||||||
asdl_seq *finalbody;
|
asdl_seq *finalbody;
|
||||||
} TryFinally;
|
} Try;
|
||||||
|
|
||||||
struct {
|
struct {
|
||||||
expr_ty test;
|
expr_ty test;
|
||||||
|
@ -433,12 +428,10 @@ stmt_ty _Py_With(asdl_seq * items, asdl_seq * body, int lineno, int col_offset,
|
||||||
#define Raise(a0, a1, a2, a3, a4) _Py_Raise(a0, a1, a2, a3, a4)
|
#define Raise(a0, a1, a2, a3, a4) _Py_Raise(a0, a1, a2, a3, a4)
|
||||||
stmt_ty _Py_Raise(expr_ty exc, expr_ty cause, int lineno, int col_offset,
|
stmt_ty _Py_Raise(expr_ty exc, expr_ty cause, int lineno, int col_offset,
|
||||||
PyArena *arena);
|
PyArena *arena);
|
||||||
#define TryExcept(a0, a1, a2, a3, a4, a5) _Py_TryExcept(a0, a1, a2, a3, a4, a5)
|
#define Try(a0, a1, a2, a3, a4, a5, a6) _Py_Try(a0, a1, a2, a3, a4, a5, a6)
|
||||||
stmt_ty _Py_TryExcept(asdl_seq * body, asdl_seq * handlers, asdl_seq * orelse,
|
stmt_ty _Py_Try(asdl_seq * body, asdl_seq * handlers, asdl_seq * orelse,
|
||||||
int lineno, int col_offset, PyArena *arena);
|
asdl_seq * finalbody, int lineno, int col_offset, PyArena
|
||||||
#define TryFinally(a0, a1, a2, a3, a4) _Py_TryFinally(a0, a1, a2, a3, a4)
|
*arena);
|
||||||
stmt_ty _Py_TryFinally(asdl_seq * body, asdl_seq * finalbody, int lineno, int
|
|
||||||
col_offset, PyArena *arena);
|
|
||||||
#define Assert(a0, a1, a2, a3, a4) _Py_Assert(a0, a1, a2, a3, a4)
|
#define Assert(a0, a1, a2, a3, a4) _Py_Assert(a0, a1, a2, a3, a4)
|
||||||
stmt_ty _Py_Assert(expr_ty test, expr_ty msg, int lineno, int col_offset,
|
stmt_ty _Py_Assert(expr_ty test, expr_ty msg, int lineno, int col_offset,
|
||||||
PyArena *arena);
|
PyArena *arena);
|
||||||
|
|
|
@ -347,8 +347,8 @@ exec_results = [
|
||||||
('Module', [('With', (1, 0), [('withitem', ('Name', (1, 5), 'x', ('Load',)), ('Name', (1, 10), 'y', ('Store',)))], [('Pass', (1, 13))])]),
|
('Module', [('With', (1, 0), [('withitem', ('Name', (1, 5), 'x', ('Load',)), ('Name', (1, 10), 'y', ('Store',)))], [('Pass', (1, 13))])]),
|
||||||
('Module', [('With', (1, 0), [('withitem', ('Name', (1, 5), 'x', ('Load',)), ('Name', (1, 10), 'y', ('Store',))), ('withitem', ('Name', (1, 13), 'z', ('Load',)), ('Name', (1, 18), 'q', ('Store',)))], [('Pass', (1, 21))])]),
|
('Module', [('With', (1, 0), [('withitem', ('Name', (1, 5), 'x', ('Load',)), ('Name', (1, 10), 'y', ('Store',))), ('withitem', ('Name', (1, 13), 'z', ('Load',)), ('Name', (1, 18), 'q', ('Store',)))], [('Pass', (1, 21))])]),
|
||||||
('Module', [('Raise', (1, 0), ('Call', (1, 6), ('Name', (1, 6), 'Exception', ('Load',)), [('Str', (1, 16), 'string')], [], None, None), None)]),
|
('Module', [('Raise', (1, 0), ('Call', (1, 6), ('Name', (1, 6), 'Exception', ('Load',)), [('Str', (1, 16), 'string')], [], None, None), None)]),
|
||||||
('Module', [('TryExcept', (1, 0), [('Pass', (2, 2))], [('ExceptHandler', (3, 0), ('Name', (3, 7), 'Exception', ('Load',)), None, [('Pass', (4, 2))])], [])]),
|
('Module', [('Try', (1, 0), [('Pass', (2, 2))], [('ExceptHandler', (3, 0), ('Name', (3, 7), 'Exception', ('Load',)), None, [('Pass', (4, 2))])], [], [])]),
|
||||||
('Module', [('TryFinally', (1, 0), [('Pass', (2, 2))], [('Pass', (4, 2))])]),
|
('Module', [('Try', (1, 0), [('Pass', (2, 2))], [], [], [('Pass', (4, 2))])]),
|
||||||
('Module', [('Assert', (1, 0), ('Name', (1, 7), 'v', ('Load',)), None)]),
|
('Module', [('Assert', (1, 0), ('Name', (1, 7), 'v', ('Load',)), None)]),
|
||||||
('Module', [('Import', (1, 0), [('alias', 'sys', None)])]),
|
('Module', [('Import', (1, 0), [('alias', 'sys', None)])]),
|
||||||
('Module', [('ImportFrom', (1, 0), 'sys', [('alias', 'v', None)], 0)]),
|
('Module', [('ImportFrom', (1, 0), 'sys', [('alias', 'v', None)], 0)]),
|
||||||
|
|
|
@ -10,6 +10,9 @@ What's New in Python 3.3 Alpha 1?
|
||||||
Core and Builtins
|
Core and Builtins
|
||||||
-----------------
|
-----------------
|
||||||
|
|
||||||
|
- Issue #12199: The TryExcept and TryFinally and AST nodes have been unified
|
||||||
|
into a Try node.
|
||||||
|
|
||||||
- Issue #9670: Increase the default stack size for secondary threads on
|
- Issue #9670: Increase the default stack size for secondary threads on
|
||||||
Mac OS X and FreeBSD to reduce the chances of a crash instead of a
|
Mac OS X and FreeBSD to reduce the chances of a crash instead of a
|
||||||
"maximum recursion depth" RuntimeError exception.
|
"maximum recursion depth" RuntimeError exception.
|
||||||
|
|
|
@ -31,8 +31,7 @@ module Python
|
||||||
| With(withitem* items, stmt* body)
|
| With(withitem* items, stmt* body)
|
||||||
|
|
||||||
| Raise(expr? exc, expr? cause)
|
| Raise(expr? exc, expr? cause)
|
||||||
| TryExcept(stmt* body, excepthandler* handlers, stmt* orelse)
|
| Try(stmt* body, excepthandler* handlers, stmt* orelse, stmt* finalbody)
|
||||||
| TryFinally(stmt* body, stmt* finalbody)
|
|
||||||
| Assert(expr test, expr? msg)
|
| Assert(expr test, expr? msg)
|
||||||
|
|
||||||
| Import(alias* names)
|
| Import(alias* names)
|
||||||
|
|
|
@ -103,15 +103,11 @@ static char *Raise_fields[]={
|
||||||
"exc",
|
"exc",
|
||||||
"cause",
|
"cause",
|
||||||
};
|
};
|
||||||
static PyTypeObject *TryExcept_type;
|
static PyTypeObject *Try_type;
|
||||||
static char *TryExcept_fields[]={
|
static char *Try_fields[]={
|
||||||
"body",
|
"body",
|
||||||
"handlers",
|
"handlers",
|
||||||
"orelse",
|
"orelse",
|
||||||
};
|
|
||||||
static PyTypeObject *TryFinally_type;
|
|
||||||
static char *TryFinally_fields[]={
|
|
||||||
"body",
|
|
||||||
"finalbody",
|
"finalbody",
|
||||||
};
|
};
|
||||||
static PyTypeObject *Assert_type;
|
static PyTypeObject *Assert_type;
|
||||||
|
@ -689,11 +685,8 @@ static int init_types(void)
|
||||||
if (!With_type) return 0;
|
if (!With_type) return 0;
|
||||||
Raise_type = make_type("Raise", stmt_type, Raise_fields, 2);
|
Raise_type = make_type("Raise", stmt_type, Raise_fields, 2);
|
||||||
if (!Raise_type) return 0;
|
if (!Raise_type) return 0;
|
||||||
TryExcept_type = make_type("TryExcept", stmt_type, TryExcept_fields, 3);
|
Try_type = make_type("Try", stmt_type, Try_fields, 4);
|
||||||
if (!TryExcept_type) return 0;
|
if (!Try_type) return 0;
|
||||||
TryFinally_type = make_type("TryFinally", stmt_type, TryFinally_fields,
|
|
||||||
2);
|
|
||||||
if (!TryFinally_type) return 0;
|
|
||||||
Assert_type = make_type("Assert", stmt_type, Assert_fields, 2);
|
Assert_type = make_type("Assert", stmt_type, Assert_fields, 2);
|
||||||
if (!Assert_type) return 0;
|
if (!Assert_type) return 0;
|
||||||
Import_type = make_type("Import", stmt_type, Import_fields, 1);
|
Import_type = make_type("Import", stmt_type, Import_fields, 1);
|
||||||
|
@ -1264,33 +1257,18 @@ Raise(expr_ty exc, expr_ty cause, int lineno, int col_offset, PyArena *arena)
|
||||||
}
|
}
|
||||||
|
|
||||||
stmt_ty
|
stmt_ty
|
||||||
TryExcept(asdl_seq * body, asdl_seq * handlers, asdl_seq * orelse, int lineno,
|
Try(asdl_seq * body, asdl_seq * handlers, asdl_seq * orelse, asdl_seq *
|
||||||
int col_offset, PyArena *arena)
|
finalbody, int lineno, int col_offset, PyArena *arena)
|
||||||
{
|
{
|
||||||
stmt_ty p;
|
stmt_ty p;
|
||||||
p = (stmt_ty)PyArena_Malloc(arena, sizeof(*p));
|
p = (stmt_ty)PyArena_Malloc(arena, sizeof(*p));
|
||||||
if (!p)
|
if (!p)
|
||||||
return NULL;
|
return NULL;
|
||||||
p->kind = TryExcept_kind;
|
p->kind = Try_kind;
|
||||||
p->v.TryExcept.body = body;
|
p->v.Try.body = body;
|
||||||
p->v.TryExcept.handlers = handlers;
|
p->v.Try.handlers = handlers;
|
||||||
p->v.TryExcept.orelse = orelse;
|
p->v.Try.orelse = orelse;
|
||||||
p->lineno = lineno;
|
p->v.Try.finalbody = finalbody;
|
||||||
p->col_offset = col_offset;
|
|
||||||
return p;
|
|
||||||
}
|
|
||||||
|
|
||||||
stmt_ty
|
|
||||||
TryFinally(asdl_seq * body, asdl_seq * finalbody, int lineno, int col_offset,
|
|
||||||
PyArena *arena)
|
|
||||||
{
|
|
||||||
stmt_ty p;
|
|
||||||
p = (stmt_ty)PyArena_Malloc(arena, sizeof(*p));
|
|
||||||
if (!p)
|
|
||||||
return NULL;
|
|
||||||
p->kind = TryFinally_kind;
|
|
||||||
p->v.TryFinally.body = body;
|
|
||||||
p->v.TryFinally.finalbody = finalbody;
|
|
||||||
p->lineno = lineno;
|
p->lineno = lineno;
|
||||||
p->col_offset = col_offset;
|
p->col_offset = col_offset;
|
||||||
return p;
|
return p;
|
||||||
|
@ -2434,35 +2412,25 @@ ast2obj_stmt(void* _o)
|
||||||
goto failed;
|
goto failed;
|
||||||
Py_DECREF(value);
|
Py_DECREF(value);
|
||||||
break;
|
break;
|
||||||
case TryExcept_kind:
|
case Try_kind:
|
||||||
result = PyType_GenericNew(TryExcept_type, NULL, NULL);
|
result = PyType_GenericNew(Try_type, NULL, NULL);
|
||||||
if (!result) goto failed;
|
if (!result) goto failed;
|
||||||
value = ast2obj_list(o->v.TryExcept.body, ast2obj_stmt);
|
value = ast2obj_list(o->v.Try.body, ast2obj_stmt);
|
||||||
if (!value) goto failed;
|
if (!value) goto failed;
|
||||||
if (PyObject_SetAttrString(result, "body", value) == -1)
|
if (PyObject_SetAttrString(result, "body", value) == -1)
|
||||||
goto failed;
|
goto failed;
|
||||||
Py_DECREF(value);
|
Py_DECREF(value);
|
||||||
value = ast2obj_list(o->v.TryExcept.handlers,
|
value = ast2obj_list(o->v.Try.handlers, ast2obj_excepthandler);
|
||||||
ast2obj_excepthandler);
|
|
||||||
if (!value) goto failed;
|
if (!value) goto failed;
|
||||||
if (PyObject_SetAttrString(result, "handlers", value) == -1)
|
if (PyObject_SetAttrString(result, "handlers", value) == -1)
|
||||||
goto failed;
|
goto failed;
|
||||||
Py_DECREF(value);
|
Py_DECREF(value);
|
||||||
value = ast2obj_list(o->v.TryExcept.orelse, ast2obj_stmt);
|
value = ast2obj_list(o->v.Try.orelse, ast2obj_stmt);
|
||||||
if (!value) goto failed;
|
if (!value) goto failed;
|
||||||
if (PyObject_SetAttrString(result, "orelse", value) == -1)
|
if (PyObject_SetAttrString(result, "orelse", value) == -1)
|
||||||
goto failed;
|
goto failed;
|
||||||
Py_DECREF(value);
|
Py_DECREF(value);
|
||||||
break;
|
value = ast2obj_list(o->v.Try.finalbody, ast2obj_stmt);
|
||||||
case TryFinally_kind:
|
|
||||||
result = PyType_GenericNew(TryFinally_type, NULL, NULL);
|
|
||||||
if (!result) goto failed;
|
|
||||||
value = ast2obj_list(o->v.TryFinally.body, ast2obj_stmt);
|
|
||||||
if (!value) goto failed;
|
|
||||||
if (PyObject_SetAttrString(result, "body", value) == -1)
|
|
||||||
goto failed;
|
|
||||||
Py_DECREF(value);
|
|
||||||
value = ast2obj_list(o->v.TryFinally.finalbody, ast2obj_stmt);
|
|
||||||
if (!value) goto failed;
|
if (!value) goto failed;
|
||||||
if (PyObject_SetAttrString(result, "finalbody", value) == -1)
|
if (PyObject_SetAttrString(result, "finalbody", value) == -1)
|
||||||
goto failed;
|
goto failed;
|
||||||
|
@ -4343,7 +4311,7 @@ obj2ast_stmt(PyObject* obj, stmt_ty* out, PyArena* arena)
|
||||||
if (*out == NULL) goto failed;
|
if (*out == NULL) goto failed;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
isinstance = PyObject_IsInstance(obj, (PyObject*)TryExcept_type);
|
isinstance = PyObject_IsInstance(obj, (PyObject*)Try_type);
|
||||||
if (isinstance == -1) {
|
if (isinstance == -1) {
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
@ -4351,6 +4319,7 @@ obj2ast_stmt(PyObject* obj, stmt_ty* out, PyArena* arena)
|
||||||
asdl_seq* body;
|
asdl_seq* body;
|
||||||
asdl_seq* handlers;
|
asdl_seq* handlers;
|
||||||
asdl_seq* orelse;
|
asdl_seq* orelse;
|
||||||
|
asdl_seq* finalbody;
|
||||||
|
|
||||||
if (PyObject_HasAttrString(obj, "body")) {
|
if (PyObject_HasAttrString(obj, "body")) {
|
||||||
int res;
|
int res;
|
||||||
|
@ -4359,7 +4328,7 @@ obj2ast_stmt(PyObject* obj, stmt_ty* out, PyArena* arena)
|
||||||
tmp = PyObject_GetAttrString(obj, "body");
|
tmp = PyObject_GetAttrString(obj, "body");
|
||||||
if (tmp == NULL) goto failed;
|
if (tmp == NULL) goto failed;
|
||||||
if (!PyList_Check(tmp)) {
|
if (!PyList_Check(tmp)) {
|
||||||
PyErr_Format(PyExc_TypeError, "TryExcept field \"body\" must be a list, not a %.200s", tmp->ob_type->tp_name);
|
PyErr_Format(PyExc_TypeError, "Try field \"body\" must be a list, not a %.200s", tmp->ob_type->tp_name);
|
||||||
goto failed;
|
goto failed;
|
||||||
}
|
}
|
||||||
len = PyList_GET_SIZE(tmp);
|
len = PyList_GET_SIZE(tmp);
|
||||||
|
@ -4374,7 +4343,7 @@ obj2ast_stmt(PyObject* obj, stmt_ty* out, PyArena* arena)
|
||||||
Py_XDECREF(tmp);
|
Py_XDECREF(tmp);
|
||||||
tmp = NULL;
|
tmp = NULL;
|
||||||
} else {
|
} else {
|
||||||
PyErr_SetString(PyExc_TypeError, "required field \"body\" missing from TryExcept");
|
PyErr_SetString(PyExc_TypeError, "required field \"body\" missing from Try");
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
if (PyObject_HasAttrString(obj, "handlers")) {
|
if (PyObject_HasAttrString(obj, "handlers")) {
|
||||||
|
@ -4384,7 +4353,7 @@ obj2ast_stmt(PyObject* obj, stmt_ty* out, PyArena* arena)
|
||||||
tmp = PyObject_GetAttrString(obj, "handlers");
|
tmp = PyObject_GetAttrString(obj, "handlers");
|
||||||
if (tmp == NULL) goto failed;
|
if (tmp == NULL) goto failed;
|
||||||
if (!PyList_Check(tmp)) {
|
if (!PyList_Check(tmp)) {
|
||||||
PyErr_Format(PyExc_TypeError, "TryExcept field \"handlers\" must be a list, not a %.200s", tmp->ob_type->tp_name);
|
PyErr_Format(PyExc_TypeError, "Try field \"handlers\" must be a list, not a %.200s", tmp->ob_type->tp_name);
|
||||||
goto failed;
|
goto failed;
|
||||||
}
|
}
|
||||||
len = PyList_GET_SIZE(tmp);
|
len = PyList_GET_SIZE(tmp);
|
||||||
|
@ -4399,7 +4368,7 @@ obj2ast_stmt(PyObject* obj, stmt_ty* out, PyArena* arena)
|
||||||
Py_XDECREF(tmp);
|
Py_XDECREF(tmp);
|
||||||
tmp = NULL;
|
tmp = NULL;
|
||||||
} else {
|
} else {
|
||||||
PyErr_SetString(PyExc_TypeError, "required field \"handlers\" missing from TryExcept");
|
PyErr_SetString(PyExc_TypeError, "required field \"handlers\" missing from Try");
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
if (PyObject_HasAttrString(obj, "orelse")) {
|
if (PyObject_HasAttrString(obj, "orelse")) {
|
||||||
|
@ -4409,7 +4378,7 @@ obj2ast_stmt(PyObject* obj, stmt_ty* out, PyArena* arena)
|
||||||
tmp = PyObject_GetAttrString(obj, "orelse");
|
tmp = PyObject_GetAttrString(obj, "orelse");
|
||||||
if (tmp == NULL) goto failed;
|
if (tmp == NULL) goto failed;
|
||||||
if (!PyList_Check(tmp)) {
|
if (!PyList_Check(tmp)) {
|
||||||
PyErr_Format(PyExc_TypeError, "TryExcept field \"orelse\" must be a list, not a %.200s", tmp->ob_type->tp_name);
|
PyErr_Format(PyExc_TypeError, "Try field \"orelse\" must be a list, not a %.200s", tmp->ob_type->tp_name);
|
||||||
goto failed;
|
goto failed;
|
||||||
}
|
}
|
||||||
len = PyList_GET_SIZE(tmp);
|
len = PyList_GET_SIZE(tmp);
|
||||||
|
@ -4424,45 +4393,7 @@ obj2ast_stmt(PyObject* obj, stmt_ty* out, PyArena* arena)
|
||||||
Py_XDECREF(tmp);
|
Py_XDECREF(tmp);
|
||||||
tmp = NULL;
|
tmp = NULL;
|
||||||
} else {
|
} else {
|
||||||
PyErr_SetString(PyExc_TypeError, "required field \"orelse\" missing from TryExcept");
|
PyErr_SetString(PyExc_TypeError, "required field \"orelse\" missing from Try");
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
*out = TryExcept(body, handlers, orelse, lineno, col_offset,
|
|
||||||
arena);
|
|
||||||
if (*out == NULL) goto failed;
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
isinstance = PyObject_IsInstance(obj, (PyObject*)TryFinally_type);
|
|
||||||
if (isinstance == -1) {
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
if (isinstance) {
|
|
||||||
asdl_seq* body;
|
|
||||||
asdl_seq* finalbody;
|
|
||||||
|
|
||||||
if (PyObject_HasAttrString(obj, "body")) {
|
|
||||||
int res;
|
|
||||||
Py_ssize_t len;
|
|
||||||
Py_ssize_t i;
|
|
||||||
tmp = PyObject_GetAttrString(obj, "body");
|
|
||||||
if (tmp == NULL) goto failed;
|
|
||||||
if (!PyList_Check(tmp)) {
|
|
||||||
PyErr_Format(PyExc_TypeError, "TryFinally field \"body\" must be a list, not a %.200s", tmp->ob_type->tp_name);
|
|
||||||
goto failed;
|
|
||||||
}
|
|
||||||
len = PyList_GET_SIZE(tmp);
|
|
||||||
body = asdl_seq_new(len, arena);
|
|
||||||
if (body == NULL) goto failed;
|
|
||||||
for (i = 0; i < len; i++) {
|
|
||||||
stmt_ty value;
|
|
||||||
res = obj2ast_stmt(PyList_GET_ITEM(tmp, i), &value, arena);
|
|
||||||
if (res != 0) goto failed;
|
|
||||||
asdl_seq_SET(body, i, value);
|
|
||||||
}
|
|
||||||
Py_XDECREF(tmp);
|
|
||||||
tmp = NULL;
|
|
||||||
} else {
|
|
||||||
PyErr_SetString(PyExc_TypeError, "required field \"body\" missing from TryFinally");
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
if (PyObject_HasAttrString(obj, "finalbody")) {
|
if (PyObject_HasAttrString(obj, "finalbody")) {
|
||||||
|
@ -4472,7 +4403,7 @@ obj2ast_stmt(PyObject* obj, stmt_ty* out, PyArena* arena)
|
||||||
tmp = PyObject_GetAttrString(obj, "finalbody");
|
tmp = PyObject_GetAttrString(obj, "finalbody");
|
||||||
if (tmp == NULL) goto failed;
|
if (tmp == NULL) goto failed;
|
||||||
if (!PyList_Check(tmp)) {
|
if (!PyList_Check(tmp)) {
|
||||||
PyErr_Format(PyExc_TypeError, "TryFinally field \"finalbody\" must be a list, not a %.200s", tmp->ob_type->tp_name);
|
PyErr_Format(PyExc_TypeError, "Try field \"finalbody\" must be a list, not a %.200s", tmp->ob_type->tp_name);
|
||||||
goto failed;
|
goto failed;
|
||||||
}
|
}
|
||||||
len = PyList_GET_SIZE(tmp);
|
len = PyList_GET_SIZE(tmp);
|
||||||
|
@ -4487,10 +4418,11 @@ obj2ast_stmt(PyObject* obj, stmt_ty* out, PyArena* arena)
|
||||||
Py_XDECREF(tmp);
|
Py_XDECREF(tmp);
|
||||||
tmp = NULL;
|
tmp = NULL;
|
||||||
} else {
|
} else {
|
||||||
PyErr_SetString(PyExc_TypeError, "required field \"finalbody\" missing from TryFinally");
|
PyErr_SetString(PyExc_TypeError, "required field \"finalbody\" missing from Try");
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
*out = TryFinally(body, finalbody, lineno, col_offset, arena);
|
*out = Try(body, handlers, orelse, finalbody, lineno,
|
||||||
|
col_offset, arena);
|
||||||
if (*out == NULL) goto failed;
|
if (*out == NULL) goto failed;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -6853,10 +6785,8 @@ PyInit__ast(void)
|
||||||
NULL;
|
NULL;
|
||||||
if (PyDict_SetItemString(d, "Raise", (PyObject*)Raise_type) < 0) return
|
if (PyDict_SetItemString(d, "Raise", (PyObject*)Raise_type) < 0) return
|
||||||
NULL;
|
NULL;
|
||||||
if (PyDict_SetItemString(d, "TryExcept", (PyObject*)TryExcept_type) <
|
if (PyDict_SetItemString(d, "Try", (PyObject*)Try_type) < 0) return
|
||||||
0) return NULL;
|
NULL;
|
||||||
if (PyDict_SetItemString(d, "TryFinally", (PyObject*)TryFinally_type) <
|
|
||||||
0) return NULL;
|
|
||||||
if (PyDict_SetItemString(d, "Assert", (PyObject*)Assert_type) < 0)
|
if (PyDict_SetItemString(d, "Assert", (PyObject*)Assert_type) < 0)
|
||||||
return NULL;
|
return NULL;
|
||||||
if (PyDict_SetItemString(d, "Import", (PyObject*)Import_type) < 0)
|
if (PyDict_SetItemString(d, "Import", (PyObject*)Import_type) < 0)
|
||||||
|
|
22
Python/ast.c
22
Python/ast.c
|
@ -2893,7 +2893,7 @@ ast_for_try_stmt(struct compiling *c, const node *n)
|
||||||
{
|
{
|
||||||
const int nch = NCH(n);
|
const int nch = NCH(n);
|
||||||
int n_except = (nch - 3)/3;
|
int n_except = (nch - 3)/3;
|
||||||
asdl_seq *body, *orelse = NULL, *finally = NULL;
|
asdl_seq *body, *handlers = NULL, *orelse = NULL, *finally = NULL;
|
||||||
|
|
||||||
REQ(n, try_stmt);
|
REQ(n, try_stmt);
|
||||||
|
|
||||||
|
@ -2934,9 +2934,8 @@ ast_for_try_stmt(struct compiling *c, const node *n)
|
||||||
|
|
||||||
if (n_except > 0) {
|
if (n_except > 0) {
|
||||||
int i;
|
int i;
|
||||||
stmt_ty except_st;
|
|
||||||
/* process except statements to create a try ... except */
|
/* process except statements to create a try ... except */
|
||||||
asdl_seq *handlers = asdl_seq_new(n_except, c->c_arena);
|
handlers = asdl_seq_new(n_except, c->c_arena);
|
||||||
if (handlers == NULL)
|
if (handlers == NULL)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
|
@ -2947,23 +2946,10 @@ ast_for_try_stmt(struct compiling *c, const node *n)
|
||||||
return NULL;
|
return NULL;
|
||||||
asdl_seq_SET(handlers, i, e);
|
asdl_seq_SET(handlers, i, e);
|
||||||
}
|
}
|
||||||
|
|
||||||
except_st = TryExcept(body, handlers, orelse, LINENO(n),
|
|
||||||
n->n_col_offset, c->c_arena);
|
|
||||||
if (!finally)
|
|
||||||
return except_st;
|
|
||||||
|
|
||||||
/* if a 'finally' is present too, we nest the TryExcept within a
|
|
||||||
TryFinally to emulate try ... except ... finally */
|
|
||||||
body = asdl_seq_new(1, c->c_arena);
|
|
||||||
if (body == NULL)
|
|
||||||
return NULL;
|
|
||||||
asdl_seq_SET(body, 0, except_st);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* must be a try ... finally (except clauses are in body, if any exist) */
|
assert(finally != NULL || asdl_seq_LEN(handlers));
|
||||||
assert(finally != NULL);
|
return Try(body, handlers, orelse, finally, LINENO(n), n->n_col_offset, c->c_arena);
|
||||||
return TryFinally(body, finally, LINENO(n), n->n_col_offset, c->c_arena);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* with_item: test ['as' expr] */
|
/* with_item: test ['as' expr] */
|
||||||
|
|
|
@ -185,6 +185,7 @@ static int compiler_call_helper(struct compiler *c, int n,
|
||||||
asdl_seq *keywords,
|
asdl_seq *keywords,
|
||||||
expr_ty starargs,
|
expr_ty starargs,
|
||||||
expr_ty kwargs);
|
expr_ty kwargs);
|
||||||
|
static int compiler_try_except(struct compiler *, stmt_ty);
|
||||||
|
|
||||||
static PyCodeObject *assemble(struct compiler *, int addNone);
|
static PyCodeObject *assemble(struct compiler *, int addNone);
|
||||||
static PyObject *__doc__;
|
static PyObject *__doc__;
|
||||||
|
@ -1898,7 +1899,13 @@ compiler_try_finally(struct compiler *c, stmt_ty s)
|
||||||
compiler_use_next_block(c, body);
|
compiler_use_next_block(c, body);
|
||||||
if (!compiler_push_fblock(c, FINALLY_TRY, body))
|
if (!compiler_push_fblock(c, FINALLY_TRY, body))
|
||||||
return 0;
|
return 0;
|
||||||
VISIT_SEQ(c, stmt, s->v.TryFinally.body);
|
if (s->v.Try.handlers && asdl_seq_LEN(s->v.Try.handlers)) {
|
||||||
|
if (!compiler_try_except(c, s))
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
VISIT_SEQ(c, stmt, s->v.Try.body);
|
||||||
|
}
|
||||||
ADDOP(c, POP_BLOCK);
|
ADDOP(c, POP_BLOCK);
|
||||||
compiler_pop_fblock(c, FINALLY_TRY, body);
|
compiler_pop_fblock(c, FINALLY_TRY, body);
|
||||||
|
|
||||||
|
@ -1906,7 +1913,7 @@ compiler_try_finally(struct compiler *c, stmt_ty s)
|
||||||
compiler_use_next_block(c, end);
|
compiler_use_next_block(c, end);
|
||||||
if (!compiler_push_fblock(c, FINALLY_END, end))
|
if (!compiler_push_fblock(c, FINALLY_END, end))
|
||||||
return 0;
|
return 0;
|
||||||
VISIT_SEQ(c, stmt, s->v.TryFinally.finalbody);
|
VISIT_SEQ(c, stmt, s->v.Try.finalbody);
|
||||||
ADDOP(c, END_FINALLY);
|
ADDOP(c, END_FINALLY);
|
||||||
compiler_pop_fblock(c, FINALLY_END, end);
|
compiler_pop_fblock(c, FINALLY_END, end);
|
||||||
|
|
||||||
|
@ -1960,15 +1967,15 @@ compiler_try_except(struct compiler *c, stmt_ty s)
|
||||||
compiler_use_next_block(c, body);
|
compiler_use_next_block(c, body);
|
||||||
if (!compiler_push_fblock(c, EXCEPT, body))
|
if (!compiler_push_fblock(c, EXCEPT, body))
|
||||||
return 0;
|
return 0;
|
||||||
VISIT_SEQ(c, stmt, s->v.TryExcept.body);
|
VISIT_SEQ(c, stmt, s->v.Try.body);
|
||||||
ADDOP(c, POP_BLOCK);
|
ADDOP(c, POP_BLOCK);
|
||||||
compiler_pop_fblock(c, EXCEPT, body);
|
compiler_pop_fblock(c, EXCEPT, body);
|
||||||
ADDOP_JREL(c, JUMP_FORWARD, orelse);
|
ADDOP_JREL(c, JUMP_FORWARD, orelse);
|
||||||
n = asdl_seq_LEN(s->v.TryExcept.handlers);
|
n = asdl_seq_LEN(s->v.Try.handlers);
|
||||||
compiler_use_next_block(c, except);
|
compiler_use_next_block(c, except);
|
||||||
for (i = 0; i < n; i++) {
|
for (i = 0; i < n; i++) {
|
||||||
excepthandler_ty handler = (excepthandler_ty)asdl_seq_GET(
|
excepthandler_ty handler = (excepthandler_ty)asdl_seq_GET(
|
||||||
s->v.TryExcept.handlers, i);
|
s->v.Try.handlers, i);
|
||||||
if (!handler->v.ExceptHandler.type && i < n-1)
|
if (!handler->v.ExceptHandler.type && i < n-1)
|
||||||
return compiler_error(c, "default 'except:' must be last");
|
return compiler_error(c, "default 'except:' must be last");
|
||||||
c->u->u_lineno_set = 0;
|
c->u->u_lineno_set = 0;
|
||||||
|
@ -2055,11 +2062,20 @@ compiler_try_except(struct compiler *c, stmt_ty s)
|
||||||
}
|
}
|
||||||
ADDOP(c, END_FINALLY);
|
ADDOP(c, END_FINALLY);
|
||||||
compiler_use_next_block(c, orelse);
|
compiler_use_next_block(c, orelse);
|
||||||
VISIT_SEQ(c, stmt, s->v.TryExcept.orelse);
|
VISIT_SEQ(c, stmt, s->v.Try.orelse);
|
||||||
compiler_use_next_block(c, end);
|
compiler_use_next_block(c, end);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
compiler_try(struct compiler *c, stmt_ty s) {
|
||||||
|
if (s->v.Try.finalbody && asdl_seq_LEN(s->v.Try.finalbody))
|
||||||
|
return compiler_try_finally(c, s);
|
||||||
|
else
|
||||||
|
return compiler_try_except(c, s);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
static int
|
static int
|
||||||
compiler_import_as(struct compiler *c, identifier name, identifier asname)
|
compiler_import_as(struct compiler *c, identifier name, identifier asname)
|
||||||
{
|
{
|
||||||
|
@ -2307,10 +2323,8 @@ compiler_visit_stmt(struct compiler *c, stmt_ty s)
|
||||||
}
|
}
|
||||||
ADDOP_I(c, RAISE_VARARGS, n);
|
ADDOP_I(c, RAISE_VARARGS, n);
|
||||||
break;
|
break;
|
||||||
case TryExcept_kind:
|
case Try_kind:
|
||||||
return compiler_try_except(c, s);
|
return compiler_try(c, s);
|
||||||
case TryFinally_kind:
|
|
||||||
return compiler_try_finally(c, s);
|
|
||||||
case Assert_kind:
|
case Assert_kind:
|
||||||
return compiler_assert(c, s);
|
return compiler_assert(c, s);
|
||||||
case Import_kind:
|
case Import_kind:
|
||||||
|
|
|
@ -1211,14 +1211,11 @@ symtable_visit_stmt(struct symtable *st, stmt_ty s)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case TryExcept_kind:
|
case Try_kind:
|
||||||
VISIT_SEQ(st, stmt, s->v.TryExcept.body);
|
VISIT_SEQ(st, stmt, s->v.Try.body);
|
||||||
VISIT_SEQ(st, stmt, s->v.TryExcept.orelse);
|
VISIT_SEQ(st, stmt, s->v.Try.orelse);
|
||||||
VISIT_SEQ(st, excepthandler, s->v.TryExcept.handlers);
|
VISIT_SEQ(st, excepthandler, s->v.Try.handlers);
|
||||||
break;
|
VISIT_SEQ(st, stmt, s->v.Try.finalbody);
|
||||||
case TryFinally_kind:
|
|
||||||
VISIT_SEQ(st, stmt, s->v.TryFinally.body);
|
|
||||||
VISIT_SEQ(st, stmt, s->v.TryFinally.finalbody);
|
|
||||||
break;
|
break;
|
||||||
case Assert_kind:
|
case Assert_kind:
|
||||||
VISIT(st, expr, s->v.Assert.test);
|
VISIT(st, expr, s->v.Assert.test);
|
||||||
|
|
Loading…
Reference in New Issue