Index: Python/compile.c =================================================================== --- Python/compile.c (revision 61399) +++ Python/compile.c (working copy) @@ -2203,8 +2203,11 @@ return UNARY_POSITIVE; case USub: return UNARY_NEGATIVE; + default: + PyErr_Format(PyExc_SystemError, + "unary op %d should not be possible", op); + return 0; } - return 0; } static int @@ -2238,8 +2241,11 @@ return BINARY_AND; case FloorDiv: return BINARY_FLOOR_DIVIDE; + default: + PyErr_Format(PyExc_SystemError, + "binary op %d should not be possible", op); + return 0; } - return 0; } static int @@ -2266,8 +2272,9 @@ return PyCmp_IN; case NotIn: return PyCmp_NOT_IN; + default: + return PyCmp_BAD; } - return PyCmp_BAD; } static int @@ -2301,10 +2308,11 @@ return INPLACE_AND; case FloorDiv: return INPLACE_FLOOR_DIVIDE; + default: + PyErr_Format(PyExc_SystemError, + "inplace binary op %d should not be possible", op); + return 0; } - PyErr_Format(PyExc_SystemError, - "inplace binary op %d should not be possible", op); - return 0; } static int Index: Python/Python-ast.c =================================================================== --- Python/Python-ast.c (revision 61399) +++ Python/Python-ast.c (working copy) @@ -446,6 +446,47 @@ return PyInt_FromLong(b); } +static int obj2ast_object(PyObject* obj, PyObject** out, PyArena* arena) +{ + if (obj == Py_None) + obj = NULL; + Py_XINCREF(obj); + *out = obj; + return 0; +} + +#define obj2ast_identifier obj2ast_object +#define obj2ast_string obj2ast_object + +static int obj2ast_int(PyObject* obj, int* out, PyArena* arena) +{ + if (!PyInt_Check(obj) && !PyLong_Check(obj)) { + PyObject *s = PyObject_Repr(obj); + if (s == NULL) return 1; + PyErr_Format(PyExc_ValueError, "invalid integer value: %s", PyString_AsString(s)); + Py_DECREF(s); + return 1; + } + + *out = (int)PyLong_AsLong(obj); + return 0; +} + +static int obj2ast_bool(PyObject* obj, bool* out, PyArena* arena) +{ + if (!PyBool_Check(obj)) { + PyObject *s = PyObject_Repr(obj); + if (s == NULL) return 1; + PyErr_Format(PyExc_ValueError, "invalid boolean value: %s", PyString_AsString(s)); + Py_DECREF(s); + return 1; + } + + *out = (obj == Py_True); + return 0; +} + + static int init_types(void) { static int initialized; @@ -736,6 +777,24 @@ return 1; } +static int obj2ast_mod(PyObject* obj, mod_ty* out, PyArena* arena); +static int obj2ast_stmt(PyObject* obj, stmt_ty* out, PyArena* arena); +static int obj2ast_expr(PyObject* obj, expr_ty* out, PyArena* arena); +static int obj2ast_expr_context(PyObject* obj, expr_context_ty* out, PyArena* + arena); +static int obj2ast_slice(PyObject* obj, slice_ty* out, PyArena* arena); +static int obj2ast_boolop(PyObject* obj, boolop_ty* out, PyArena* arena); +static int obj2ast_operator(PyObject* obj, operator_ty* out, PyArena* arena); +static int obj2ast_unaryop(PyObject* obj, unaryop_ty* out, PyArena* arena); +static int obj2ast_cmpop(PyObject* obj, cmpop_ty* out, PyArena* arena); +static int obj2ast_comprehension(PyObject* obj, comprehension_ty* out, PyArena* + arena); +static int obj2ast_excepthandler(PyObject* obj, excepthandler_ty* out, PyArena* + arena); +static int obj2ast_arguments(PyObject* obj, arguments_ty* out, PyArena* arena); +static int obj2ast_keyword(PyObject* obj, keyword_ty* out, PyArena* arena); +static int obj2ast_alias(PyObject* obj, alias_ty* out, PyArena* arena); + mod_ty Module(asdl_seq * body, PyArena *arena) { @@ -2600,8 +2659,11 @@ case Param: Py_INCREF(Param_singleton); return Param_singleton; + default: + /* should never happen, but just in case ... */ + PyErr_Format(PyExc_SystemError, "unknown expr_context found"); + return NULL; } - return NULL; /* cannot happen */ } PyObject* ast2obj_slice(void* _o) @@ -2672,8 +2734,11 @@ case Or: Py_INCREF(Or_singleton); return Or_singleton; + default: + /* should never happen, but just in case ... */ + PyErr_Format(PyExc_SystemError, "unknown boolop found"); + return NULL; } - return NULL; /* cannot happen */ } PyObject* ast2obj_operator(operator_ty o) { @@ -2714,8 +2779,11 @@ case FloorDiv: Py_INCREF(FloorDiv_singleton); return FloorDiv_singleton; + default: + /* should never happen, but just in case ... */ + PyErr_Format(PyExc_SystemError, "unknown operator found"); + return NULL; } - return NULL; /* cannot happen */ } PyObject* ast2obj_unaryop(unaryop_ty o) { @@ -2732,8 +2800,11 @@ case USub: Py_INCREF(USub_singleton); return USub_singleton; + default: + /* should never happen, but just in case ... */ + PyErr_Format(PyExc_SystemError, "unknown unaryop found"); + return NULL; } - return NULL; /* cannot happen */ } PyObject* ast2obj_cmpop(cmpop_ty o) { @@ -2768,8 +2839,11 @@ case NotIn: Py_INCREF(NotIn_singleton); return NotIn_singleton; + default: + /* should never happen, but just in case ... */ + PyErr_Format(PyExc_SystemError, "unknown cmpop found"); + return NULL; } - return NULL; /* cannot happen */ } PyObject* ast2obj_comprehension(void* _o) @@ -2947,6 +3021,2669 @@ } +int +obj2ast_mod(PyObject* obj, mod_ty* out, PyArena* arena) +{ + PyObject* tmp = NULL; + + if (obj == Py_None) { + *out = NULL; + return 0; + } + if (PyObject_IsInstance(obj, (PyObject*)Module_type)) { + asdl_seq* body; + + 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; + len = PyList_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_GetItem(tmp, i), &value, arena); + if (res != 0) goto failed; + asdl_seq_SET(body, i, value); + } + Py_DECREF(tmp); + tmp = NULL; + } + else { + PyErr_SetString(PyExc_SystemError, "required field \"body\" missing from Module"); + return 1; + } + *out = Module(body, arena); + if (*out == NULL) goto failed; + return 0; + } + if (PyObject_IsInstance(obj, (PyObject*)Interactive_type)) { + asdl_seq* body; + + 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; + len = PyList_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_GetItem(tmp, i), &value, arena); + if (res != 0) goto failed; + asdl_seq_SET(body, i, value); + } + Py_DECREF(tmp); + tmp = NULL; + } + else { + PyErr_SetString(PyExc_SystemError, "required field \"body\" missing from Interactive"); + return 1; + } + *out = Interactive(body, arena); + if (*out == NULL) goto failed; + return 0; + } + if (PyObject_IsInstance(obj, (PyObject*)Expression_type)) { + expr_ty body; + + if (PyObject_HasAttrString(obj, "body")) { + int res; + tmp = PyObject_GetAttrString(obj, "body"); + if (tmp == NULL) goto failed; + res = obj2ast_expr(tmp, &body, arena); + if (res != 0) goto failed; + Py_DECREF(tmp); + tmp = NULL; + } + else { + PyErr_SetString(PyExc_SystemError, "required field \"body\" missing from Expression"); + return 1; + } + *out = Expression(body, arena); + if (*out == NULL) goto failed; + return 0; + } + if (PyObject_IsInstance(obj, (PyObject*)Suite_type)) { + asdl_seq* body; + + 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; + len = PyList_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_GetItem(tmp, i), &value, arena); + if (res != 0) goto failed; + asdl_seq_SET(body, i, value); + } + Py_DECREF(tmp); + tmp = NULL; + } + else { + PyErr_SetString(PyExc_SystemError, "required field \"body\" missing from Suite"); + return 1; + } + *out = Suite(body, arena); + if (*out == NULL) goto failed; + return 0; + } + + tmp = PyObject_Str(obj); + if (tmp == NULL) goto failed; + PyErr_Format(PyExc_TypeError, "expected some sort of mod, but got %s", PyString_AsString(tmp)); +failed: + Py_XDECREF(tmp); + return 1; +} + +int +obj2ast_stmt(PyObject* obj, stmt_ty* out, PyArena* arena) +{ + PyObject* tmp = NULL; + int lineno; + int col_offset; + + if (obj == Py_None) { + *out = NULL; + return 0; + } + if (PyObject_HasAttrString(obj, "lineno")) { + int res; + tmp = PyObject_GetAttrString(obj, "lineno"); + if (tmp == NULL) goto failed; + res = obj2ast_int(tmp, &lineno, arena); + if (res != 0) goto failed; + Py_DECREF(tmp); + tmp = NULL; + } + else { + PyErr_SetString(PyExc_SystemError, "required field \"lineno\" missing from stmt"); + return 1; + } + if (PyObject_HasAttrString(obj, "col_offset")) { + int res; + tmp = PyObject_GetAttrString(obj, "col_offset"); + if (tmp == NULL) goto failed; + res = obj2ast_int(tmp, &col_offset, arena); + if (res != 0) goto failed; + Py_DECREF(tmp); + tmp = NULL; + } + else { + PyErr_SetString(PyExc_SystemError, "required field \"col_offset\" missing from stmt"); + return 1; + } + if (PyObject_IsInstance(obj, (PyObject*)FunctionDef_type)) { + identifier name; + arguments_ty args; + asdl_seq* body; + asdl_seq* decorator_list; + + if (PyObject_HasAttrString(obj, "name")) { + int res; + tmp = PyObject_GetAttrString(obj, "name"); + if (tmp == NULL) goto failed; + res = obj2ast_identifier(tmp, &name, arena); + if (res != 0) goto failed; + Py_DECREF(tmp); + tmp = NULL; + } + else { + PyErr_SetString(PyExc_SystemError, "required field \"name\" missing from FunctionDef"); + return 1; + } + if (PyObject_HasAttrString(obj, "args")) { + int res; + tmp = PyObject_GetAttrString(obj, "args"); + if (tmp == NULL) goto failed; + res = obj2ast_arguments(tmp, &args, arena); + if (res != 0) goto failed; + Py_DECREF(tmp); + tmp = NULL; + } + else { + PyErr_SetString(PyExc_SystemError, "required field \"args\" missing from FunctionDef"); + return 1; + } + 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; + len = PyList_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_GetItem(tmp, i), &value, arena); + if (res != 0) goto failed; + asdl_seq_SET(body, i, value); + } + Py_DECREF(tmp); + tmp = NULL; + } + else { + PyErr_SetString(PyExc_SystemError, "required field \"body\" missing from FunctionDef"); + return 1; + } + if (PyObject_HasAttrString(obj, "decorator_list")) { + int res; + Py_ssize_t len; + Py_ssize_t i; + tmp = PyObject_GetAttrString(obj, "decorator_list"); + if (tmp == NULL) goto failed; + len = PyList_Size(tmp); + decorator_list = asdl_seq_new(len, arena); + if (decorator_list == NULL) goto failed; + for (i = 0; i < len; i++) { + expr_ty value; + res = obj2ast_expr(PyList_GetItem(tmp, i), &value, arena); + if (res != 0) goto failed; + asdl_seq_SET(decorator_list, i, value); + } + Py_DECREF(tmp); + tmp = NULL; + } + else { + PyErr_SetString(PyExc_SystemError, "required field \"decorator_list\" missing from FunctionDef"); + return 1; + } + *out = FunctionDef(name, args, body, decorator_list, lineno, + col_offset, arena); + if (*out == NULL) goto failed; + return 0; + } + if (PyObject_IsInstance(obj, (PyObject*)ClassDef_type)) { + identifier name; + asdl_seq* bases; + asdl_seq* body; + asdl_seq* decorator_list; + + if (PyObject_HasAttrString(obj, "name")) { + int res; + tmp = PyObject_GetAttrString(obj, "name"); + if (tmp == NULL) goto failed; + res = obj2ast_identifier(tmp, &name, arena); + if (res != 0) goto failed; + Py_DECREF(tmp); + tmp = NULL; + } + else { + PyErr_SetString(PyExc_SystemError, "required field \"name\" missing from ClassDef"); + return 1; + } + if (PyObject_HasAttrString(obj, "bases")) { + int res; + Py_ssize_t len; + Py_ssize_t i; + tmp = PyObject_GetAttrString(obj, "bases"); + if (tmp == NULL) goto failed; + len = PyList_Size(tmp); + bases = asdl_seq_new(len, arena); + if (bases == NULL) goto failed; + for (i = 0; i < len; i++) { + expr_ty value; + res = obj2ast_expr(PyList_GetItem(tmp, i), &value, arena); + if (res != 0) goto failed; + asdl_seq_SET(bases, i, value); + } + Py_DECREF(tmp); + tmp = NULL; + } + else { + PyErr_SetString(PyExc_SystemError, "required field \"bases\" missing from ClassDef"); + return 1; + } + 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; + len = PyList_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_GetItem(tmp, i), &value, arena); + if (res != 0) goto failed; + asdl_seq_SET(body, i, value); + } + Py_DECREF(tmp); + tmp = NULL; + } + else { + PyErr_SetString(PyExc_SystemError, "required field \"body\" missing from ClassDef"); + return 1; + } + if (PyObject_HasAttrString(obj, "decorator_list")) { + int res; + Py_ssize_t len; + Py_ssize_t i; + tmp = PyObject_GetAttrString(obj, "decorator_list"); + if (tmp == NULL) goto failed; + len = PyList_Size(tmp); + decorator_list = asdl_seq_new(len, arena); + if (decorator_list == NULL) goto failed; + for (i = 0; i < len; i++) { + expr_ty value; + res = obj2ast_expr(PyList_GetItem(tmp, i), &value, arena); + if (res != 0) goto failed; + asdl_seq_SET(decorator_list, i, value); + } + Py_DECREF(tmp); + tmp = NULL; + } + else { + PyErr_SetString(PyExc_SystemError, "required field \"decorator_list\" missing from ClassDef"); + return 1; + } + *out = ClassDef(name, bases, body, decorator_list, lineno, + col_offset, arena); + if (*out == NULL) goto failed; + return 0; + } + if (PyObject_IsInstance(obj, (PyObject*)Return_type)) { + expr_ty value; + + if (PyObject_HasAttrString(obj, "value")) { + int res; + tmp = PyObject_GetAttrString(obj, "value"); + if (tmp == NULL) goto failed; + res = obj2ast_expr(tmp, &value, arena); + if (res != 0) goto failed; + Py_DECREF(tmp); + tmp = NULL; + } + else { + value = NULL; + } + *out = Return(value, lineno, col_offset, arena); + if (*out == NULL) goto failed; + return 0; + } + if (PyObject_IsInstance(obj, (PyObject*)Delete_type)) { + asdl_seq* targets; + + if (PyObject_HasAttrString(obj, "targets")) { + int res; + Py_ssize_t len; + Py_ssize_t i; + tmp = PyObject_GetAttrString(obj, "targets"); + if (tmp == NULL) goto failed; + len = PyList_Size(tmp); + targets = asdl_seq_new(len, arena); + if (targets == NULL) goto failed; + for (i = 0; i < len; i++) { + expr_ty value; + res = obj2ast_expr(PyList_GetItem(tmp, i), &value, arena); + if (res != 0) goto failed; + asdl_seq_SET(targets, i, value); + } + Py_DECREF(tmp); + tmp = NULL; + } + else { + PyErr_SetString(PyExc_SystemError, "required field \"targets\" missing from Delete"); + return 1; + } + *out = Delete(targets, lineno, col_offset, arena); + if (*out == NULL) goto failed; + return 0; + } + if (PyObject_IsInstance(obj, (PyObject*)Assign_type)) { + asdl_seq* targets; + expr_ty value; + + if (PyObject_HasAttrString(obj, "targets")) { + int res; + Py_ssize_t len; + Py_ssize_t i; + tmp = PyObject_GetAttrString(obj, "targets"); + if (tmp == NULL) goto failed; + len = PyList_Size(tmp); + targets = asdl_seq_new(len, arena); + if (targets == NULL) goto failed; + for (i = 0; i < len; i++) { + expr_ty value; + res = obj2ast_expr(PyList_GetItem(tmp, i), &value, arena); + if (res != 0) goto failed; + asdl_seq_SET(targets, i, value); + } + Py_DECREF(tmp); + tmp = NULL; + } + else { + PyErr_SetString(PyExc_SystemError, "required field \"targets\" missing from Assign"); + return 1; + } + if (PyObject_HasAttrString(obj, "value")) { + int res; + tmp = PyObject_GetAttrString(obj, "value"); + if (tmp == NULL) goto failed; + res = obj2ast_expr(tmp, &value, arena); + if (res != 0) goto failed; + Py_DECREF(tmp); + tmp = NULL; + } + else { + PyErr_SetString(PyExc_SystemError, "required field \"value\" missing from Assign"); + return 1; + } + *out = Assign(targets, value, lineno, col_offset, arena); + if (*out == NULL) goto failed; + return 0; + } + if (PyObject_IsInstance(obj, (PyObject*)AugAssign_type)) { + expr_ty target; + operator_ty op; + expr_ty value; + + if (PyObject_HasAttrString(obj, "target")) { + int res; + tmp = PyObject_GetAttrString(obj, "target"); + if (tmp == NULL) goto failed; + res = obj2ast_expr(tmp, &target, arena); + if (res != 0) goto failed; + Py_DECREF(tmp); + tmp = NULL; + } + else { + PyErr_SetString(PyExc_SystemError, "required field \"target\" missing from AugAssign"); + return 1; + } + if (PyObject_HasAttrString(obj, "op")) { + int res; + tmp = PyObject_GetAttrString(obj, "op"); + if (tmp == NULL) goto failed; + res = obj2ast_operator(tmp, &op, arena); + if (res != 0) goto failed; + Py_DECREF(tmp); + tmp = NULL; + } + else { + PyErr_SetString(PyExc_SystemError, "required field \"op\" missing from AugAssign"); + return 1; + } + if (PyObject_HasAttrString(obj, "value")) { + int res; + tmp = PyObject_GetAttrString(obj, "value"); + if (tmp == NULL) goto failed; + res = obj2ast_expr(tmp, &value, arena); + if (res != 0) goto failed; + Py_DECREF(tmp); + tmp = NULL; + } + else { + PyErr_SetString(PyExc_SystemError, "required field \"value\" missing from AugAssign"); + return 1; + } + *out = AugAssign(target, op, value, lineno, col_offset, arena); + if (*out == NULL) goto failed; + return 0; + } + if (PyObject_IsInstance(obj, (PyObject*)Print_type)) { + expr_ty dest; + asdl_seq* values; + bool nl; + + if (PyObject_HasAttrString(obj, "dest")) { + int res; + tmp = PyObject_GetAttrString(obj, "dest"); + if (tmp == NULL) goto failed; + res = obj2ast_expr(tmp, &dest, arena); + if (res != 0) goto failed; + Py_DECREF(tmp); + tmp = NULL; + } + else { + dest = NULL; + } + if (PyObject_HasAttrString(obj, "values")) { + int res; + Py_ssize_t len; + Py_ssize_t i; + tmp = PyObject_GetAttrString(obj, "values"); + if (tmp == NULL) goto failed; + len = PyList_Size(tmp); + values = asdl_seq_new(len, arena); + if (values == NULL) goto failed; + for (i = 0; i < len; i++) { + expr_ty value; + res = obj2ast_expr(PyList_GetItem(tmp, i), &value, arena); + if (res != 0) goto failed; + asdl_seq_SET(values, i, value); + } + Py_DECREF(tmp); + tmp = NULL; + } + else { + PyErr_SetString(PyExc_SystemError, "required field \"values\" missing from Print"); + return 1; + } + if (PyObject_HasAttrString(obj, "nl")) { + int res; + tmp = PyObject_GetAttrString(obj, "nl"); + if (tmp == NULL) goto failed; + res = obj2ast_bool(tmp, &nl, arena); + if (res != 0) goto failed; + Py_DECREF(tmp); + tmp = NULL; + } + else { + PyErr_SetString(PyExc_SystemError, "required field \"nl\" missing from Print"); + return 1; + } + *out = Print(dest, values, nl, lineno, col_offset, arena); + if (*out == NULL) goto failed; + return 0; + } + if (PyObject_IsInstance(obj, (PyObject*)For_type)) { + expr_ty target; + expr_ty iter; + asdl_seq* body; + asdl_seq* orelse; + + if (PyObject_HasAttrString(obj, "target")) { + int res; + tmp = PyObject_GetAttrString(obj, "target"); + if (tmp == NULL) goto failed; + res = obj2ast_expr(tmp, &target, arena); + if (res != 0) goto failed; + Py_DECREF(tmp); + tmp = NULL; + } + else { + PyErr_SetString(PyExc_SystemError, "required field \"target\" missing from For"); + return 1; + } + if (PyObject_HasAttrString(obj, "iter")) { + int res; + tmp = PyObject_GetAttrString(obj, "iter"); + if (tmp == NULL) goto failed; + res = obj2ast_expr(tmp, &iter, arena); + if (res != 0) goto failed; + Py_DECREF(tmp); + tmp = NULL; + } + else { + PyErr_SetString(PyExc_SystemError, "required field \"iter\" missing from For"); + return 1; + } + 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; + len = PyList_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_GetItem(tmp, i), &value, arena); + if (res != 0) goto failed; + asdl_seq_SET(body, i, value); + } + Py_DECREF(tmp); + tmp = NULL; + } + else { + PyErr_SetString(PyExc_SystemError, "required field \"body\" missing from For"); + return 1; + } + if (PyObject_HasAttrString(obj, "orelse")) { + int res; + Py_ssize_t len; + Py_ssize_t i; + tmp = PyObject_GetAttrString(obj, "orelse"); + if (tmp == NULL) goto failed; + len = PyList_Size(tmp); + orelse = asdl_seq_new(len, arena); + if (orelse == NULL) goto failed; + for (i = 0; i < len; i++) { + stmt_ty value; + res = obj2ast_stmt(PyList_GetItem(tmp, i), &value, arena); + if (res != 0) goto failed; + asdl_seq_SET(orelse, i, value); + } + Py_DECREF(tmp); + tmp = NULL; + } + else { + PyErr_SetString(PyExc_SystemError, "required field \"orelse\" missing from For"); + return 1; + } + *out = For(target, iter, body, orelse, lineno, col_offset, + arena); + if (*out == NULL) goto failed; + return 0; + } + if (PyObject_IsInstance(obj, (PyObject*)While_type)) { + expr_ty test; + asdl_seq* body; + asdl_seq* orelse; + + if (PyObject_HasAttrString(obj, "test")) { + int res; + tmp = PyObject_GetAttrString(obj, "test"); + if (tmp == NULL) goto failed; + res = obj2ast_expr(tmp, &test, arena); + if (res != 0) goto failed; + Py_DECREF(tmp); + tmp = NULL; + } + else { + PyErr_SetString(PyExc_SystemError, "required field \"test\" missing from While"); + return 1; + } + 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; + len = PyList_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_GetItem(tmp, i), &value, arena); + if (res != 0) goto failed; + asdl_seq_SET(body, i, value); + } + Py_DECREF(tmp); + tmp = NULL; + } + else { + PyErr_SetString(PyExc_SystemError, "required field \"body\" missing from While"); + return 1; + } + if (PyObject_HasAttrString(obj, "orelse")) { + int res; + Py_ssize_t len; + Py_ssize_t i; + tmp = PyObject_GetAttrString(obj, "orelse"); + if (tmp == NULL) goto failed; + len = PyList_Size(tmp); + orelse = asdl_seq_new(len, arena); + if (orelse == NULL) goto failed; + for (i = 0; i < len; i++) { + stmt_ty value; + res = obj2ast_stmt(PyList_GetItem(tmp, i), &value, arena); + if (res != 0) goto failed; + asdl_seq_SET(orelse, i, value); + } + Py_DECREF(tmp); + tmp = NULL; + } + else { + PyErr_SetString(PyExc_SystemError, "required field \"orelse\" missing from While"); + return 1; + } + *out = While(test, body, orelse, lineno, col_offset, arena); + if (*out == NULL) goto failed; + return 0; + } + if (PyObject_IsInstance(obj, (PyObject*)If_type)) { + expr_ty test; + asdl_seq* body; + asdl_seq* orelse; + + if (PyObject_HasAttrString(obj, "test")) { + int res; + tmp = PyObject_GetAttrString(obj, "test"); + if (tmp == NULL) goto failed; + res = obj2ast_expr(tmp, &test, arena); + if (res != 0) goto failed; + Py_DECREF(tmp); + tmp = NULL; + } + else { + PyErr_SetString(PyExc_SystemError, "required field \"test\" missing from If"); + return 1; + } + 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; + len = PyList_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_GetItem(tmp, i), &value, arena); + if (res != 0) goto failed; + asdl_seq_SET(body, i, value); + } + Py_DECREF(tmp); + tmp = NULL; + } + else { + PyErr_SetString(PyExc_SystemError, "required field \"body\" missing from If"); + return 1; + } + if (PyObject_HasAttrString(obj, "orelse")) { + int res; + Py_ssize_t len; + Py_ssize_t i; + tmp = PyObject_GetAttrString(obj, "orelse"); + if (tmp == NULL) goto failed; + len = PyList_Size(tmp); + orelse = asdl_seq_new(len, arena); + if (orelse == NULL) goto failed; + for (i = 0; i < len; i++) { + stmt_ty value; + res = obj2ast_stmt(PyList_GetItem(tmp, i), &value, arena); + if (res != 0) goto failed; + asdl_seq_SET(orelse, i, value); + } + Py_DECREF(tmp); + tmp = NULL; + } + else { + PyErr_SetString(PyExc_SystemError, "required field \"orelse\" missing from If"); + return 1; + } + *out = If(test, body, orelse, lineno, col_offset, arena); + if (*out == NULL) goto failed; + return 0; + } + if (PyObject_IsInstance(obj, (PyObject*)With_type)) { + expr_ty context_expr; + expr_ty optional_vars; + asdl_seq* body; + + if (PyObject_HasAttrString(obj, "context_expr")) { + int res; + tmp = PyObject_GetAttrString(obj, "context_expr"); + if (tmp == NULL) goto failed; + res = obj2ast_expr(tmp, &context_expr, arena); + if (res != 0) goto failed; + Py_DECREF(tmp); + tmp = NULL; + } + else { + PyErr_SetString(PyExc_SystemError, "required field \"context_expr\" missing from With"); + return 1; + } + if (PyObject_HasAttrString(obj, "optional_vars")) { + int res; + tmp = PyObject_GetAttrString(obj, "optional_vars"); + if (tmp == NULL) goto failed; + res = obj2ast_expr(tmp, &optional_vars, arena); + if (res != 0) goto failed; + Py_DECREF(tmp); + tmp = NULL; + } + else { + optional_vars = NULL; + } + 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; + len = PyList_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_GetItem(tmp, i), &value, arena); + if (res != 0) goto failed; + asdl_seq_SET(body, i, value); + } + Py_DECREF(tmp); + tmp = NULL; + } + else { + PyErr_SetString(PyExc_SystemError, "required field \"body\" missing from With"); + return 1; + } + *out = With(context_expr, optional_vars, body, lineno, + col_offset, arena); + if (*out == NULL) goto failed; + return 0; + } + if (PyObject_IsInstance(obj, (PyObject*)Raise_type)) { + expr_ty type; + expr_ty inst; + expr_ty tback; + + if (PyObject_HasAttrString(obj, "type")) { + int res; + tmp = PyObject_GetAttrString(obj, "type"); + if (tmp == NULL) goto failed; + res = obj2ast_expr(tmp, &type, arena); + if (res != 0) goto failed; + Py_DECREF(tmp); + tmp = NULL; + } + else { + type = NULL; + } + if (PyObject_HasAttrString(obj, "inst")) { + int res; + tmp = PyObject_GetAttrString(obj, "inst"); + if (tmp == NULL) goto failed; + res = obj2ast_expr(tmp, &inst, arena); + if (res != 0) goto failed; + Py_DECREF(tmp); + tmp = NULL; + } + else { + inst = NULL; + } + if (PyObject_HasAttrString(obj, "tback")) { + int res; + tmp = PyObject_GetAttrString(obj, "tback"); + if (tmp == NULL) goto failed; + res = obj2ast_expr(tmp, &tback, arena); + if (res != 0) goto failed; + Py_DECREF(tmp); + tmp = NULL; + } + else { + tback = NULL; + } + *out = Raise(type, inst, tback, lineno, col_offset, arena); + if (*out == NULL) goto failed; + return 0; + } + if (PyObject_IsInstance(obj, (PyObject*)TryExcept_type)) { + asdl_seq* body; + asdl_seq* handlers; + asdl_seq* orelse; + + 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; + len = PyList_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_GetItem(tmp, i), &value, arena); + if (res != 0) goto failed; + asdl_seq_SET(body, i, value); + } + Py_DECREF(tmp); + tmp = NULL; + } + else { + PyErr_SetString(PyExc_SystemError, "required field \"body\" missing from TryExcept"); + return 1; + } + if (PyObject_HasAttrString(obj, "handlers")) { + int res; + Py_ssize_t len; + Py_ssize_t i; + tmp = PyObject_GetAttrString(obj, "handlers"); + if (tmp == NULL) goto failed; + len = PyList_Size(tmp); + handlers = asdl_seq_new(len, arena); + if (handlers == NULL) goto failed; + for (i = 0; i < len; i++) { + excepthandler_ty value; + res = obj2ast_excepthandler(PyList_GetItem(tmp, i), &value, arena); + if (res != 0) goto failed; + asdl_seq_SET(handlers, i, value); + } + Py_DECREF(tmp); + tmp = NULL; + } + else { + PyErr_SetString(PyExc_SystemError, "required field \"handlers\" missing from TryExcept"); + return 1; + } + if (PyObject_HasAttrString(obj, "orelse")) { + int res; + Py_ssize_t len; + Py_ssize_t i; + tmp = PyObject_GetAttrString(obj, "orelse"); + if (tmp == NULL) goto failed; + len = PyList_Size(tmp); + orelse = asdl_seq_new(len, arena); + if (orelse == NULL) goto failed; + for (i = 0; i < len; i++) { + stmt_ty value; + res = obj2ast_stmt(PyList_GetItem(tmp, i), &value, arena); + if (res != 0) goto failed; + asdl_seq_SET(orelse, i, value); + } + Py_DECREF(tmp); + tmp = NULL; + } + else { + PyErr_SetString(PyExc_SystemError, "required field \"orelse\" missing from TryExcept"); + return 1; + } + *out = TryExcept(body, handlers, orelse, lineno, col_offset, + arena); + if (*out == NULL) goto failed; + return 0; + } + if (PyObject_IsInstance(obj, (PyObject*)TryFinally_type)) { + 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; + len = PyList_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_GetItem(tmp, i), &value, arena); + if (res != 0) goto failed; + asdl_seq_SET(body, i, value); + } + Py_DECREF(tmp); + tmp = NULL; + } + else { + PyErr_SetString(PyExc_SystemError, "required field \"body\" missing from TryFinally"); + return 1; + } + if (PyObject_HasAttrString(obj, "finalbody")) { + int res; + Py_ssize_t len; + Py_ssize_t i; + tmp = PyObject_GetAttrString(obj, "finalbody"); + if (tmp == NULL) goto failed; + len = PyList_Size(tmp); + finalbody = asdl_seq_new(len, arena); + if (finalbody == NULL) goto failed; + for (i = 0; i < len; i++) { + stmt_ty value; + res = obj2ast_stmt(PyList_GetItem(tmp, i), &value, arena); + if (res != 0) goto failed; + asdl_seq_SET(finalbody, i, value); + } + Py_DECREF(tmp); + tmp = NULL; + } + else { + PyErr_SetString(PyExc_SystemError, "required field \"finalbody\" missing from TryFinally"); + return 1; + } + *out = TryFinally(body, finalbody, lineno, col_offset, arena); + if (*out == NULL) goto failed; + return 0; + } + if (PyObject_IsInstance(obj, (PyObject*)Assert_type)) { + expr_ty test; + expr_ty msg; + + if (PyObject_HasAttrString(obj, "test")) { + int res; + tmp = PyObject_GetAttrString(obj, "test"); + if (tmp == NULL) goto failed; + res = obj2ast_expr(tmp, &test, arena); + if (res != 0) goto failed; + Py_DECREF(tmp); + tmp = NULL; + } + else { + PyErr_SetString(PyExc_SystemError, "required field \"test\" missing from Assert"); + return 1; + } + if (PyObject_HasAttrString(obj, "msg")) { + int res; + tmp = PyObject_GetAttrString(obj, "msg"); + if (tmp == NULL) goto failed; + res = obj2ast_expr(tmp, &msg, arena); + if (res != 0) goto failed; + Py_DECREF(tmp); + tmp = NULL; + } + else { + msg = NULL; + } + *out = Assert(test, msg, lineno, col_offset, arena); + if (*out == NULL) goto failed; + return 0; + } + if (PyObject_IsInstance(obj, (PyObject*)Import_type)) { + asdl_seq* names; + + if (PyObject_HasAttrString(obj, "names")) { + int res; + Py_ssize_t len; + Py_ssize_t i; + tmp = PyObject_GetAttrString(obj, "names"); + if (tmp == NULL) goto failed; + len = PyList_Size(tmp); + names = asdl_seq_new(len, arena); + if (names == NULL) goto failed; + for (i = 0; i < len; i++) { + alias_ty value; + res = obj2ast_alias(PyList_GetItem(tmp, i), &value, arena); + if (res != 0) goto failed; + asdl_seq_SET(names, i, value); + } + Py_DECREF(tmp); + tmp = NULL; + } + else { + PyErr_SetString(PyExc_SystemError, "required field \"names\" missing from Import"); + return 1; + } + *out = Import(names, lineno, col_offset, arena); + if (*out == NULL) goto failed; + return 0; + } + if (PyObject_IsInstance(obj, (PyObject*)ImportFrom_type)) { + identifier module; + asdl_seq* names; + int level; + + if (PyObject_HasAttrString(obj, "module")) { + int res; + tmp = PyObject_GetAttrString(obj, "module"); + if (tmp == NULL) goto failed; + res = obj2ast_identifier(tmp, &module, arena); + if (res != 0) goto failed; + Py_DECREF(tmp); + tmp = NULL; + } + else { + PyErr_SetString(PyExc_SystemError, "required field \"module\" missing from ImportFrom"); + return 1; + } + if (PyObject_HasAttrString(obj, "names")) { + int res; + Py_ssize_t len; + Py_ssize_t i; + tmp = PyObject_GetAttrString(obj, "names"); + if (tmp == NULL) goto failed; + len = PyList_Size(tmp); + names = asdl_seq_new(len, arena); + if (names == NULL) goto failed; + for (i = 0; i < len; i++) { + alias_ty value; + res = obj2ast_alias(PyList_GetItem(tmp, i), &value, arena); + if (res != 0) goto failed; + asdl_seq_SET(names, i, value); + } + Py_DECREF(tmp); + tmp = NULL; + } + else { + PyErr_SetString(PyExc_SystemError, "required field \"names\" missing from ImportFrom"); + return 1; + } + if (PyObject_HasAttrString(obj, "level")) { + int res; + tmp = PyObject_GetAttrString(obj, "level"); + if (tmp == NULL) goto failed; + res = obj2ast_int(tmp, &level, arena); + if (res != 0) goto failed; + Py_DECREF(tmp); + tmp = NULL; + } + else { + level = 0; + } + *out = ImportFrom(module, names, level, lineno, col_offset, + arena); + if (*out == NULL) goto failed; + return 0; + } + if (PyObject_IsInstance(obj, (PyObject*)Exec_type)) { + expr_ty body; + expr_ty globals; + expr_ty locals; + + if (PyObject_HasAttrString(obj, "body")) { + int res; + tmp = PyObject_GetAttrString(obj, "body"); + if (tmp == NULL) goto failed; + res = obj2ast_expr(tmp, &body, arena); + if (res != 0) goto failed; + Py_DECREF(tmp); + tmp = NULL; + } + else { + PyErr_SetString(PyExc_SystemError, "required field \"body\" missing from Exec"); + return 1; + } + if (PyObject_HasAttrString(obj, "globals")) { + int res; + tmp = PyObject_GetAttrString(obj, "globals"); + if (tmp == NULL) goto failed; + res = obj2ast_expr(tmp, &globals, arena); + if (res != 0) goto failed; + Py_DECREF(tmp); + tmp = NULL; + } + else { + globals = NULL; + } + if (PyObject_HasAttrString(obj, "locals")) { + int res; + tmp = PyObject_GetAttrString(obj, "locals"); + if (tmp == NULL) goto failed; + res = obj2ast_expr(tmp, &locals, arena); + if (res != 0) goto failed; + Py_DECREF(tmp); + tmp = NULL; + } + else { + locals = NULL; + } + *out = Exec(body, globals, locals, lineno, col_offset, arena); + if (*out == NULL) goto failed; + return 0; + } + if (PyObject_IsInstance(obj, (PyObject*)Global_type)) { + asdl_seq* names; + + if (PyObject_HasAttrString(obj, "names")) { + int res; + Py_ssize_t len; + Py_ssize_t i; + tmp = PyObject_GetAttrString(obj, "names"); + if (tmp == NULL) goto failed; + len = PyList_Size(tmp); + names = asdl_seq_new(len, arena); + if (names == NULL) goto failed; + for (i = 0; i < len; i++) { + identifier value; + res = obj2ast_identifier(PyList_GetItem(tmp, i), &value, arena); + if (res != 0) goto failed; + asdl_seq_SET(names, i, value); + } + Py_DECREF(tmp); + tmp = NULL; + } + else { + PyErr_SetString(PyExc_SystemError, "required field \"names\" missing from Global"); + return 1; + } + *out = Global(names, lineno, col_offset, arena); + if (*out == NULL) goto failed; + return 0; + } + if (PyObject_IsInstance(obj, (PyObject*)Expr_type)) { + expr_ty value; + + if (PyObject_HasAttrString(obj, "value")) { + int res; + tmp = PyObject_GetAttrString(obj, "value"); + if (tmp == NULL) goto failed; + res = obj2ast_expr(tmp, &value, arena); + if (res != 0) goto failed; + Py_DECREF(tmp); + tmp = NULL; + } + else { + PyErr_SetString(PyExc_SystemError, "required field \"value\" missing from Expr"); + return 1; + } + *out = Expr(value, lineno, col_offset, arena); + if (*out == NULL) goto failed; + return 0; + } + if (PyObject_IsInstance(obj, (PyObject*)Pass_type)) { + + *out = Pass(lineno, col_offset, arena); + if (*out == NULL) goto failed; + return 0; + } + if (PyObject_IsInstance(obj, (PyObject*)Break_type)) { + + *out = Break(lineno, col_offset, arena); + if (*out == NULL) goto failed; + return 0; + } + if (PyObject_IsInstance(obj, (PyObject*)Continue_type)) { + + *out = Continue(lineno, col_offset, arena); + if (*out == NULL) goto failed; + return 0; + } + + tmp = PyObject_Str(obj); + if (tmp == NULL) goto failed; + PyErr_Format(PyExc_TypeError, "expected some sort of stmt, but got %s", PyString_AsString(tmp)); +failed: + Py_XDECREF(tmp); + return 1; +} + +int +obj2ast_expr(PyObject* obj, expr_ty* out, PyArena* arena) +{ + PyObject* tmp = NULL; + int lineno; + int col_offset; + + if (obj == Py_None) { + *out = NULL; + return 0; + } + if (PyObject_HasAttrString(obj, "lineno")) { + int res; + tmp = PyObject_GetAttrString(obj, "lineno"); + if (tmp == NULL) goto failed; + res = obj2ast_int(tmp, &lineno, arena); + if (res != 0) goto failed; + Py_DECREF(tmp); + tmp = NULL; + } + else { + PyErr_SetString(PyExc_SystemError, "required field \"lineno\" missing from expr"); + return 1; + } + if (PyObject_HasAttrString(obj, "col_offset")) { + int res; + tmp = PyObject_GetAttrString(obj, "col_offset"); + if (tmp == NULL) goto failed; + res = obj2ast_int(tmp, &col_offset, arena); + if (res != 0) goto failed; + Py_DECREF(tmp); + tmp = NULL; + } + else { + PyErr_SetString(PyExc_SystemError, "required field \"col_offset\" missing from expr"); + return 1; + } + if (PyObject_IsInstance(obj, (PyObject*)BoolOp_type)) { + boolop_ty op; + asdl_seq* values; + + if (PyObject_HasAttrString(obj, "op")) { + int res; + tmp = PyObject_GetAttrString(obj, "op"); + if (tmp == NULL) goto failed; + res = obj2ast_boolop(tmp, &op, arena); + if (res != 0) goto failed; + Py_DECREF(tmp); + tmp = NULL; + } + else { + PyErr_SetString(PyExc_SystemError, "required field \"op\" missing from BoolOp"); + return 1; + } + if (PyObject_HasAttrString(obj, "values")) { + int res; + Py_ssize_t len; + Py_ssize_t i; + tmp = PyObject_GetAttrString(obj, "values"); + if (tmp == NULL) goto failed; + len = PyList_Size(tmp); + values = asdl_seq_new(len, arena); + if (values == NULL) goto failed; + for (i = 0; i < len; i++) { + expr_ty value; + res = obj2ast_expr(PyList_GetItem(tmp, i), &value, arena); + if (res != 0) goto failed; + asdl_seq_SET(values, i, value); + } + Py_DECREF(tmp); + tmp = NULL; + } + else { + PyErr_SetString(PyExc_SystemError, "required field \"values\" missing from BoolOp"); + return 1; + } + *out = BoolOp(op, values, lineno, col_offset, arena); + if (*out == NULL) goto failed; + return 0; + } + if (PyObject_IsInstance(obj, (PyObject*)BinOp_type)) { + expr_ty left; + operator_ty op; + expr_ty right; + + if (PyObject_HasAttrString(obj, "left")) { + int res; + tmp = PyObject_GetAttrString(obj, "left"); + if (tmp == NULL) goto failed; + res = obj2ast_expr(tmp, &left, arena); + if (res != 0) goto failed; + Py_DECREF(tmp); + tmp = NULL; + } + else { + PyErr_SetString(PyExc_SystemError, "required field \"left\" missing from BinOp"); + return 1; + } + if (PyObject_HasAttrString(obj, "op")) { + int res; + tmp = PyObject_GetAttrString(obj, "op"); + if (tmp == NULL) goto failed; + res = obj2ast_operator(tmp, &op, arena); + if (res != 0) goto failed; + Py_DECREF(tmp); + tmp = NULL; + } + else { + PyErr_SetString(PyExc_SystemError, "required field \"op\" missing from BinOp"); + return 1; + } + if (PyObject_HasAttrString(obj, "right")) { + int res; + tmp = PyObject_GetAttrString(obj, "right"); + if (tmp == NULL) goto failed; + res = obj2ast_expr(tmp, &right, arena); + if (res != 0) goto failed; + Py_DECREF(tmp); + tmp = NULL; + } + else { + PyErr_SetString(PyExc_SystemError, "required field \"right\" missing from BinOp"); + return 1; + } + *out = BinOp(left, op, right, lineno, col_offset, arena); + if (*out == NULL) goto failed; + return 0; + } + if (PyObject_IsInstance(obj, (PyObject*)UnaryOp_type)) { + unaryop_ty op; + expr_ty operand; + + if (PyObject_HasAttrString(obj, "op")) { + int res; + tmp = PyObject_GetAttrString(obj, "op"); + if (tmp == NULL) goto failed; + res = obj2ast_unaryop(tmp, &op, arena); + if (res != 0) goto failed; + Py_DECREF(tmp); + tmp = NULL; + } + else { + PyErr_SetString(PyExc_SystemError, "required field \"op\" missing from UnaryOp"); + return 1; + } + if (PyObject_HasAttrString(obj, "operand")) { + int res; + tmp = PyObject_GetAttrString(obj, "operand"); + if (tmp == NULL) goto failed; + res = obj2ast_expr(tmp, &operand, arena); + if (res != 0) goto failed; + Py_DECREF(tmp); + tmp = NULL; + } + else { + PyErr_SetString(PyExc_SystemError, "required field \"operand\" missing from UnaryOp"); + return 1; + } + *out = UnaryOp(op, operand, lineno, col_offset, arena); + if (*out == NULL) goto failed; + return 0; + } + if (PyObject_IsInstance(obj, (PyObject*)Lambda_type)) { + arguments_ty args; + expr_ty body; + + if (PyObject_HasAttrString(obj, "args")) { + int res; + tmp = PyObject_GetAttrString(obj, "args"); + if (tmp == NULL) goto failed; + res = obj2ast_arguments(tmp, &args, arena); + if (res != 0) goto failed; + Py_DECREF(tmp); + tmp = NULL; + } + else { + PyErr_SetString(PyExc_SystemError, "required field \"args\" missing from Lambda"); + return 1; + } + if (PyObject_HasAttrString(obj, "body")) { + int res; + tmp = PyObject_GetAttrString(obj, "body"); + if (tmp == NULL) goto failed; + res = obj2ast_expr(tmp, &body, arena); + if (res != 0) goto failed; + Py_DECREF(tmp); + tmp = NULL; + } + else { + PyErr_SetString(PyExc_SystemError, "required field \"body\" missing from Lambda"); + return 1; + } + *out = Lambda(args, body, lineno, col_offset, arena); + if (*out == NULL) goto failed; + return 0; + } + if (PyObject_IsInstance(obj, (PyObject*)IfExp_type)) { + expr_ty test; + expr_ty body; + expr_ty orelse; + + if (PyObject_HasAttrString(obj, "test")) { + int res; + tmp = PyObject_GetAttrString(obj, "test"); + if (tmp == NULL) goto failed; + res = obj2ast_expr(tmp, &test, arena); + if (res != 0) goto failed; + Py_DECREF(tmp); + tmp = NULL; + } + else { + PyErr_SetString(PyExc_SystemError, "required field \"test\" missing from IfExp"); + return 1; + } + if (PyObject_HasAttrString(obj, "body")) { + int res; + tmp = PyObject_GetAttrString(obj, "body"); + if (tmp == NULL) goto failed; + res = obj2ast_expr(tmp, &body, arena); + if (res != 0) goto failed; + Py_DECREF(tmp); + tmp = NULL; + } + else { + PyErr_SetString(PyExc_SystemError, "required field \"body\" missing from IfExp"); + return 1; + } + if (PyObject_HasAttrString(obj, "orelse")) { + int res; + tmp = PyObject_GetAttrString(obj, "orelse"); + if (tmp == NULL) goto failed; + res = obj2ast_expr(tmp, &orelse, arena); + if (res != 0) goto failed; + Py_DECREF(tmp); + tmp = NULL; + } + else { + PyErr_SetString(PyExc_SystemError, "required field \"orelse\" missing from IfExp"); + return 1; + } + *out = IfExp(test, body, orelse, lineno, col_offset, arena); + if (*out == NULL) goto failed; + return 0; + } + if (PyObject_IsInstance(obj, (PyObject*)Dict_type)) { + asdl_seq* keys; + asdl_seq* values; + + if (PyObject_HasAttrString(obj, "keys")) { + int res; + Py_ssize_t len; + Py_ssize_t i; + tmp = PyObject_GetAttrString(obj, "keys"); + if (tmp == NULL) goto failed; + len = PyList_Size(tmp); + keys = asdl_seq_new(len, arena); + if (keys == NULL) goto failed; + for (i = 0; i < len; i++) { + expr_ty value; + res = obj2ast_expr(PyList_GetItem(tmp, i), &value, arena); + if (res != 0) goto failed; + asdl_seq_SET(keys, i, value); + } + Py_DECREF(tmp); + tmp = NULL; + } + else { + PyErr_SetString(PyExc_SystemError, "required field \"keys\" missing from Dict"); + return 1; + } + if (PyObject_HasAttrString(obj, "values")) { + int res; + Py_ssize_t len; + Py_ssize_t i; + tmp = PyObject_GetAttrString(obj, "values"); + if (tmp == NULL) goto failed; + len = PyList_Size(tmp); + values = asdl_seq_new(len, arena); + if (values == NULL) goto failed; + for (i = 0; i < len; i++) { + expr_ty value; + res = obj2ast_expr(PyList_GetItem(tmp, i), &value, arena); + if (res != 0) goto failed; + asdl_seq_SET(values, i, value); + } + Py_DECREF(tmp); + tmp = NULL; + } + else { + PyErr_SetString(PyExc_SystemError, "required field \"values\" missing from Dict"); + return 1; + } + *out = Dict(keys, values, lineno, col_offset, arena); + if (*out == NULL) goto failed; + return 0; + } + if (PyObject_IsInstance(obj, (PyObject*)ListComp_type)) { + expr_ty elt; + asdl_seq* generators; + + if (PyObject_HasAttrString(obj, "elt")) { + int res; + tmp = PyObject_GetAttrString(obj, "elt"); + if (tmp == NULL) goto failed; + res = obj2ast_expr(tmp, &elt, arena); + if (res != 0) goto failed; + Py_DECREF(tmp); + tmp = NULL; + } + else { + PyErr_SetString(PyExc_SystemError, "required field \"elt\" missing from ListComp"); + return 1; + } + if (PyObject_HasAttrString(obj, "generators")) { + int res; + Py_ssize_t len; + Py_ssize_t i; + tmp = PyObject_GetAttrString(obj, "generators"); + if (tmp == NULL) goto failed; + len = PyList_Size(tmp); + generators = asdl_seq_new(len, arena); + if (generators == NULL) goto failed; + for (i = 0; i < len; i++) { + comprehension_ty value; + res = obj2ast_comprehension(PyList_GetItem(tmp, i), &value, arena); + if (res != 0) goto failed; + asdl_seq_SET(generators, i, value); + } + Py_DECREF(tmp); + tmp = NULL; + } + else { + PyErr_SetString(PyExc_SystemError, "required field \"generators\" missing from ListComp"); + return 1; + } + *out = ListComp(elt, generators, lineno, col_offset, arena); + if (*out == NULL) goto failed; + return 0; + } + if (PyObject_IsInstance(obj, (PyObject*)GeneratorExp_type)) { + expr_ty elt; + asdl_seq* generators; + + if (PyObject_HasAttrString(obj, "elt")) { + int res; + tmp = PyObject_GetAttrString(obj, "elt"); + if (tmp == NULL) goto failed; + res = obj2ast_expr(tmp, &elt, arena); + if (res != 0) goto failed; + Py_DECREF(tmp); + tmp = NULL; + } + else { + PyErr_SetString(PyExc_SystemError, "required field \"elt\" missing from GeneratorExp"); + return 1; + } + if (PyObject_HasAttrString(obj, "generators")) { + int res; + Py_ssize_t len; + Py_ssize_t i; + tmp = PyObject_GetAttrString(obj, "generators"); + if (tmp == NULL) goto failed; + len = PyList_Size(tmp); + generators = asdl_seq_new(len, arena); + if (generators == NULL) goto failed; + for (i = 0; i < len; i++) { + comprehension_ty value; + res = obj2ast_comprehension(PyList_GetItem(tmp, i), &value, arena); + if (res != 0) goto failed; + asdl_seq_SET(generators, i, value); + } + Py_DECREF(tmp); + tmp = NULL; + } + else { + PyErr_SetString(PyExc_SystemError, "required field \"generators\" missing from GeneratorExp"); + return 1; + } + *out = GeneratorExp(elt, generators, lineno, col_offset, arena); + if (*out == NULL) goto failed; + return 0; + } + if (PyObject_IsInstance(obj, (PyObject*)Yield_type)) { + expr_ty value; + + if (PyObject_HasAttrString(obj, "value")) { + int res; + tmp = PyObject_GetAttrString(obj, "value"); + if (tmp == NULL) goto failed; + res = obj2ast_expr(tmp, &value, arena); + if (res != 0) goto failed; + Py_DECREF(tmp); + tmp = NULL; + } + else { + value = NULL; + } + *out = Yield(value, lineno, col_offset, arena); + if (*out == NULL) goto failed; + return 0; + } + if (PyObject_IsInstance(obj, (PyObject*)Compare_type)) { + expr_ty left; + asdl_int_seq* ops; + asdl_seq* comparators; + + if (PyObject_HasAttrString(obj, "left")) { + int res; + tmp = PyObject_GetAttrString(obj, "left"); + if (tmp == NULL) goto failed; + res = obj2ast_expr(tmp, &left, arena); + if (res != 0) goto failed; + Py_DECREF(tmp); + tmp = NULL; + } + else { + PyErr_SetString(PyExc_SystemError, "required field \"left\" missing from Compare"); + return 1; + } + if (PyObject_HasAttrString(obj, "ops")) { + int res; + Py_ssize_t len; + Py_ssize_t i; + tmp = PyObject_GetAttrString(obj, "ops"); + if (tmp == NULL) goto failed; + len = PyList_Size(tmp); + ops = asdl_int_seq_new(len, arena); + if (ops == NULL) goto failed; + for (i = 0; i < len; i++) { + cmpop_ty value; + res = obj2ast_cmpop(PyList_GetItem(tmp, i), &value, arena); + if (res != 0) goto failed; + asdl_seq_SET(ops, i, value); + } + Py_DECREF(tmp); + tmp = NULL; + } + else { + PyErr_SetString(PyExc_SystemError, "required field \"ops\" missing from Compare"); + return 1; + } + if (PyObject_HasAttrString(obj, "comparators")) { + int res; + Py_ssize_t len; + Py_ssize_t i; + tmp = PyObject_GetAttrString(obj, "comparators"); + if (tmp == NULL) goto failed; + len = PyList_Size(tmp); + comparators = asdl_seq_new(len, arena); + if (comparators == NULL) goto failed; + for (i = 0; i < len; i++) { + expr_ty value; + res = obj2ast_expr(PyList_GetItem(tmp, i), &value, arena); + if (res != 0) goto failed; + asdl_seq_SET(comparators, i, value); + } + Py_DECREF(tmp); + tmp = NULL; + } + else { + PyErr_SetString(PyExc_SystemError, "required field \"comparators\" missing from Compare"); + return 1; + } + *out = Compare(left, ops, comparators, lineno, col_offset, + arena); + if (*out == NULL) goto failed; + return 0; + } + if (PyObject_IsInstance(obj, (PyObject*)Call_type)) { + expr_ty func; + asdl_seq* args; + asdl_seq* keywords; + expr_ty starargs; + expr_ty kwargs; + + if (PyObject_HasAttrString(obj, "func")) { + int res; + tmp = PyObject_GetAttrString(obj, "func"); + if (tmp == NULL) goto failed; + res = obj2ast_expr(tmp, &func, arena); + if (res != 0) goto failed; + Py_DECREF(tmp); + tmp = NULL; + } + else { + PyErr_SetString(PyExc_SystemError, "required field \"func\" missing from Call"); + return 1; + } + if (PyObject_HasAttrString(obj, "args")) { + int res; + Py_ssize_t len; + Py_ssize_t i; + tmp = PyObject_GetAttrString(obj, "args"); + if (tmp == NULL) goto failed; + len = PyList_Size(tmp); + args = asdl_seq_new(len, arena); + if (args == NULL) goto failed; + for (i = 0; i < len; i++) { + expr_ty value; + res = obj2ast_expr(PyList_GetItem(tmp, i), &value, arena); + if (res != 0) goto failed; + asdl_seq_SET(args, i, value); + } + Py_DECREF(tmp); + tmp = NULL; + } + else { + PyErr_SetString(PyExc_SystemError, "required field \"args\" missing from Call"); + return 1; + } + if (PyObject_HasAttrString(obj, "keywords")) { + int res; + Py_ssize_t len; + Py_ssize_t i; + tmp = PyObject_GetAttrString(obj, "keywords"); + if (tmp == NULL) goto failed; + len = PyList_Size(tmp); + keywords = asdl_seq_new(len, arena); + if (keywords == NULL) goto failed; + for (i = 0; i < len; i++) { + keyword_ty value; + res = obj2ast_keyword(PyList_GetItem(tmp, i), &value, arena); + if (res != 0) goto failed; + asdl_seq_SET(keywords, i, value); + } + Py_DECREF(tmp); + tmp = NULL; + } + else { + PyErr_SetString(PyExc_SystemError, "required field \"keywords\" missing from Call"); + return 1; + } + if (PyObject_HasAttrString(obj, "starargs")) { + int res; + tmp = PyObject_GetAttrString(obj, "starargs"); + if (tmp == NULL) goto failed; + res = obj2ast_expr(tmp, &starargs, arena); + if (res != 0) goto failed; + Py_DECREF(tmp); + tmp = NULL; + } + else { + starargs = NULL; + } + if (PyObject_HasAttrString(obj, "kwargs")) { + int res; + tmp = PyObject_GetAttrString(obj, "kwargs"); + if (tmp == NULL) goto failed; + res = obj2ast_expr(tmp, &kwargs, arena); + if (res != 0) goto failed; + Py_DECREF(tmp); + tmp = NULL; + } + else { + kwargs = NULL; + } + *out = Call(func, args, keywords, starargs, kwargs, lineno, + col_offset, arena); + if (*out == NULL) goto failed; + return 0; + } + if (PyObject_IsInstance(obj, (PyObject*)Repr_type)) { + expr_ty value; + + if (PyObject_HasAttrString(obj, "value")) { + int res; + tmp = PyObject_GetAttrString(obj, "value"); + if (tmp == NULL) goto failed; + res = obj2ast_expr(tmp, &value, arena); + if (res != 0) goto failed; + Py_DECREF(tmp); + tmp = NULL; + } + else { + PyErr_SetString(PyExc_SystemError, "required field \"value\" missing from Repr"); + return 1; + } + *out = Repr(value, lineno, col_offset, arena); + if (*out == NULL) goto failed; + return 0; + } + if (PyObject_IsInstance(obj, (PyObject*)Num_type)) { + object n; + + if (PyObject_HasAttrString(obj, "n")) { + int res; + tmp = PyObject_GetAttrString(obj, "n"); + if (tmp == NULL) goto failed; + res = obj2ast_object(tmp, &n, arena); + if (res != 0) goto failed; + Py_DECREF(tmp); + tmp = NULL; + } + else { + PyErr_SetString(PyExc_SystemError, "required field \"n\" missing from Num"); + return 1; + } + *out = Num(n, lineno, col_offset, arena); + if (*out == NULL) goto failed; + return 0; + } + if (PyObject_IsInstance(obj, (PyObject*)Str_type)) { + string s; + + if (PyObject_HasAttrString(obj, "s")) { + int res; + tmp = PyObject_GetAttrString(obj, "s"); + if (tmp == NULL) goto failed; + res = obj2ast_string(tmp, &s, arena); + if (res != 0) goto failed; + Py_DECREF(tmp); + tmp = NULL; + } + else { + PyErr_SetString(PyExc_SystemError, "required field \"s\" missing from Str"); + return 1; + } + *out = Str(s, lineno, col_offset, arena); + if (*out == NULL) goto failed; + return 0; + } + if (PyObject_IsInstance(obj, (PyObject*)Attribute_type)) { + expr_ty value; + identifier attr; + expr_context_ty ctx; + + if (PyObject_HasAttrString(obj, "value")) { + int res; + tmp = PyObject_GetAttrString(obj, "value"); + if (tmp == NULL) goto failed; + res = obj2ast_expr(tmp, &value, arena); + if (res != 0) goto failed; + Py_DECREF(tmp); + tmp = NULL; + } + else { + PyErr_SetString(PyExc_SystemError, "required field \"value\" missing from Attribute"); + return 1; + } + if (PyObject_HasAttrString(obj, "attr")) { + int res; + tmp = PyObject_GetAttrString(obj, "attr"); + if (tmp == NULL) goto failed; + res = obj2ast_identifier(tmp, &attr, arena); + if (res != 0) goto failed; + Py_DECREF(tmp); + tmp = NULL; + } + else { + PyErr_SetString(PyExc_SystemError, "required field \"attr\" missing from Attribute"); + return 1; + } + if (PyObject_HasAttrString(obj, "ctx")) { + int res; + tmp = PyObject_GetAttrString(obj, "ctx"); + if (tmp == NULL) goto failed; + res = obj2ast_expr_context(tmp, &ctx, arena); + if (res != 0) goto failed; + Py_DECREF(tmp); + tmp = NULL; + } + else { + PyErr_SetString(PyExc_SystemError, "required field \"ctx\" missing from Attribute"); + return 1; + } + *out = Attribute(value, attr, ctx, lineno, col_offset, arena); + if (*out == NULL) goto failed; + return 0; + } + if (PyObject_IsInstance(obj, (PyObject*)Subscript_type)) { + expr_ty value; + slice_ty slice; + expr_context_ty ctx; + + if (PyObject_HasAttrString(obj, "value")) { + int res; + tmp = PyObject_GetAttrString(obj, "value"); + if (tmp == NULL) goto failed; + res = obj2ast_expr(tmp, &value, arena); + if (res != 0) goto failed; + Py_DECREF(tmp); + tmp = NULL; + } + else { + PyErr_SetString(PyExc_SystemError, "required field \"value\" missing from Subscript"); + return 1; + } + if (PyObject_HasAttrString(obj, "slice")) { + int res; + tmp = PyObject_GetAttrString(obj, "slice"); + if (tmp == NULL) goto failed; + res = obj2ast_slice(tmp, &slice, arena); + if (res != 0) goto failed; + Py_DECREF(tmp); + tmp = NULL; + } + else { + PyErr_SetString(PyExc_SystemError, "required field \"slice\" missing from Subscript"); + return 1; + } + if (PyObject_HasAttrString(obj, "ctx")) { + int res; + tmp = PyObject_GetAttrString(obj, "ctx"); + if (tmp == NULL) goto failed; + res = obj2ast_expr_context(tmp, &ctx, arena); + if (res != 0) goto failed; + Py_DECREF(tmp); + tmp = NULL; + } + else { + PyErr_SetString(PyExc_SystemError, "required field \"ctx\" missing from Subscript"); + return 1; + } + *out = Subscript(value, slice, ctx, lineno, col_offset, arena); + if (*out == NULL) goto failed; + return 0; + } + if (PyObject_IsInstance(obj, (PyObject*)Name_type)) { + identifier id; + expr_context_ty ctx; + + if (PyObject_HasAttrString(obj, "id")) { + int res; + tmp = PyObject_GetAttrString(obj, "id"); + if (tmp == NULL) goto failed; + res = obj2ast_identifier(tmp, &id, arena); + if (res != 0) goto failed; + Py_DECREF(tmp); + tmp = NULL; + } + else { + PyErr_SetString(PyExc_SystemError, "required field \"id\" missing from Name"); + return 1; + } + if (PyObject_HasAttrString(obj, "ctx")) { + int res; + tmp = PyObject_GetAttrString(obj, "ctx"); + if (tmp == NULL) goto failed; + res = obj2ast_expr_context(tmp, &ctx, arena); + if (res != 0) goto failed; + Py_DECREF(tmp); + tmp = NULL; + } + else { + PyErr_SetString(PyExc_SystemError, "required field \"ctx\" missing from Name"); + return 1; + } + *out = Name(id, ctx, lineno, col_offset, arena); + if (*out == NULL) goto failed; + return 0; + } + if (PyObject_IsInstance(obj, (PyObject*)List_type)) { + asdl_seq* elts; + expr_context_ty ctx; + + if (PyObject_HasAttrString(obj, "elts")) { + int res; + Py_ssize_t len; + Py_ssize_t i; + tmp = PyObject_GetAttrString(obj, "elts"); + if (tmp == NULL) goto failed; + len = PyList_Size(tmp); + elts = asdl_seq_new(len, arena); + if (elts == NULL) goto failed; + for (i = 0; i < len; i++) { + expr_ty value; + res = obj2ast_expr(PyList_GetItem(tmp, i), &value, arena); + if (res != 0) goto failed; + asdl_seq_SET(elts, i, value); + } + Py_DECREF(tmp); + tmp = NULL; + } + else { + PyErr_SetString(PyExc_SystemError, "required field \"elts\" missing from List"); + return 1; + } + if (PyObject_HasAttrString(obj, "ctx")) { + int res; + tmp = PyObject_GetAttrString(obj, "ctx"); + if (tmp == NULL) goto failed; + res = obj2ast_expr_context(tmp, &ctx, arena); + if (res != 0) goto failed; + Py_DECREF(tmp); + tmp = NULL; + } + else { + PyErr_SetString(PyExc_SystemError, "required field \"ctx\" missing from List"); + return 1; + } + *out = List(elts, ctx, lineno, col_offset, arena); + if (*out == NULL) goto failed; + return 0; + } + if (PyObject_IsInstance(obj, (PyObject*)Tuple_type)) { + asdl_seq* elts; + expr_context_ty ctx; + + if (PyObject_HasAttrString(obj, "elts")) { + int res; + Py_ssize_t len; + Py_ssize_t i; + tmp = PyObject_GetAttrString(obj, "elts"); + if (tmp == NULL) goto failed; + len = PyList_Size(tmp); + elts = asdl_seq_new(len, arena); + if (elts == NULL) goto failed; + for (i = 0; i < len; i++) { + expr_ty value; + res = obj2ast_expr(PyList_GetItem(tmp, i), &value, arena); + if (res != 0) goto failed; + asdl_seq_SET(elts, i, value); + } + Py_DECREF(tmp); + tmp = NULL; + } + else { + PyErr_SetString(PyExc_SystemError, "required field \"elts\" missing from Tuple"); + return 1; + } + if (PyObject_HasAttrString(obj, "ctx")) { + int res; + tmp = PyObject_GetAttrString(obj, "ctx"); + if (tmp == NULL) goto failed; + res = obj2ast_expr_context(tmp, &ctx, arena); + if (res != 0) goto failed; + Py_DECREF(tmp); + tmp = NULL; + } + else { + PyErr_SetString(PyExc_SystemError, "required field \"ctx\" missing from Tuple"); + return 1; + } + *out = Tuple(elts, ctx, lineno, col_offset, arena); + if (*out == NULL) goto failed; + return 0; + } + + tmp = PyObject_Str(obj); + if (tmp == NULL) goto failed; + PyErr_Format(PyExc_TypeError, "expected some sort of expr, but got %s", PyString_AsString(tmp)); +failed: + Py_XDECREF(tmp); + return 1; +} + +int +obj2ast_expr_context(PyObject* obj, expr_context_ty* out, PyArena* arena) +{ + + if (obj == Load_singleton) { + *out = Load; + return 0; + } + if (obj == Store_singleton) { + *out = Store; + return 0; + } + if (obj == Del_singleton) { + *out = Del; + return 0; + } + if (obj == AugLoad_singleton) { + *out = AugLoad; + return 0; + } + if (obj == AugStore_singleton) { + *out = AugStore; + return 0; + } + if (obj == Param_singleton) { + *out = Param; + return 0; + } + return 1; +} + +int +obj2ast_slice(PyObject* obj, slice_ty* out, PyArena* arena) +{ + PyObject* tmp = NULL; + + if (obj == Py_None) { + *out = NULL; + return 0; + } + if (PyObject_IsInstance(obj, (PyObject*)Ellipsis_type)) { + + *out = Ellipsis(arena); + if (*out == NULL) goto failed; + return 0; + } + if (PyObject_IsInstance(obj, (PyObject*)Slice_type)) { + expr_ty lower; + expr_ty upper; + expr_ty step; + + if (PyObject_HasAttrString(obj, "lower")) { + int res; + tmp = PyObject_GetAttrString(obj, "lower"); + if (tmp == NULL) goto failed; + res = obj2ast_expr(tmp, &lower, arena); + if (res != 0) goto failed; + Py_DECREF(tmp); + tmp = NULL; + } + else { + lower = NULL; + } + if (PyObject_HasAttrString(obj, "upper")) { + int res; + tmp = PyObject_GetAttrString(obj, "upper"); + if (tmp == NULL) goto failed; + res = obj2ast_expr(tmp, &upper, arena); + if (res != 0) goto failed; + Py_DECREF(tmp); + tmp = NULL; + } + else { + upper = NULL; + } + if (PyObject_HasAttrString(obj, "step")) { + int res; + tmp = PyObject_GetAttrString(obj, "step"); + if (tmp == NULL) goto failed; + res = obj2ast_expr(tmp, &step, arena); + if (res != 0) goto failed; + Py_DECREF(tmp); + tmp = NULL; + } + else { + step = NULL; + } + *out = Slice(lower, upper, step, arena); + if (*out == NULL) goto failed; + return 0; + } + if (PyObject_IsInstance(obj, (PyObject*)ExtSlice_type)) { + asdl_seq* dims; + + if (PyObject_HasAttrString(obj, "dims")) { + int res; + Py_ssize_t len; + Py_ssize_t i; + tmp = PyObject_GetAttrString(obj, "dims"); + if (tmp == NULL) goto failed; + len = PyList_Size(tmp); + dims = asdl_seq_new(len, arena); + if (dims == NULL) goto failed; + for (i = 0; i < len; i++) { + slice_ty value; + res = obj2ast_slice(PyList_GetItem(tmp, i), &value, arena); + if (res != 0) goto failed; + asdl_seq_SET(dims, i, value); + } + Py_DECREF(tmp); + tmp = NULL; + } + else { + PyErr_SetString(PyExc_SystemError, "required field \"dims\" missing from ExtSlice"); + return 1; + } + *out = ExtSlice(dims, arena); + if (*out == NULL) goto failed; + return 0; + } + if (PyObject_IsInstance(obj, (PyObject*)Index_type)) { + expr_ty value; + + if (PyObject_HasAttrString(obj, "value")) { + int res; + tmp = PyObject_GetAttrString(obj, "value"); + if (tmp == NULL) goto failed; + res = obj2ast_expr(tmp, &value, arena); + if (res != 0) goto failed; + Py_DECREF(tmp); + tmp = NULL; + } + else { + PyErr_SetString(PyExc_SystemError, "required field \"value\" missing from Index"); + return 1; + } + *out = Index(value, arena); + if (*out == NULL) goto failed; + return 0; + } + + tmp = PyObject_Str(obj); + if (tmp == NULL) goto failed; + PyErr_Format(PyExc_TypeError, "expected some sort of slice, but got %s", PyString_AsString(tmp)); +failed: + Py_XDECREF(tmp); + return 1; +} + +int +obj2ast_boolop(PyObject* obj, boolop_ty* out, PyArena* arena) +{ + + if (obj == And_singleton) { + *out = And; + return 0; + } + if (obj == Or_singleton) { + *out = Or; + return 0; + } + return 1; +} + +int +obj2ast_operator(PyObject* obj, operator_ty* out, PyArena* arena) +{ + + if (obj == Add_singleton) { + *out = Add; + return 0; + } + if (obj == Sub_singleton) { + *out = Sub; + return 0; + } + if (obj == Mult_singleton) { + *out = Mult; + return 0; + } + if (obj == Div_singleton) { + *out = Div; + return 0; + } + if (obj == Mod_singleton) { + *out = Mod; + return 0; + } + if (obj == Pow_singleton) { + *out = Pow; + return 0; + } + if (obj == LShift_singleton) { + *out = LShift; + return 0; + } + if (obj == RShift_singleton) { + *out = RShift; + return 0; + } + if (obj == BitOr_singleton) { + *out = BitOr; + return 0; + } + if (obj == BitXor_singleton) { + *out = BitXor; + return 0; + } + if (obj == BitAnd_singleton) { + *out = BitAnd; + return 0; + } + if (obj == FloorDiv_singleton) { + *out = FloorDiv; + return 0; + } + return 1; +} + +int +obj2ast_unaryop(PyObject* obj, unaryop_ty* out, PyArena* arena) +{ + + if (obj == Invert_singleton) { + *out = Invert; + return 0; + } + if (obj == Not_singleton) { + *out = Not; + return 0; + } + if (obj == UAdd_singleton) { + *out = UAdd; + return 0; + } + if (obj == USub_singleton) { + *out = USub; + return 0; + } + return 1; +} + +int +obj2ast_cmpop(PyObject* obj, cmpop_ty* out, PyArena* arena) +{ + + if (obj == Eq_singleton) { + *out = Eq; + return 0; + } + if (obj == NotEq_singleton) { + *out = NotEq; + return 0; + } + if (obj == Lt_singleton) { + *out = Lt; + return 0; + } + if (obj == LtE_singleton) { + *out = LtE; + return 0; + } + if (obj == Gt_singleton) { + *out = Gt; + return 0; + } + if (obj == GtE_singleton) { + *out = GtE; + return 0; + } + if (obj == Is_singleton) { + *out = Is; + return 0; + } + if (obj == IsNot_singleton) { + *out = IsNot; + return 0; + } + if (obj == In_singleton) { + *out = In; + return 0; + } + if (obj == NotIn_singleton) { + *out = NotIn; + return 0; + } + return 1; +} + +int +obj2ast_comprehension(PyObject* obj, comprehension_ty* out, PyArena* arena) +{ + PyObject* tmp = NULL; + expr_ty target; + expr_ty iter; + asdl_seq* ifs; + + if (PyObject_HasAttrString(obj, "target")) { + int res; + tmp = PyObject_GetAttrString(obj, "target"); + if (tmp == NULL) goto failed; + res = obj2ast_expr(tmp, &target, arena); + if (res != 0) goto failed; + Py_DECREF(tmp); + tmp = NULL; + } + else { + PyErr_SetString(PyExc_SystemError, "required field \"target\" missing from comprehension"); + return 1; + } + if (PyObject_HasAttrString(obj, "iter")) { + int res; + tmp = PyObject_GetAttrString(obj, "iter"); + if (tmp == NULL) goto failed; + res = obj2ast_expr(tmp, &iter, arena); + if (res != 0) goto failed; + Py_DECREF(tmp); + tmp = NULL; + } + else { + PyErr_SetString(PyExc_SystemError, "required field \"iter\" missing from comprehension"); + return 1; + } + if (PyObject_HasAttrString(obj, "ifs")) { + int res; + Py_ssize_t len; + Py_ssize_t i; + tmp = PyObject_GetAttrString(obj, "ifs"); + if (tmp == NULL) goto failed; + len = PyList_Size(tmp); + ifs = asdl_seq_new(len, arena); + if (ifs == NULL) goto failed; + for (i = 0; i < len; i++) { + expr_ty value; + res = obj2ast_expr(PyList_GetItem(tmp, i), &value, arena); + if (res != 0) goto failed; + asdl_seq_SET(ifs, i, value); + } + Py_DECREF(tmp); + tmp = NULL; + } + else { + PyErr_SetString(PyExc_SystemError, "required field \"ifs\" missing from comprehension"); + return 1; + } + *out = comprehension(target, iter, ifs, arena); + return 0; +failed: + Py_XDECREF(tmp); + return 1; +} + +int +obj2ast_excepthandler(PyObject* obj, excepthandler_ty* out, PyArena* arena) +{ + PyObject* tmp = NULL; + expr_ty type; + expr_ty name; + asdl_seq* body; + int lineno; + int col_offset; + + if (PyObject_HasAttrString(obj, "type")) { + int res; + tmp = PyObject_GetAttrString(obj, "type"); + if (tmp == NULL) goto failed; + res = obj2ast_expr(tmp, &type, arena); + if (res != 0) goto failed; + Py_DECREF(tmp); + tmp = NULL; + } + else { + type = NULL; + } + if (PyObject_HasAttrString(obj, "name")) { + int res; + tmp = PyObject_GetAttrString(obj, "name"); + if (tmp == NULL) goto failed; + res = obj2ast_expr(tmp, &name, arena); + if (res != 0) goto failed; + Py_DECREF(tmp); + tmp = NULL; + } + else { + name = NULL; + } + 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; + len = PyList_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_GetItem(tmp, i), &value, arena); + if (res != 0) goto failed; + asdl_seq_SET(body, i, value); + } + Py_DECREF(tmp); + tmp = NULL; + } + else { + PyErr_SetString(PyExc_SystemError, "required field \"body\" missing from excepthandler"); + return 1; + } + if (PyObject_HasAttrString(obj, "lineno")) { + int res; + tmp = PyObject_GetAttrString(obj, "lineno"); + if (tmp == NULL) goto failed; + res = obj2ast_int(tmp, &lineno, arena); + if (res != 0) goto failed; + Py_DECREF(tmp); + tmp = NULL; + } + else { + PyErr_SetString(PyExc_SystemError, "required field \"lineno\" missing from excepthandler"); + return 1; + } + if (PyObject_HasAttrString(obj, "col_offset")) { + int res; + tmp = PyObject_GetAttrString(obj, "col_offset"); + if (tmp == NULL) goto failed; + res = obj2ast_int(tmp, &col_offset, arena); + if (res != 0) goto failed; + Py_DECREF(tmp); + tmp = NULL; + } + else { + PyErr_SetString(PyExc_SystemError, "required field \"col_offset\" missing from excepthandler"); + return 1; + } + *out = excepthandler(type, name, body, lineno, col_offset, arena); + return 0; +failed: + Py_XDECREF(tmp); + return 1; +} + +int +obj2ast_arguments(PyObject* obj, arguments_ty* out, PyArena* arena) +{ + PyObject* tmp = NULL; + asdl_seq* args; + identifier vararg; + identifier kwarg; + asdl_seq* defaults; + + if (PyObject_HasAttrString(obj, "args")) { + int res; + Py_ssize_t len; + Py_ssize_t i; + tmp = PyObject_GetAttrString(obj, "args"); + if (tmp == NULL) goto failed; + len = PyList_Size(tmp); + args = asdl_seq_new(len, arena); + if (args == NULL) goto failed; + for (i = 0; i < len; i++) { + expr_ty value; + res = obj2ast_expr(PyList_GetItem(tmp, i), &value, arena); + if (res != 0) goto failed; + asdl_seq_SET(args, i, value); + } + Py_DECREF(tmp); + tmp = NULL; + } + else { + PyErr_SetString(PyExc_SystemError, "required field \"args\" missing from arguments"); + return 1; + } + if (PyObject_HasAttrString(obj, "vararg")) { + int res; + tmp = PyObject_GetAttrString(obj, "vararg"); + if (tmp == NULL) goto failed; + res = obj2ast_identifier(tmp, &vararg, arena); + if (res != 0) goto failed; + Py_DECREF(tmp); + tmp = NULL; + } + else { + vararg = NULL; + } + if (PyObject_HasAttrString(obj, "kwarg")) { + int res; + tmp = PyObject_GetAttrString(obj, "kwarg"); + if (tmp == NULL) goto failed; + res = obj2ast_identifier(tmp, &kwarg, arena); + if (res != 0) goto failed; + Py_DECREF(tmp); + tmp = NULL; + } + else { + kwarg = NULL; + } + if (PyObject_HasAttrString(obj, "defaults")) { + int res; + Py_ssize_t len; + Py_ssize_t i; + tmp = PyObject_GetAttrString(obj, "defaults"); + if (tmp == NULL) goto failed; + len = PyList_Size(tmp); + defaults = asdl_seq_new(len, arena); + if (defaults == NULL) goto failed; + for (i = 0; i < len; i++) { + expr_ty value; + res = obj2ast_expr(PyList_GetItem(tmp, i), &value, arena); + if (res != 0) goto failed; + asdl_seq_SET(defaults, i, value); + } + Py_DECREF(tmp); + tmp = NULL; + } + else { + PyErr_SetString(PyExc_SystemError, "required field \"defaults\" missing from arguments"); + return 1; + } + *out = arguments(args, vararg, kwarg, defaults, arena); + return 0; +failed: + Py_XDECREF(tmp); + return 1; +} + +int +obj2ast_keyword(PyObject* obj, keyword_ty* out, PyArena* arena) +{ + PyObject* tmp = NULL; + identifier arg; + expr_ty value; + + if (PyObject_HasAttrString(obj, "arg")) { + int res; + tmp = PyObject_GetAttrString(obj, "arg"); + if (tmp == NULL) goto failed; + res = obj2ast_identifier(tmp, &arg, arena); + if (res != 0) goto failed; + Py_DECREF(tmp); + tmp = NULL; + } + else { + PyErr_SetString(PyExc_SystemError, "required field \"arg\" missing from keyword"); + return 1; + } + if (PyObject_HasAttrString(obj, "value")) { + int res; + tmp = PyObject_GetAttrString(obj, "value"); + if (tmp == NULL) goto failed; + res = obj2ast_expr(tmp, &value, arena); + if (res != 0) goto failed; + Py_DECREF(tmp); + tmp = NULL; + } + else { + PyErr_SetString(PyExc_SystemError, "required field \"value\" missing from keyword"); + return 1; + } + *out = keyword(arg, value, arena); + return 0; +failed: + Py_XDECREF(tmp); + return 1; +} + +int +obj2ast_alias(PyObject* obj, alias_ty* out, PyArena* arena) +{ + PyObject* tmp = NULL; + identifier name; + identifier asname; + + if (PyObject_HasAttrString(obj, "name")) { + int res; + tmp = PyObject_GetAttrString(obj, "name"); + if (tmp == NULL) goto failed; + res = obj2ast_identifier(tmp, &name, arena); + if (res != 0) goto failed; + Py_DECREF(tmp); + tmp = NULL; + } + else { + PyErr_SetString(PyExc_SystemError, "required field \"name\" missing from alias"); + return 1; + } + if (PyObject_HasAttrString(obj, "asname")) { + int res; + tmp = PyObject_GetAttrString(obj, "asname"); + if (tmp == NULL) goto failed; + res = obj2ast_identifier(tmp, &asname, arena); + if (res != 0) goto failed; + Py_DECREF(tmp); + tmp = NULL; + } + else { + asname = NULL; + } + *out = alias(name, asname, arena); + return 0; +failed: + Py_XDECREF(tmp); + return 1; +} + + PyMODINIT_FUNC init_ast(void) { @@ -3109,4 +5846,20 @@ return ast2obj_mod(t); } +mod_ty PyAST_obj2mod(PyObject *ast, PyArena *arena) +{ + mod_ty res; + init_types(); + if (obj2ast_mod(ast, &res, arena) != 0) + return NULL; + else + return res; +} +int PyAST_Check(PyObject *obj) +{ + init_types(); + return PyObject_IsInstance(obj, (PyObject *)AST_type); +} + + Index: Python/bltinmodule.c =================================================================== --- Python/bltinmodule.c (revision 61399) +++ Python/bltinmodule.c (working copy) @@ -1,6 +1,7 @@ /* Built-in functions */ #include "Python.h" +#include "Python-ast.h" #include "node.h" #include "code.h" @@ -460,15 +461,12 @@ static PyObject * builtin_compile(PyObject *self, PyObject *args, PyObject *kwds) { - char *str; char *filename; char *startstr; - int start; int dont_inherit = 0; int supplied_flags = 0; PyCompilerFlags cf; PyObject *result = NULL, *cmd, *tmp = NULL; - Py_ssize_t length; static char *kwlist[] = {"source", "filename", "mode", "flags", "dont_inherit", NULL}; @@ -479,35 +477,6 @@ cf.cf_flags = supplied_flags; -#ifdef Py_USING_UNICODE - if (PyUnicode_Check(cmd)) { - tmp = PyUnicode_AsUTF8String(cmd); - if (tmp == NULL) - return NULL; - cmd = tmp; - cf.cf_flags |= PyCF_SOURCE_IS_UTF8; - } -#endif - if (PyObject_AsReadBuffer(cmd, (const void **)&str, &length)) - return NULL; - if ((size_t)length != strlen(str)) { - PyErr_SetString(PyExc_TypeError, - "compile() expected string without null bytes"); - goto cleanup; - } - - if (strcmp(startstr, "exec") == 0) - start = Py_file_input; - else if (strcmp(startstr, "eval") == 0) - start = Py_eval_input; - else if (strcmp(startstr, "single") == 0) - start = Py_single_input; - else { - PyErr_SetString(PyExc_ValueError, - "compile() arg 3 must be 'exec' or 'eval' or 'single'"); - goto cleanup; - } - if (supplied_flags & ~(PyCF_MASK | PyCF_MASK_OBSOLETE | PyCF_DONT_IMPLY_DEDENT | PyCF_ONLY_AST)) { @@ -520,7 +489,62 @@ if (!dont_inherit) { PyEval_MergeCompilerFlags(&cf); } - result = Py_CompileStringFlags(str, filename, start, &cf); + + if (PyAST_Check(cmd)) { + if (supplied_flags & PyCF_ONLY_AST) { + Py_INCREF(cmd); + result = cmd; + } + else { + PyArena *arena; + mod_ty mod; + + arena = PyArena_New(); + mod = PyAST_obj2mod(cmd, arena); + if (mod == NULL) { + PyArena_Free(arena); + goto cleanup; + } + result = (PyObject*)PyAST_Compile(mod, filename, &cf, arena); + PyArena_Free(arena); + } + } + else { + char *str; + Py_ssize_t length; + int start; + +#ifdef Py_USING_UNICODE + if (PyUnicode_Check(cmd)) { + tmp = PyUnicode_AsUTF8String(cmd); + if (tmp == NULL) + return NULL; + cmd = tmp; + cf.cf_flags |= PyCF_SOURCE_IS_UTF8; + } +#endif + /* XXX: is it possible to pass start to the PyAST_ branch? */ + if (strcmp(startstr, "exec") == 0) + start = Py_file_input; + else if (strcmp(startstr, "eval") == 0) + start = Py_eval_input; + else if (strcmp(startstr, "single") == 0) + start = Py_single_input; + else { + PyErr_SetString(PyExc_ValueError, + "compile() arg 3 must be 'exec' or 'eval' or 'single'"); + goto cleanup; + } + + if (PyObject_AsReadBuffer(cmd, (const void **)&str, &length)) + return NULL; + if ((size_t)length != strlen(str)) { + PyErr_SetString(PyExc_TypeError, + "compile() expected string without null bytes"); + goto cleanup; + } + result = Py_CompileStringFlags(str, filename, start, &cf); + } cleanup: Py_XDECREF(tmp); return result; Index: Include/Python-ast.h =================================================================== --- Include/Python-ast.h (revision 61399) +++ Include/Python-ast.h (working copy) @@ -501,3 +501,5 @@ alias_ty _Py_alias(identifier name, identifier asname, PyArena *arena); PyObject* PyAST_mod2obj(mod_ty t); +mod_ty PyAST_obj2mod(PyObject *obj, PyArena* arena); +int PyAST_Check(PyObject *obj); Index: Parser/asdl_c.py =================================================================== --- Parser/asdl_c.py (revision 61399) +++ Parser/asdl_c.py (working copy) @@ -74,6 +74,10 @@ unaryop = Invert | Not | UAdd | USub """ + if not hasattr(sum, "types"): + # probably a product or something + return False + for t in sum.types: if t.fields: return False @@ -346,6 +350,171 @@ def visitField(self, sum): pass +class Obj2ModPrototypeVisitor(PickleVisitor): + + def visitProduct(self, prod, name): + code = "static int obj2ast_%s(PyObject* obj, %s* out, PyArena* arena);" + self.emit(code % (name, get_c_type(name)), 0) + + visitSum = visitProduct + +class Obj2ModVisitor(PickleVisitor): + def simpleSum(self, sum, name): + ctype = get_c_type(name) + self.emit("int", 0) + self.emit("obj2ast_%s(PyObject* obj, %s* out, PyArena* arena)" % (name, ctype), 0) + self.emit("{", 0) + self.emit("", 0) + for t in sum.types: + self.emit("if (obj == %s_singleton) {" % t.name, 1) + self.emit("*out = %s;" % t.name, 2) + self.emit("return 0;", 2) + self.emit("}", 1) + self.emit("return 1;", 1) + self.emit("}", 0) + self.emit("", 0) + + def buildArgs(self, fields): + if len(fields) > 0: + return ", ".join(fields) + ", arena" + else: + return "arena" + + def complexSum(self, sum, name): + ctype = get_c_type(name) + self.emit("int", 0) + self.emit("obj2ast_%s(PyObject* obj, %s* out, PyArena* arena)" % (name, ctype), 0) + self.emit("{", 0) + self.emit("PyObject* tmp = NULL;", 1) + for a in sum.attributes: + self.visitAttributeDeclaration(a, name, sum=sum) + self.emit("", 0) + # XXX: should we only do this for 'expr'? + self.emit("if (obj == Py_None) {", 1) + self.emit("*out = NULL;", 2) + self.emit("return 0;", 2) + self.emit("}", 1) + for a in sum.attributes: + self.visitField(a, name, sum=sum, depth=1) + for t in sum.types: + self.emit("if (PyObject_IsInstance(obj, (PyObject*)%s_type)) {" % t.name, 1) + for f in t.fields: + self.visitFieldDeclaration(f, t.name, sum=sum, depth=2) + self.emit("", 0) + for f in t.fields: + self.visitField(f, t.name, sum=sum, depth=2) + args = [f.name.value for f in t.fields] + [a.name.value for a in sum.attributes] + self.emit("*out = %s(%s);" % (t.name, self.buildArgs(args)), 2) + self.emit("if (*out == NULL) goto failed;", 2) + self.emit("return 0;", 2) + self.emit("}", 1) + self.emit("", 0) + self.emit("tmp = PyObject_Str(obj);", 1) + # there's really nothing more we can do if this fails ... + self.emit("if (tmp == NULL) goto failed;", 1) + error = "expected some sort of %s, but got %%s" % name + format = "PyErr_Format(PyExc_TypeError, \"%s\", PyString_AsString(tmp));" + self.emit(format % error, 1, reflow=False) + self.emit("failed:", 0) + self.emit("Py_XDECREF(tmp);", 1) + self.emit("return 1;", 1) + self.emit("}", 0) + self.emit("", 0) + + def visitAttributeDeclaration(self, a, name, sum=sum): + ctype = get_c_type(a.type) + self.emit("%s %s;" % (ctype, a.name), 1) + + def visitSum(self, sum, name): + if is_simple(sum): + self.simpleSum(sum, name) + else: + self.complexSum(sum, name) + + def visitProduct(self, prod, name): + ctype = get_c_type(name) + self.emit("int", 0) + self.emit("obj2ast_%s(PyObject* obj, %s* out, PyArena* arena)" % (name, ctype), 0) + self.emit("{", 0) + self.emit("PyObject* tmp = NULL;", 1) + for f in prod.fields: + self.visitFieldDeclaration(f, name, prod=prod, depth=1) + self.emit("", 0) + for f in prod.fields: + self.visitField(f, name, prod=prod, depth=1) + args = [f.name.value for f in prod.fields] + self.emit("*out = %s(%s);" % (name, self.buildArgs(args)), 1) + self.emit("return 0;", 1) + self.emit("failed:", 0) + self.emit("Py_XDECREF(tmp);", 1) + self.emit("return 1;", 1) + self.emit("}", 0) + self.emit("", 0) + + def visitFieldDeclaration(self, field, name, sum=None, prod=None, depth=0): + ctype = get_c_type(field.type) + if field.seq: + if self.isSimpleType(field): + self.emit("asdl_int_seq* %s;" % field.name, depth) + else: + self.emit("asdl_seq* %s;" % field.name, depth) + else: + ctype = get_c_type(field.type) + self.emit("%s %s;" % (ctype, field.name), depth) + + def isSimpleSum(self, field): + return field.type.value in ("expr_context", "boolop", "unaryop", "operator", "cmpop") + + def isNumeric(self, field): + return get_c_type(field.type) in ("int", "bool") + + def isSimpleType(self, field): + return self.isSimpleSum(field) or self.isNumeric(field) + + def visitField(self, field, name, sum=None, prod=None, depth=0): + ctype = get_c_type(field.type) + self.emit("if (PyObject_HasAttrString(obj, \"%s\")) {" % field.name, depth) + self.emit("int res;", depth+1) + if field.seq: + self.emit("Py_ssize_t len;", depth+1) + self.emit("Py_ssize_t i;", depth+1) + self.emit("tmp = PyObject_GetAttrString(obj, \"%s\");" % field.name, depth+1) + self.emit("if (tmp == NULL) goto failed;", depth+1) + if field.seq: + self.emit("len = PyList_Size(tmp);", depth+1) + if self.isSimpleType(field): + self.emit("%s = asdl_int_seq_new(len, arena);" % field.name, depth+1) + else: + self.emit("%s = asdl_seq_new(len, arena);" % field.name, depth+1) + self.emit("if (%s == NULL) goto failed;" % field.name, depth+1) + self.emit("for (i = 0; i < len; i++) {", depth+1) + self.emit("%s value;" % ctype, depth+2) + self.emit("res = obj2ast_%s(PyList_GetItem(tmp, i), &value, arena);" % field.type, depth+2, reflow=False) + self.emit("if (res != 0) goto failed;", depth+2) + self.emit("asdl_seq_SET(%s, i, value);" % field.name, depth+2) + self.emit("}", depth+1) + else: + self.emit("res = obj2ast_%s(tmp, &%s, arena);" % (field.type, field.name), depth+1) + self.emit("if (res != 0) goto failed;", depth+1) + + self.emit("Py_DECREF(tmp);", depth+1) + self.emit("tmp = NULL;", depth+1) + self.emit("}", depth) + self.emit("else {", depth) + if not field.opt: + message = "required field \\\"%s\\\" missing from %s" % (field.name, name) + format = "PyErr_SetString(PyExc_SystemError, \"%s\");" + self.emit(format % message, depth+1, reflow=False) + self.emit("return 1;", depth+1) + else: + if self.isNumeric(field): + self.emit("%s = 0;" % field.name, depth+1) + elif not self.isSimpleType(field): + self.emit("%s = NULL;" % field.name, depth+1) + else: + raise TypeError, "could not determine the default value for %s" % field.name + self.emit("}", depth) + class MarshalPrototypeVisitor(PickleVisitor): def prototype(self, sum, name): @@ -476,6 +645,47 @@ { return PyInt_FromLong(b); } + +static int obj2ast_object(PyObject* obj, PyObject** out, PyArena* arena) +{ + if (obj == Py_None) + obj = NULL; + Py_XINCREF(obj); + *out = obj; + return 0; +} + +#define obj2ast_identifier obj2ast_object +#define obj2ast_string obj2ast_object + +static int obj2ast_int(PyObject* obj, int* out, PyArena* arena) +{ + if (!PyInt_Check(obj) && !PyLong_Check(obj)) { + PyObject *s = PyObject_Repr(obj); + if (s == NULL) return 1; + PyErr_Format(PyExc_ValueError, "invalid integer value: %s", PyString_AsString(s)); + Py_DECREF(s); + return 1; + } + + *out = (int)PyLong_AsLong(obj); + return 0; +} + +static int obj2ast_bool(PyObject* obj, bool* out, PyArena* arena) +{ + if (!PyBool_Check(obj)) { + PyObject *s = PyObject_Repr(obj); + if (s == NULL) return 1; + PyErr_Format(PyExc_ValueError, "invalid boolean value: %s", PyString_AsString(s)); + Py_DECREF(s); + return 1; + } + + *out = (obj == Py_True); + return 0; +} + """, 0, reflow=False) self.emit("static int init_types(void)",0) @@ -637,8 +847,12 @@ self.emit("case %s:" % t.name, 2) self.emit("Py_INCREF(%s_singleton);" % t.name, 3) self.emit("return %s_singleton;" % t.name, 3) + self.emit("default:" % name, 2) + self.emit('/* should never happen, but just in case ... */', 3) + code = "PyErr_Format(PyExc_SystemError, \"unknown %s found\");" % name + self.emit(code, 3, reflow=False) + self.emit("return NULL;", 3) self.emit("}", 1) - self.emit("return NULL; /* cannot happen */", 1) self.emit("}", 0) def visitProduct(self, prod, name): @@ -712,6 +926,22 @@ init_types(); return ast2obj_mod(t); } + +mod_ty PyAST_obj2mod(PyObject *ast, PyArena *arena) +{ + mod_ty res; + init_types(); + if (obj2ast_mod(ast, &res, arena) != 0) + return NULL; + else + return res; +} + +int PyAST_Check(PyObject *obj) +{ + init_types(); + return PyObject_IsInstance(obj, (PyObject *)AST_type); +} """ class ChainOfVisitors: @@ -754,6 +984,8 @@ ) c.visit(mod) print >>f, "PyObject* PyAST_mod2obj(mod_ty t);" + print >>f, "mod_ty PyAST_obj2mod(PyObject *obj, PyArena* arena);" + print >>f, "int PyAST_Check(PyObject *obj);" f.close() if SRC_DIR: @@ -768,8 +1000,10 @@ v = ChainOfVisitors( PyTypesDeclareVisitor(f), PyTypesVisitor(f), + Obj2ModPrototypeVisitor(f), FunctionVisitor(f), ObjVisitor(f), + Obj2ModVisitor(f), ASTModuleVisitor(f), PartingShots(f), ) Index: Lib/test/test_compile.py =================================================================== --- Lib/test/test_compile.py (revision 61399) +++ Lib/test/test_compile.py (working copy) @@ -1,5 +1,6 @@ import unittest import sys +import _ast from test import test_support class TestSpecifics(unittest.TestCase): @@ -410,6 +411,34 @@ self.assert_("_A__mangled_mod" in A.f.func_code.co_varnames) self.assert_("__package__" in A.f.func_code.co_varnames) + def test_compile_ast(self): + sample_code = [ + ['', 'x = 5'], + ['', 'print 1'], + ['', 'print v'], + ['', 'print True'], + ['', 'print []'], + ['', """if True: + pass +"""], + ['', """for n in [1, 2, 3]: + print n +"""], + ['', """def foo(): + pass + +foo() + +"""] + ] + + for fname, code in sample_code: + co1 = compile(code, '%s1' % fname, 'exec') + ast = compile(code, '%s2' % fname, 'exec', _ast.PyCF_ONLY_AST) + self.assert_(type(ast) == _ast.Module) + co2 = compile(ast, '%s3' % fname, 'exec') + self.assertEqual(co1, co2) + def test_main(): test_support.run_unittest(TestSpecifics)