diff options
author | Martin v. Löwis <martin@v.loewis.de> | 2008-03-30 20:03:44 (GMT) |
---|---|---|
committer | Martin v. Löwis <martin@v.loewis.de> | 2008-03-30 20:03:44 (GMT) |
commit | 618dc5e06459dab5fae2dc0a8caee7d15afd6410 (patch) | |
tree | 2881b2c079821ef43895742f3c65171acf582cc1 | |
parent | d3372793d6de665be2f866e9245a33bcefeaaa76 (diff) | |
download | cpython-618dc5e06459dab5fae2dc0a8caee7d15afd6410.zip cpython-618dc5e06459dab5fae2dc0a8caee7d15afd6410.tar.gz cpython-618dc5e06459dab5fae2dc0a8caee7d15afd6410.tar.bz2 |
Merged revisions 62004 via svnmerge from
svn+ssh://pythondev@svn.python.org/python/trunk
........
r62004 | georg.brandl | 2008-03-28 13:11:56 +0100 (Fr, 28 Mär 2008) | 4 lines
Patch #1810 by Thomas Lee, reviewed by myself:
allow compiling Python AST objects into code objects
in compile().
........
-rw-r--r-- | Doc/library/_ast.rst | 23 | ||||
-rw-r--r-- | Doc/library/functions.rst | 33 | ||||
-rw-r--r-- | Include/Python-ast.h | 2 | ||||
-rw-r--r-- | Lib/test/test_compile.py | 23 | ||||
-rwxr-xr-x | Parser/asdl_c.py | 255 | ||||
-rw-r--r-- | Python/Python-ast.c | 3116 | ||||
-rw-r--r-- | Python/bltinmodule.c | 53 | ||||
-rw-r--r-- | Python/compile.c | 20 |
8 files changed, 3474 insertions, 51 deletions
diff --git a/Doc/library/_ast.rst b/Doc/library/_ast.rst index 9f56156..518798e 100644 --- a/Doc/library/_ast.rst +++ b/Doc/library/_ast.rst @@ -10,16 +10,16 @@ Abstract Syntax Trees The ``_ast`` module helps Python applications to process trees of the Python -abstract syntax grammar. The Python compiler currently provides read-only access -to such trees, meaning that applications can only create a tree for a given -piece of Python source code; generating :term:`bytecode` from a (potentially modified) -tree is not supported. The abstract syntax itself might change with each Python -release; this module helps to find out programmatically what the current grammar -looks like. +abstract syntax grammar. The abstract syntax itself might change with each +Python release; this module helps to find out programmatically what the current +grammar looks like. -An abstract syntax tree can be generated by passing ``_ast.PyCF_ONLY_AST`` as a -flag to the :func:`compile` builtin function. The result will be a tree of -objects whose classes all inherit from ``_ast.AST``. +An abstract syntax tree can be generated by passing :data:`_ast.PyCF_ONLY_AST` +as a flag to the :func:`compile` builtin function. The result will be a tree of +objects whose classes all inherit from :class:`_ast.AST`. + +A modified abstract syntax tree can be compiled into a Python code object using +the built-in :func:`compile` function. The actual classes are derived from the ``Parser/Python.asdl`` file, which is reproduced below. There is one class defined for each left-hand side symbol in @@ -39,12 +39,15 @@ attribute ``left`` of type ``_ast.expr``. Instances of ``_ast.expr`` and ``_ast.stmt`` subclasses also have lineno and col_offset attributes. The lineno is the line number of source text (1 indexed so the first line is line 1) and the col_offset is the utf8 byte offset of the first token that generated the -node. The utf8 offset is recorded because the parser uses utf8 internally. +node. The utf8 offset is recorded because the parser uses utf8 internally. If these attributes are marked as optional in the grammar (using a question mark), the value might be ``None``. If the attributes can have zero-or-more values (marked with an asterisk), the values are represented as Python lists. +The constructors of all ``_ast`` classes don't take arguments; instead, if you +create instances, you must assign the required attributes separately. + Abstract Grammar ---------------- diff --git a/Doc/library/functions.rst b/Doc/library/functions.rst index 7c97edb..d1e979c 100644 --- a/Doc/library/functions.rst +++ b/Doc/library/functions.rst @@ -193,21 +193,21 @@ available. They are listed here in alphabetical order. .. function:: compile(source, filename, mode[, flags[, dont_inherit]]) - Compile the *source* into a code object. Code objects can be executed by a call - to :func:`exec` or evaluated by a call to :func:`eval`. The *filename* argument - should give the file from which the code was read; pass some recognizable value - if it wasn't read from a file (``'<string>'`` is commonly used). The *mode* - argument specifies what kind of code must be compiled; it can be ``'exec'`` if - *source* consists of a sequence of statements, ``'eval'`` if it consists of a - single expression, or ``'single'`` if it consists of a single interactive - statement (in the latter case, expression statements that evaluate to something - else than ``None`` will be printed). - - When compiling multi-line statements, two caveats apply: line endings must be - represented by a single newline character (``'\n'``), and the input must be - terminated by at least one newline character. If line endings are represented - by ``'\r\n'``, use the string :meth:`replace` method to change them into - ``'\n'``. + Compile the *source* into a code object. Code objects can be + executed by a call to :func:`exec` or evaluated by a call to + :func:`eval`. *source* can either be a string or an AST object. + Refer to the :mod:`_ast` module documentation for information on + how to compile into and from AST objects. + + The *filename* argument should give the file from + which the code was read; pass some recognizable value if it wasn't + read from a file (``'<string>'`` is commonly used). The *mode* + argument specifies what kind of code must be compiled; it can be + ``'exec'`` if *source* consists of a sequence of statements, + ``'eval'`` if it consists of a single expression, or ``'single'`` + if it consists of a single interactive statement (in the latter + case, expression statements that evaluate to something else than + ``None`` will be printed). The optional arguments *flags* and *dont_inherit* (which are new in Python 2.2) control which future statements (see :pep:`236`) affect the compilation of @@ -227,6 +227,9 @@ available. They are listed here in alphabetical order. This function raises :exc:`SyntaxError` if the compiled source is invalid, and :exc:`TypeError` if the source contains null bytes. + .. versionadded:: 2.6 + Support for compiling AST objects. + .. function:: complex([real[, imag]]) diff --git a/Include/Python-ast.h b/Include/Python-ast.h index 51e5298..c018ddd 100644 --- a/Include/Python-ast.h +++ b/Include/Python-ast.h @@ -542,3 +542,5 @@ keyword_ty _Py_keyword(identifier arg, expr_ty value, PyArena *arena); alias_ty _Py_alias(identifier name, identifier asname, PyArena *arena); PyObject* PyAST_mod2obj(mod_ty t); +mod_ty PyAST_obj2mod(PyObject* ast, PyArena* arena); +int PyAST_Check(PyObject* obj); diff --git a/Lib/test/test_compile.py b/Lib/test/test_compile.py index 4979f92..376369b 100644 --- a/Lib/test/test_compile.py +++ b/Lib/test/test_compile.py @@ -1,5 +1,6 @@ import unittest import sys +import _ast from test import test_support class TestSpecifics(unittest.TestCase): @@ -406,6 +407,28 @@ if 1: self.assert_("_A__mangled_mod" in A.f.__code__.co_varnames) self.assert_("__package__" in A.f.__code__.co_varnames) + def test_compile_ast(self): + fname = __file__ + if fname.lower().endswith(('pyc', 'pyo')): + fname = fname[:-1] + with open(fname, 'r') as f: + fcontents = f.read() + sample_code = [ + ['<assign>', 'x = 5'], + ['<ifblock>', """if True:\n pass\n"""], + ['<forblock>', """for n in [1, 2, 3]:\n print(n)\n"""], + ['<deffunc>', """def foo():\n pass\nfoo()\n"""], + [fname, fcontents], + ] + + 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) diff --git a/Parser/asdl_c.py b/Parser/asdl_c.py index df4a91d..496ad01 100755 --- a/Parser/asdl_c.py +++ b/Parser/asdl_c.py @@ -73,12 +73,12 @@ def is_simple(sum): A sum is simple if its types have no fields, e.g. unaryop = Invert | Not | UAdd | USub """ - for t in sum.types: if t.fields: return False return True + class EmitVisitor(asdl.VisitorBase): """Visit that emits lines""" @@ -96,6 +96,7 @@ class EmitVisitor(asdl.VisitorBase): line = (" " * TABSIZE * depth) + line + "\n" self.file.write(line) + class TypeDefVisitor(EmitVisitor): def visitModule(self, mod): for dfn in mod.dfns: @@ -133,6 +134,7 @@ class TypeDefVisitor(EmitVisitor): self.emit(s, depth) self.emit("", depth) + class StructVisitor(EmitVisitor): """Visitor to generate typdefs for AST.""" @@ -202,6 +204,7 @@ class StructVisitor(EmitVisitor): self.emit("};", depth) self.emit("", depth) + class PrototypeVisitor(EmitVisitor): """Generate function prototypes for the .h file""" @@ -271,6 +274,7 @@ class PrototypeVisitor(EmitVisitor): self.emit_function(name, get_c_type(name), self.get_args(prod.fields), [], union=0) + class FunctionVisitor(PrototypeVisitor): """Visitor to generate constructor functions for AST.""" @@ -324,6 +328,7 @@ class FunctionVisitor(PrototypeVisitor): emit("p->%s = %s;" % (argname, argname), 1) assert not attrs + class PickleVisitor(EmitVisitor): def visitModule(self, mod): @@ -345,6 +350,181 @@ class PickleVisitor(EmitVisitor): 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 funcHeader(self, 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) + self.emit("", 0) + + def sumTrailer(self, name): + self.emit("", 0) + self.emit("tmp = PyObject_Repr(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 %%.400s" % name + format = "PyErr_Format(PyExc_TypeError, \"%s\", PyString_AS_STRING(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 simpleSum(self, sum, name): + self.funcHeader(name) + for t in sum.types: + self.emit("if (PyObject_IsInstance(obj, (PyObject*)%s_type)) {" % t.name, 1) + self.emit("*out = %s;" % t.name, 2) + self.emit("return 0;", 2) + self.emit("}", 1) + self.sumTrailer(name) + + def buildArgs(self, fields): + return ", ".join(fields + ["arena"]) + + def complexSum(self, sum, name): + self.funcHeader(name) + 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.sumTrailer(name) + + 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): + # XXX can the members of this list be determined automatically? + return field.type.value in ('expr_context', 'boolop', 'operator', + 'unaryop', '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("if (!PyList_Check(tmp)) {", depth+1) + self.emit("PyErr_Format(PyExc_TypeError, \"%s field \\\"%s\\\" must " + "be a list, not a %%.200s\", tmp->ob_type->tp_name);" % + (name, field.name), + depth+2, reflow=False) + self.emit("goto failed;", depth+2) + self.emit("}", depth+1) + self.emit("len = PyList_GET_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_GET_ITEM(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_XDECREF(tmp);", depth+1) + self.emit("tmp = NULL;", depth+1) + self.emit("} else {", depth) + if not field.opt: + message = "required field \\\"%s\\\" missing from %s" % (field.name, name) + format = "PyErr_SetString(PyExc_TypeError, \"%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): @@ -354,6 +534,7 @@ class MarshalPrototypeVisitor(PickleVisitor): visitProduct = visitSum = prototype + class PyTypesDeclareVisitor(PickleVisitor): def visitProduct(self, prod, name): @@ -439,6 +620,8 @@ static int add_attributes(PyTypeObject* type, char**attrs, int num_fields) return result; } +/* Conversion AST -> Python */ + static PyObject* ast2obj_list(asdl_seq *seq, PyObject* (*func)(void*)) { int i, n = asdl_seq_LEN(seq); @@ -471,6 +654,42 @@ static PyObject* ast2obj_int(long b) { return PyLong_FromLong(b); } + +/* Conversion Python -> AST */ + +static int obj2ast_object(PyObject* obj, PyObject** out, PyArena* arena) +{ + if (obj == Py_None) + obj = NULL; + if (obj) + PyArena_AddPyObject(arena, obj); + 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) +{ + int i; + if (!PyLong_Check(obj)) { + PyObject *s = PyObject_Repr(obj); + if (s == NULL) return 1; + PyErr_Format(PyExc_ValueError, "invalid integer value: %.400s", + PyString_AS_STRING(s)); + Py_DECREF(s); + return 1; + } + + i = (int)PyLong_AsLong(obj); + if (i == -1 && PyErr_Occurred()) + return 1; + *out = i; + return 0; +} + """, 0, reflow=False) self.emit("static int init_types(void)",0) @@ -518,6 +737,7 @@ static PyObject* ast2obj_int(long b) (cons.name, cons.name), 1) self.emit("if (!%s_singleton) return 0;" % cons.name, 1) + def parse_version(mod): return mod.version.value[12:-3] @@ -557,6 +777,7 @@ class ASTModuleVisitor(PickleVisitor): def addObj(self, name): self.emit('if (PyDict_SetItemString(d, "%s", (PyObject*)%s_type) < 0) return;' % (name, name), 1) + _SPECIALIZED_SEQUENCES = ('stmt', 'expr') def find_sequence(fields, doing_specialization): @@ -582,6 +803,7 @@ class StaticVisitor(PickleVisitor): def visit(self, object): self.emit(self.CODE, 0, reflow=False) + class ObjVisitor(PickleVisitor): def func_begin(self, name): @@ -632,8 +854,12 @@ class ObjVisitor(PickleVisitor): 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): @@ -707,6 +933,27 @@ PyObject* PyAST_mod2obj(mod_ty t) init_types(); return ast2obj_mod(t); } + +mod_ty PyAST_obj2mod(PyObject* ast, PyArena* arena) +{ + mod_ty res; + init_types(); + if (!PyObject_IsInstance(ast, mod_type)) { + PyErr_SetString(PyExc_TypeError, "expected either Module, Interactive " + "or Expression node"); + return NULL; + } + 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: @@ -750,6 +997,8 @@ def main(srcfile): ) c.visit(mod) f.write("PyObject* PyAST_mod2obj(mod_ty t);\n") + print >>f, "mod_ty PyAST_obj2mod(PyObject* ast, PyArena* arena);" + print >>f, "int PyAST_Check(PyObject* obj);" f.close() if SRC_DIR: @@ -764,8 +1013,10 @@ def main(srcfile): v = ChainOfVisitors( PyTypesDeclareVisitor(f), PyTypesVisitor(f), + Obj2ModPrototypeVisitor(f), FunctionVisitor(f), ObjVisitor(f), + Obj2ModVisitor(f), ASTModuleVisitor(f), PartingShots(f), ) diff --git a/Python/Python-ast.c b/Python/Python-ast.c index c46176c..e89c9d5 100644 --- a/Python/Python-ast.c +++ b/Python/Python-ast.c @@ -434,6 +434,8 @@ static int add_attributes(PyTypeObject* type, char**attrs, int num_fields) return result; } +/* Conversion AST -> Python */ + static PyObject* ast2obj_list(asdl_seq *seq, PyObject* (*func)(void*)) { int i, n = asdl_seq_LEN(seq); @@ -467,6 +469,42 @@ static PyObject* ast2obj_int(long b) return PyLong_FromLong(b); } +/* Conversion Python -> AST */ + +static int obj2ast_object(PyObject* obj, PyObject** out, PyArena* arena) +{ + if (obj == Py_None) + obj = NULL; + if (obj) + PyArena_AddPyObject(arena, obj); + 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) +{ + int i; + if (!PyLong_Check(obj)) { + PyObject *s = PyObject_Repr(obj); + if (s == NULL) return 1; + PyErr_Format(PyExc_ValueError, "invalid integer value: %.400s", + PyString_AS_STRING(s)); + Py_DECREF(s); + return 1; + } + + i = (int)PyLong_AsLong(obj); + if (i == -1 && PyErr_Occurred()) + return 1; + *out = i; + return 0; +} + + static int init_types(void) { static int initialized; @@ -765,6 +803,25 @@ static int init_types(void) 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_arg(PyObject* obj, arg_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) { @@ -2768,8 +2825,11 @@ PyObject* ast2obj_expr_context(expr_context_ty o) 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) @@ -2836,8 +2896,11 @@ PyObject* ast2obj_boolop(boolop_ty o) 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) { @@ -2878,8 +2941,11 @@ PyObject* ast2obj_operator(operator_ty o) 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) { @@ -2896,8 +2962,11 @@ PyObject* ast2obj_unaryop(unaryop_ty o) 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) { @@ -2932,8 +3001,11 @@ PyObject* ast2obj_cmpop(cmpop_ty o) 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) @@ -3160,6 +3232,3019 @@ failed: } +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; + if (!PyList_Check(tmp)) { + PyErr_Format(PyExc_TypeError, "Module 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 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; + if (!PyList_Check(tmp)) { + PyErr_Format(PyExc_TypeError, "Interactive 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 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_XDECREF(tmp); + tmp = NULL; + } else { + PyErr_SetString(PyExc_TypeError, "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; + if (!PyList_Check(tmp)) { + PyErr_Format(PyExc_TypeError, "Suite 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 Suite"); + return 1; + } + *out = Suite(body, arena); + if (*out == NULL) goto failed; + return 0; + } + + tmp = PyObject_Repr(obj); + if (tmp == NULL) goto failed; + PyErr_Format(PyExc_TypeError, "expected some sort of mod, but got %.400s", PyString_AS_STRING(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_XDECREF(tmp); + tmp = NULL; + } else { + PyErr_SetString(PyExc_TypeError, "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_XDECREF(tmp); + tmp = NULL; + } else { + PyErr_SetString(PyExc_TypeError, "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; + expr_ty returns; + + 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_XDECREF(tmp); + tmp = NULL; + } else { + PyErr_SetString(PyExc_TypeError, "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_XDECREF(tmp); + tmp = NULL; + } else { + PyErr_SetString(PyExc_TypeError, "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; + if (!PyList_Check(tmp)) { + PyErr_Format(PyExc_TypeError, "FunctionDef 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 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; + if (!PyList_Check(tmp)) { + PyErr_Format(PyExc_TypeError, "FunctionDef field \"decorator_list\" must be a list, not a %.200s", tmp->ob_type->tp_name); + goto failed; + } + len = PyList_GET_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_GET_ITEM(tmp, i), &value, arena); + if (res != 0) goto failed; + asdl_seq_SET(decorator_list, i, value); + } + Py_XDECREF(tmp); + tmp = NULL; + } else { + PyErr_SetString(PyExc_TypeError, "required field \"decorator_list\" missing from FunctionDef"); + return 1; + } + if (PyObject_HasAttrString(obj, "returns")) { + int res; + tmp = PyObject_GetAttrString(obj, "returns"); + if (tmp == NULL) goto failed; + res = obj2ast_expr(tmp, &returns, arena); + if (res != 0) goto failed; + Py_XDECREF(tmp); + tmp = NULL; + } else { + returns = NULL; + } + *out = FunctionDef(name, args, body, decorator_list, returns, + 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* keywords; + expr_ty starargs; + expr_ty kwargs; + 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_XDECREF(tmp); + tmp = NULL; + } else { + PyErr_SetString(PyExc_TypeError, "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; + if (!PyList_Check(tmp)) { + PyErr_Format(PyExc_TypeError, "ClassDef field \"bases\" must be a list, not a %.200s", tmp->ob_type->tp_name); + goto failed; + } + len = PyList_GET_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_GET_ITEM(tmp, i), &value, arena); + if (res != 0) goto failed; + asdl_seq_SET(bases, i, value); + } + Py_XDECREF(tmp); + tmp = NULL; + } else { + PyErr_SetString(PyExc_TypeError, "required field \"bases\" missing from ClassDef"); + 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; + if (!PyList_Check(tmp)) { + PyErr_Format(PyExc_TypeError, "ClassDef field \"keywords\" must be a list, not a %.200s", tmp->ob_type->tp_name); + goto failed; + } + len = PyList_GET_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_GET_ITEM(tmp, i), &value, arena); + if (res != 0) goto failed; + asdl_seq_SET(keywords, i, value); + } + Py_XDECREF(tmp); + tmp = NULL; + } else { + PyErr_SetString(PyExc_TypeError, "required field \"keywords\" missing from ClassDef"); + 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_XDECREF(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_XDECREF(tmp); + tmp = NULL; + } else { + kwargs = 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; + if (!PyList_Check(tmp)) { + PyErr_Format(PyExc_TypeError, "ClassDef 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 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; + if (!PyList_Check(tmp)) { + PyErr_Format(PyExc_TypeError, "ClassDef field \"decorator_list\" must be a list, not a %.200s", tmp->ob_type->tp_name); + goto failed; + } + len = PyList_GET_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_GET_ITEM(tmp, i), &value, arena); + if (res != 0) goto failed; + asdl_seq_SET(decorator_list, i, value); + } + Py_XDECREF(tmp); + tmp = NULL; + } else { + PyErr_SetString(PyExc_TypeError, "required field \"decorator_list\" missing from ClassDef"); + return 1; + } + *out = ClassDef(name, bases, keywords, starargs, kwargs, 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_XDECREF(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; + if (!PyList_Check(tmp)) { + PyErr_Format(PyExc_TypeError, "Delete field \"targets\" must be a list, not a %.200s", tmp->ob_type->tp_name); + goto failed; + } + len = PyList_GET_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_GET_ITEM(tmp, i), &value, arena); + if (res != 0) goto failed; + asdl_seq_SET(targets, i, value); + } + Py_XDECREF(tmp); + tmp = NULL; + } else { + PyErr_SetString(PyExc_TypeError, "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; + if (!PyList_Check(tmp)) { + PyErr_Format(PyExc_TypeError, "Assign field \"targets\" must be a list, not a %.200s", tmp->ob_type->tp_name); + goto failed; + } + len = PyList_GET_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_GET_ITEM(tmp, i), &value, arena); + if (res != 0) goto failed; + asdl_seq_SET(targets, i, value); + } + Py_XDECREF(tmp); + tmp = NULL; + } else { + PyErr_SetString(PyExc_TypeError, "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_XDECREF(tmp); + tmp = NULL; + } else { + PyErr_SetString(PyExc_TypeError, "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_XDECREF(tmp); + tmp = NULL; + } else { + PyErr_SetString(PyExc_TypeError, "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_XDECREF(tmp); + tmp = NULL; + } else { + PyErr_SetString(PyExc_TypeError, "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_XDECREF(tmp); + tmp = NULL; + } else { + PyErr_SetString(PyExc_TypeError, "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*)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_XDECREF(tmp); + tmp = NULL; + } else { + PyErr_SetString(PyExc_TypeError, "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_XDECREF(tmp); + tmp = NULL; + } else { + PyErr_SetString(PyExc_TypeError, "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; + if (!PyList_Check(tmp)) { + PyErr_Format(PyExc_TypeError, "For 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 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; + if (!PyList_Check(tmp)) { + PyErr_Format(PyExc_TypeError, "For field \"orelse\" must be a list, not a %.200s", tmp->ob_type->tp_name); + goto failed; + } + len = PyList_GET_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_GET_ITEM(tmp, i), &value, arena); + if (res != 0) goto failed; + asdl_seq_SET(orelse, i, value); + } + Py_XDECREF(tmp); + tmp = NULL; + } else { + PyErr_SetString(PyExc_TypeError, "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_XDECREF(tmp); + tmp = NULL; + } else { + PyErr_SetString(PyExc_TypeError, "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; + if (!PyList_Check(tmp)) { + PyErr_Format(PyExc_TypeError, "While 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 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; + if (!PyList_Check(tmp)) { + PyErr_Format(PyExc_TypeError, "While field \"orelse\" must be a list, not a %.200s", tmp->ob_type->tp_name); + goto failed; + } + len = PyList_GET_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_GET_ITEM(tmp, i), &value, arena); + if (res != 0) goto failed; + asdl_seq_SET(orelse, i, value); + } + Py_XDECREF(tmp); + tmp = NULL; + } else { + PyErr_SetString(PyExc_TypeError, "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_XDECREF(tmp); + tmp = NULL; + } else { + PyErr_SetString(PyExc_TypeError, "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; + if (!PyList_Check(tmp)) { + PyErr_Format(PyExc_TypeError, "If 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 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; + if (!PyList_Check(tmp)) { + PyErr_Format(PyExc_TypeError, "If field \"orelse\" must be a list, not a %.200s", tmp->ob_type->tp_name); + goto failed; + } + len = PyList_GET_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_GET_ITEM(tmp, i), &value, arena); + if (res != 0) goto failed; + asdl_seq_SET(orelse, i, value); + } + Py_XDECREF(tmp); + tmp = NULL; + } else { + PyErr_SetString(PyExc_TypeError, "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_XDECREF(tmp); + tmp = NULL; + } else { + PyErr_SetString(PyExc_TypeError, "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_XDECREF(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; + if (!PyList_Check(tmp)) { + PyErr_Format(PyExc_TypeError, "With 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 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 exc; + expr_ty cause; + + if (PyObject_HasAttrString(obj, "exc")) { + int res; + tmp = PyObject_GetAttrString(obj, "exc"); + if (tmp == NULL) goto failed; + res = obj2ast_expr(tmp, &exc, arena); + if (res != 0) goto failed; + Py_XDECREF(tmp); + tmp = NULL; + } else { + exc = NULL; + } + if (PyObject_HasAttrString(obj, "cause")) { + int res; + tmp = PyObject_GetAttrString(obj, "cause"); + if (tmp == NULL) goto failed; + res = obj2ast_expr(tmp, &cause, arena); + if (res != 0) goto failed; + Py_XDECREF(tmp); + tmp = NULL; + } else { + cause = NULL; + } + *out = Raise(exc, cause, 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; + if (!PyList_Check(tmp)) { + PyErr_Format(PyExc_TypeError, "TryExcept 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 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; + if (!PyList_Check(tmp)) { + PyErr_Format(PyExc_TypeError, "TryExcept field \"handlers\" must be a list, not a %.200s", tmp->ob_type->tp_name); + goto failed; + } + len = PyList_GET_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_GET_ITEM(tmp, i), &value, arena); + if (res != 0) goto failed; + asdl_seq_SET(handlers, i, value); + } + Py_XDECREF(tmp); + tmp = NULL; + } else { + PyErr_SetString(PyExc_TypeError, "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; + if (!PyList_Check(tmp)) { + PyErr_Format(PyExc_TypeError, "TryExcept field \"orelse\" must be a list, not a %.200s", tmp->ob_type->tp_name); + goto failed; + } + len = PyList_GET_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_GET_ITEM(tmp, i), &value, arena); + if (res != 0) goto failed; + asdl_seq_SET(orelse, i, value); + } + Py_XDECREF(tmp); + tmp = NULL; + } else { + PyErr_SetString(PyExc_TypeError, "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; + 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; + } + 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; + if (!PyList_Check(tmp)) { + PyErr_Format(PyExc_TypeError, "TryFinally field \"finalbody\" must be a list, not a %.200s", tmp->ob_type->tp_name); + goto failed; + } + len = PyList_GET_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_GET_ITEM(tmp, i), &value, arena); + if (res != 0) goto failed; + asdl_seq_SET(finalbody, i, value); + } + Py_XDECREF(tmp); + tmp = NULL; + } else { + PyErr_SetString(PyExc_TypeError, "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_XDECREF(tmp); + tmp = NULL; + } else { + PyErr_SetString(PyExc_TypeError, "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_XDECREF(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; + if (!PyList_Check(tmp)) { + PyErr_Format(PyExc_TypeError, "Import field \"names\" must be a list, not a %.200s", tmp->ob_type->tp_name); + goto failed; + } + len = PyList_GET_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_GET_ITEM(tmp, i), &value, arena); + if (res != 0) goto failed; + asdl_seq_SET(names, i, value); + } + Py_XDECREF(tmp); + tmp = NULL; + } else { + PyErr_SetString(PyExc_TypeError, "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_XDECREF(tmp); + tmp = NULL; + } else { + PyErr_SetString(PyExc_TypeError, "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; + if (!PyList_Check(tmp)) { + PyErr_Format(PyExc_TypeError, "ImportFrom field \"names\" must be a list, not a %.200s", tmp->ob_type->tp_name); + goto failed; + } + len = PyList_GET_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_GET_ITEM(tmp, i), &value, arena); + if (res != 0) goto failed; + asdl_seq_SET(names, i, value); + } + Py_XDECREF(tmp); + tmp = NULL; + } else { + PyErr_SetString(PyExc_TypeError, "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_XDECREF(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*)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; + if (!PyList_Check(tmp)) { + PyErr_Format(PyExc_TypeError, "Global field \"names\" must be a list, not a %.200s", tmp->ob_type->tp_name); + goto failed; + } + len = PyList_GET_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_GET_ITEM(tmp, i), &value, arena); + if (res != 0) goto failed; + asdl_seq_SET(names, i, value); + } + Py_XDECREF(tmp); + tmp = NULL; + } else { + PyErr_SetString(PyExc_TypeError, "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*)Nonlocal_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; + if (!PyList_Check(tmp)) { + PyErr_Format(PyExc_TypeError, "Nonlocal field \"names\" must be a list, not a %.200s", tmp->ob_type->tp_name); + goto failed; + } + len = PyList_GET_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_GET_ITEM(tmp, i), &value, arena); + if (res != 0) goto failed; + asdl_seq_SET(names, i, value); + } + Py_XDECREF(tmp); + tmp = NULL; + } else { + PyErr_SetString(PyExc_TypeError, "required field \"names\" missing from Nonlocal"); + return 1; + } + *out = Nonlocal(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_XDECREF(tmp); + tmp = NULL; + } else { + PyErr_SetString(PyExc_TypeError, "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_Repr(obj); + if (tmp == NULL) goto failed; + PyErr_Format(PyExc_TypeError, "expected some sort of stmt, but got %.400s", PyString_AS_STRING(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_XDECREF(tmp); + tmp = NULL; + } else { + PyErr_SetString(PyExc_TypeError, "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_XDECREF(tmp); + tmp = NULL; + } else { + PyErr_SetString(PyExc_TypeError, "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_XDECREF(tmp); + tmp = NULL; + } else { + PyErr_SetString(PyExc_TypeError, "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; + if (!PyList_Check(tmp)) { + PyErr_Format(PyExc_TypeError, "BoolOp field \"values\" must be a list, not a %.200s", tmp->ob_type->tp_name); + goto failed; + } + len = PyList_GET_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_GET_ITEM(tmp, i), &value, arena); + if (res != 0) goto failed; + asdl_seq_SET(values, i, value); + } + Py_XDECREF(tmp); + tmp = NULL; + } else { + PyErr_SetString(PyExc_TypeError, "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_XDECREF(tmp); + tmp = NULL; + } else { + PyErr_SetString(PyExc_TypeError, "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_XDECREF(tmp); + tmp = NULL; + } else { + PyErr_SetString(PyExc_TypeError, "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_XDECREF(tmp); + tmp = NULL; + } else { + PyErr_SetString(PyExc_TypeError, "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_XDECREF(tmp); + tmp = NULL; + } else { + PyErr_SetString(PyExc_TypeError, "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_XDECREF(tmp); + tmp = NULL; + } else { + PyErr_SetString(PyExc_TypeError, "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_XDECREF(tmp); + tmp = NULL; + } else { + PyErr_SetString(PyExc_TypeError, "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_XDECREF(tmp); + tmp = NULL; + } else { + PyErr_SetString(PyExc_TypeError, "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_XDECREF(tmp); + tmp = NULL; + } else { + PyErr_SetString(PyExc_TypeError, "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_XDECREF(tmp); + tmp = NULL; + } else { + PyErr_SetString(PyExc_TypeError, "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_XDECREF(tmp); + tmp = NULL; + } else { + PyErr_SetString(PyExc_TypeError, "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; + if (!PyList_Check(tmp)) { + PyErr_Format(PyExc_TypeError, "Dict field \"keys\" must be a list, not a %.200s", tmp->ob_type->tp_name); + goto failed; + } + len = PyList_GET_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_GET_ITEM(tmp, i), &value, arena); + if (res != 0) goto failed; + asdl_seq_SET(keys, i, value); + } + Py_XDECREF(tmp); + tmp = NULL; + } else { + PyErr_SetString(PyExc_TypeError, "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; + if (!PyList_Check(tmp)) { + PyErr_Format(PyExc_TypeError, "Dict field \"values\" must be a list, not a %.200s", tmp->ob_type->tp_name); + goto failed; + } + len = PyList_GET_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_GET_ITEM(tmp, i), &value, arena); + if (res != 0) goto failed; + asdl_seq_SET(values, i, value); + } + Py_XDECREF(tmp); + tmp = NULL; + } else { + PyErr_SetString(PyExc_TypeError, "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*)Set_type)) { + asdl_seq* elts; + + 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; + if (!PyList_Check(tmp)) { + PyErr_Format(PyExc_TypeError, "Set field \"elts\" must be a list, not a %.200s", tmp->ob_type->tp_name); + goto failed; + } + len = PyList_GET_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_GET_ITEM(tmp, i), &value, arena); + if (res != 0) goto failed; + asdl_seq_SET(elts, i, value); + } + Py_XDECREF(tmp); + tmp = NULL; + } else { + PyErr_SetString(PyExc_TypeError, "required field \"elts\" missing from Set"); + return 1; + } + *out = Set(elts, 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_XDECREF(tmp); + tmp = NULL; + } else { + PyErr_SetString(PyExc_TypeError, "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; + if (!PyList_Check(tmp)) { + PyErr_Format(PyExc_TypeError, "ListComp field \"generators\" must be a list, not a %.200s", tmp->ob_type->tp_name); + goto failed; + } + len = PyList_GET_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_GET_ITEM(tmp, i), &value, arena); + if (res != 0) goto failed; + asdl_seq_SET(generators, i, value); + } + Py_XDECREF(tmp); + tmp = NULL; + } else { + PyErr_SetString(PyExc_TypeError, "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*)SetComp_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_XDECREF(tmp); + tmp = NULL; + } else { + PyErr_SetString(PyExc_TypeError, "required field \"elt\" missing from SetComp"); + 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; + if (!PyList_Check(tmp)) { + PyErr_Format(PyExc_TypeError, "SetComp field \"generators\" must be a list, not a %.200s", tmp->ob_type->tp_name); + goto failed; + } + len = PyList_GET_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_GET_ITEM(tmp, i), &value, arena); + if (res != 0) goto failed; + asdl_seq_SET(generators, i, value); + } + Py_XDECREF(tmp); + tmp = NULL; + } else { + PyErr_SetString(PyExc_TypeError, "required field \"generators\" missing from SetComp"); + return 1; + } + *out = SetComp(elt, generators, lineno, col_offset, arena); + if (*out == NULL) goto failed; + return 0; + } + if (PyObject_IsInstance(obj, (PyObject*)DictComp_type)) { + expr_ty key; + expr_ty value; + asdl_seq* generators; + + if (PyObject_HasAttrString(obj, "key")) { + int res; + tmp = PyObject_GetAttrString(obj, "key"); + if (tmp == NULL) goto failed; + res = obj2ast_expr(tmp, &key, arena); + if (res != 0) goto failed; + Py_XDECREF(tmp); + tmp = NULL; + } else { + PyErr_SetString(PyExc_TypeError, "required field \"key\" missing from DictComp"); + 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_XDECREF(tmp); + tmp = NULL; + } else { + PyErr_SetString(PyExc_TypeError, "required field \"value\" missing from DictComp"); + 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; + if (!PyList_Check(tmp)) { + PyErr_Format(PyExc_TypeError, "DictComp field \"generators\" must be a list, not a %.200s", tmp->ob_type->tp_name); + goto failed; + } + len = PyList_GET_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_GET_ITEM(tmp, i), &value, arena); + if (res != 0) goto failed; + asdl_seq_SET(generators, i, value); + } + Py_XDECREF(tmp); + tmp = NULL; + } else { + PyErr_SetString(PyExc_TypeError, "required field \"generators\" missing from DictComp"); + return 1; + } + *out = DictComp(key, value, 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_XDECREF(tmp); + tmp = NULL; + } else { + PyErr_SetString(PyExc_TypeError, "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; + if (!PyList_Check(tmp)) { + PyErr_Format(PyExc_TypeError, "GeneratorExp field \"generators\" must be a list, not a %.200s", tmp->ob_type->tp_name); + goto failed; + } + len = PyList_GET_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_GET_ITEM(tmp, i), &value, arena); + if (res != 0) goto failed; + asdl_seq_SET(generators, i, value); + } + Py_XDECREF(tmp); + tmp = NULL; + } else { + PyErr_SetString(PyExc_TypeError, "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_XDECREF(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_XDECREF(tmp); + tmp = NULL; + } else { + PyErr_SetString(PyExc_TypeError, "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; + if (!PyList_Check(tmp)) { + PyErr_Format(PyExc_TypeError, "Compare field \"ops\" must be a list, not a %.200s", tmp->ob_type->tp_name); + goto failed; + } + len = PyList_GET_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_GET_ITEM(tmp, i), &value, arena); + if (res != 0) goto failed; + asdl_seq_SET(ops, i, value); + } + Py_XDECREF(tmp); + tmp = NULL; + } else { + PyErr_SetString(PyExc_TypeError, "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; + if (!PyList_Check(tmp)) { + PyErr_Format(PyExc_TypeError, "Compare field \"comparators\" must be a list, not a %.200s", tmp->ob_type->tp_name); + goto failed; + } + len = PyList_GET_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_GET_ITEM(tmp, i), &value, arena); + if (res != 0) goto failed; + asdl_seq_SET(comparators, i, value); + } + Py_XDECREF(tmp); + tmp = NULL; + } else { + PyErr_SetString(PyExc_TypeError, "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_XDECREF(tmp); + tmp = NULL; + } else { + PyErr_SetString(PyExc_TypeError, "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; + if (!PyList_Check(tmp)) { + PyErr_Format(PyExc_TypeError, "Call field \"args\" must be a list, not a %.200s", tmp->ob_type->tp_name); + goto failed; + } + len = PyList_GET_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_GET_ITEM(tmp, i), &value, arena); + if (res != 0) goto failed; + asdl_seq_SET(args, i, value); + } + Py_XDECREF(tmp); + tmp = NULL; + } else { + PyErr_SetString(PyExc_TypeError, "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; + if (!PyList_Check(tmp)) { + PyErr_Format(PyExc_TypeError, "Call field \"keywords\" must be a list, not a %.200s", tmp->ob_type->tp_name); + goto failed; + } + len = PyList_GET_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_GET_ITEM(tmp, i), &value, arena); + if (res != 0) goto failed; + asdl_seq_SET(keywords, i, value); + } + Py_XDECREF(tmp); + tmp = NULL; + } else { + PyErr_SetString(PyExc_TypeError, "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_XDECREF(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_XDECREF(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*)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_XDECREF(tmp); + tmp = NULL; + } else { + PyErr_SetString(PyExc_TypeError, "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_XDECREF(tmp); + tmp = NULL; + } else { + PyErr_SetString(PyExc_TypeError, "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*)Bytes_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_XDECREF(tmp); + tmp = NULL; + } else { + PyErr_SetString(PyExc_TypeError, "required field \"s\" missing from Bytes"); + return 1; + } + *out = Bytes(s, lineno, col_offset, arena); + if (*out == NULL) goto failed; + return 0; + } + if (PyObject_IsInstance(obj, (PyObject*)Ellipsis_type)) { + + *out = Ellipsis(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_XDECREF(tmp); + tmp = NULL; + } else { + PyErr_SetString(PyExc_TypeError, "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_XDECREF(tmp); + tmp = NULL; + } else { + PyErr_SetString(PyExc_TypeError, "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_XDECREF(tmp); + tmp = NULL; + } else { + PyErr_SetString(PyExc_TypeError, "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_XDECREF(tmp); + tmp = NULL; + } else { + PyErr_SetString(PyExc_TypeError, "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_XDECREF(tmp); + tmp = NULL; + } else { + PyErr_SetString(PyExc_TypeError, "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_XDECREF(tmp); + tmp = NULL; + } else { + PyErr_SetString(PyExc_TypeError, "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*)Starred_type)) { + expr_ty value; + 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_XDECREF(tmp); + tmp = NULL; + } else { + PyErr_SetString(PyExc_TypeError, "required field \"value\" missing from Starred"); + 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_XDECREF(tmp); + tmp = NULL; + } else { + PyErr_SetString(PyExc_TypeError, "required field \"ctx\" missing from Starred"); + return 1; + } + *out = Starred(value, 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_XDECREF(tmp); + tmp = NULL; + } else { + PyErr_SetString(PyExc_TypeError, "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_XDECREF(tmp); + tmp = NULL; + } else { + PyErr_SetString(PyExc_TypeError, "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; + if (!PyList_Check(tmp)) { + PyErr_Format(PyExc_TypeError, "List field \"elts\" must be a list, not a %.200s", tmp->ob_type->tp_name); + goto failed; + } + len = PyList_GET_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_GET_ITEM(tmp, i), &value, arena); + if (res != 0) goto failed; + asdl_seq_SET(elts, i, value); + } + Py_XDECREF(tmp); + tmp = NULL; + } else { + PyErr_SetString(PyExc_TypeError, "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_XDECREF(tmp); + tmp = NULL; + } else { + PyErr_SetString(PyExc_TypeError, "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; + if (!PyList_Check(tmp)) { + PyErr_Format(PyExc_TypeError, "Tuple field \"elts\" must be a list, not a %.200s", tmp->ob_type->tp_name); + goto failed; + } + len = PyList_GET_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_GET_ITEM(tmp, i), &value, arena); + if (res != 0) goto failed; + asdl_seq_SET(elts, i, value); + } + Py_XDECREF(tmp); + tmp = NULL; + } else { + PyErr_SetString(PyExc_TypeError, "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_XDECREF(tmp); + tmp = NULL; + } else { + PyErr_SetString(PyExc_TypeError, "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_Repr(obj); + if (tmp == NULL) goto failed; + PyErr_Format(PyExc_TypeError, "expected some sort of expr, but got %.400s", PyString_AS_STRING(tmp)); +failed: + Py_XDECREF(tmp); + return 1; +} + +int +obj2ast_expr_context(PyObject* obj, expr_context_ty* out, PyArena* arena) +{ + PyObject* tmp = NULL; + + if (PyObject_IsInstance(obj, (PyObject*)Load_type)) { + *out = Load; + return 0; + } + if (PyObject_IsInstance(obj, (PyObject*)Store_type)) { + *out = Store; + return 0; + } + if (PyObject_IsInstance(obj, (PyObject*)Del_type)) { + *out = Del; + return 0; + } + if (PyObject_IsInstance(obj, (PyObject*)AugLoad_type)) { + *out = AugLoad; + return 0; + } + if (PyObject_IsInstance(obj, (PyObject*)AugStore_type)) { + *out = AugStore; + return 0; + } + if (PyObject_IsInstance(obj, (PyObject*)Param_type)) { + *out = Param; + return 0; + } + + tmp = PyObject_Repr(obj); + if (tmp == NULL) goto failed; + PyErr_Format(PyExc_TypeError, "expected some sort of expr_context, but got %.400s", PyString_AS_STRING(tmp)); +failed: + Py_XDECREF(tmp); + 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*)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_XDECREF(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_XDECREF(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_XDECREF(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; + if (!PyList_Check(tmp)) { + PyErr_Format(PyExc_TypeError, "ExtSlice field \"dims\" must be a list, not a %.200s", tmp->ob_type->tp_name); + goto failed; + } + len = PyList_GET_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_GET_ITEM(tmp, i), &value, arena); + if (res != 0) goto failed; + asdl_seq_SET(dims, i, value); + } + Py_XDECREF(tmp); + tmp = NULL; + } else { + PyErr_SetString(PyExc_TypeError, "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_XDECREF(tmp); + tmp = NULL; + } else { + PyErr_SetString(PyExc_TypeError, "required field \"value\" missing from Index"); + return 1; + } + *out = Index(value, arena); + if (*out == NULL) goto failed; + return 0; + } + + tmp = PyObject_Repr(obj); + if (tmp == NULL) goto failed; + PyErr_Format(PyExc_TypeError, "expected some sort of slice, but got %.400s", PyString_AS_STRING(tmp)); +failed: + Py_XDECREF(tmp); + return 1; +} + +int +obj2ast_boolop(PyObject* obj, boolop_ty* out, PyArena* arena) +{ + PyObject* tmp = NULL; + + if (PyObject_IsInstance(obj, (PyObject*)And_type)) { + *out = And; + return 0; + } + if (PyObject_IsInstance(obj, (PyObject*)Or_type)) { + *out = Or; + return 0; + } + + tmp = PyObject_Repr(obj); + if (tmp == NULL) goto failed; + PyErr_Format(PyExc_TypeError, "expected some sort of boolop, but got %.400s", PyString_AS_STRING(tmp)); +failed: + Py_XDECREF(tmp); + return 1; +} + +int +obj2ast_operator(PyObject* obj, operator_ty* out, PyArena* arena) +{ + PyObject* tmp = NULL; + + if (PyObject_IsInstance(obj, (PyObject*)Add_type)) { + *out = Add; + return 0; + } + if (PyObject_IsInstance(obj, (PyObject*)Sub_type)) { + *out = Sub; + return 0; + } + if (PyObject_IsInstance(obj, (PyObject*)Mult_type)) { + *out = Mult; + return 0; + } + if (PyObject_IsInstance(obj, (PyObject*)Div_type)) { + *out = Div; + return 0; + } + if (PyObject_IsInstance(obj, (PyObject*)Mod_type)) { + *out = Mod; + return 0; + } + if (PyObject_IsInstance(obj, (PyObject*)Pow_type)) { + *out = Pow; + return 0; + } + if (PyObject_IsInstance(obj, (PyObject*)LShift_type)) { + *out = LShift; + return 0; + } + if (PyObject_IsInstance(obj, (PyObject*)RShift_type)) { + *out = RShift; + return 0; + } + if (PyObject_IsInstance(obj, (PyObject*)BitOr_type)) { + *out = BitOr; + return 0; + } + if (PyObject_IsInstance(obj, (PyObject*)BitXor_type)) { + *out = BitXor; + return 0; + } + if (PyObject_IsInstance(obj, (PyObject*)BitAnd_type)) { + *out = BitAnd; + return 0; + } + if (PyObject_IsInstance(obj, (PyObject*)FloorDiv_type)) { + *out = FloorDiv; + return 0; + } + + tmp = PyObject_Repr(obj); + if (tmp == NULL) goto failed; + PyErr_Format(PyExc_TypeError, "expected some sort of operator, but got %.400s", PyString_AS_STRING(tmp)); +failed: + Py_XDECREF(tmp); + return 1; +} + +int +obj2ast_unaryop(PyObject* obj, unaryop_ty* out, PyArena* arena) +{ + PyObject* tmp = NULL; + + if (PyObject_IsInstance(obj, (PyObject*)Invert_type)) { + *out = Invert; + return 0; + } + if (PyObject_IsInstance(obj, (PyObject*)Not_type)) { + *out = Not; + return 0; + } + if (PyObject_IsInstance(obj, (PyObject*)UAdd_type)) { + *out = UAdd; + return 0; + } + if (PyObject_IsInstance(obj, (PyObject*)USub_type)) { + *out = USub; + return 0; + } + + tmp = PyObject_Repr(obj); + if (tmp == NULL) goto failed; + PyErr_Format(PyExc_TypeError, "expected some sort of unaryop, but got %.400s", PyString_AS_STRING(tmp)); +failed: + Py_XDECREF(tmp); + return 1; +} + +int +obj2ast_cmpop(PyObject* obj, cmpop_ty* out, PyArena* arena) +{ + PyObject* tmp = NULL; + + if (PyObject_IsInstance(obj, (PyObject*)Eq_type)) { + *out = Eq; + return 0; + } + if (PyObject_IsInstance(obj, (PyObject*)NotEq_type)) { + *out = NotEq; + return 0; + } + if (PyObject_IsInstance(obj, (PyObject*)Lt_type)) { + *out = Lt; + return 0; + } + if (PyObject_IsInstance(obj, (PyObject*)LtE_type)) { + *out = LtE; + return 0; + } + if (PyObject_IsInstance(obj, (PyObject*)Gt_type)) { + *out = Gt; + return 0; + } + if (PyObject_IsInstance(obj, (PyObject*)GtE_type)) { + *out = GtE; + return 0; + } + if (PyObject_IsInstance(obj, (PyObject*)Is_type)) { + *out = Is; + return 0; + } + if (PyObject_IsInstance(obj, (PyObject*)IsNot_type)) { + *out = IsNot; + return 0; + } + if (PyObject_IsInstance(obj, (PyObject*)In_type)) { + *out = In; + return 0; + } + if (PyObject_IsInstance(obj, (PyObject*)NotIn_type)) { + *out = NotIn; + return 0; + } + + tmp = PyObject_Repr(obj); + if (tmp == NULL) goto failed; + PyErr_Format(PyExc_TypeError, "expected some sort of cmpop, but got %.400s", PyString_AS_STRING(tmp)); +failed: + Py_XDECREF(tmp); + 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_XDECREF(tmp); + tmp = NULL; + } else { + PyErr_SetString(PyExc_TypeError, "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_XDECREF(tmp); + tmp = NULL; + } else { + PyErr_SetString(PyExc_TypeError, "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; + if (!PyList_Check(tmp)) { + PyErr_Format(PyExc_TypeError, "comprehension field \"ifs\" must be a list, not a %.200s", tmp->ob_type->tp_name); + goto failed; + } + len = PyList_GET_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_GET_ITEM(tmp, i), &value, arena); + if (res != 0) goto failed; + asdl_seq_SET(ifs, i, value); + } + Py_XDECREF(tmp); + tmp = NULL; + } else { + PyErr_SetString(PyExc_TypeError, "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; + identifier 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_XDECREF(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_identifier(tmp, &name, arena); + if (res != 0) goto failed; + Py_XDECREF(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; + if (!PyList_Check(tmp)) { + PyErr_Format(PyExc_TypeError, "excepthandler 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 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_XDECREF(tmp); + tmp = NULL; + } else { + PyErr_SetString(PyExc_TypeError, "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_XDECREF(tmp); + tmp = NULL; + } else { + PyErr_SetString(PyExc_TypeError, "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; + expr_ty varargannotation; + asdl_seq* kwonlyargs; + identifier kwarg; + expr_ty kwargannotation; + asdl_seq* defaults; + asdl_seq* kw_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; + if (!PyList_Check(tmp)) { + PyErr_Format(PyExc_TypeError, "arguments field \"args\" must be a list, not a %.200s", tmp->ob_type->tp_name); + goto failed; + } + len = PyList_GET_SIZE(tmp); + args = asdl_seq_new(len, arena); + if (args == NULL) goto failed; + for (i = 0; i < len; i++) { + arg_ty value; + res = obj2ast_arg(PyList_GET_ITEM(tmp, i), &value, arena); + if (res != 0) goto failed; + asdl_seq_SET(args, i, value); + } + Py_XDECREF(tmp); + tmp = NULL; + } else { + PyErr_SetString(PyExc_TypeError, "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_XDECREF(tmp); + tmp = NULL; + } else { + vararg = NULL; + } + if (PyObject_HasAttrString(obj, "varargannotation")) { + int res; + tmp = PyObject_GetAttrString(obj, "varargannotation"); + if (tmp == NULL) goto failed; + res = obj2ast_expr(tmp, &varargannotation, arena); + if (res != 0) goto failed; + Py_XDECREF(tmp); + tmp = NULL; + } else { + varargannotation = NULL; + } + if (PyObject_HasAttrString(obj, "kwonlyargs")) { + int res; + Py_ssize_t len; + Py_ssize_t i; + tmp = PyObject_GetAttrString(obj, "kwonlyargs"); + if (tmp == NULL) goto failed; + if (!PyList_Check(tmp)) { + PyErr_Format(PyExc_TypeError, "arguments field \"kwonlyargs\" must be a list, not a %.200s", tmp->ob_type->tp_name); + goto failed; + } + len = PyList_GET_SIZE(tmp); + kwonlyargs = asdl_seq_new(len, arena); + if (kwonlyargs == NULL) goto failed; + for (i = 0; i < len; i++) { + arg_ty value; + res = obj2ast_arg(PyList_GET_ITEM(tmp, i), &value, arena); + if (res != 0) goto failed; + asdl_seq_SET(kwonlyargs, i, value); + } + Py_XDECREF(tmp); + tmp = NULL; + } else { + PyErr_SetString(PyExc_TypeError, "required field \"kwonlyargs\" missing from arguments"); + return 1; + } + 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_XDECREF(tmp); + tmp = NULL; + } else { + kwarg = NULL; + } + if (PyObject_HasAttrString(obj, "kwargannotation")) { + int res; + tmp = PyObject_GetAttrString(obj, "kwargannotation"); + if (tmp == NULL) goto failed; + res = obj2ast_expr(tmp, &kwargannotation, arena); + if (res != 0) goto failed; + Py_XDECREF(tmp); + tmp = NULL; + } else { + kwargannotation = 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; + if (!PyList_Check(tmp)) { + PyErr_Format(PyExc_TypeError, "arguments field \"defaults\" must be a list, not a %.200s", tmp->ob_type->tp_name); + goto failed; + } + len = PyList_GET_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_GET_ITEM(tmp, i), &value, arena); + if (res != 0) goto failed; + asdl_seq_SET(defaults, i, value); + } + Py_XDECREF(tmp); + tmp = NULL; + } else { + PyErr_SetString(PyExc_TypeError, "required field \"defaults\" missing from arguments"); + return 1; + } + if (PyObject_HasAttrString(obj, "kw_defaults")) { + int res; + Py_ssize_t len; + Py_ssize_t i; + tmp = PyObject_GetAttrString(obj, "kw_defaults"); + if (tmp == NULL) goto failed; + if (!PyList_Check(tmp)) { + PyErr_Format(PyExc_TypeError, "arguments field \"kw_defaults\" must be a list, not a %.200s", tmp->ob_type->tp_name); + goto failed; + } + len = PyList_GET_SIZE(tmp); + kw_defaults = asdl_seq_new(len, arena); + if (kw_defaults == NULL) goto failed; + for (i = 0; i < len; i++) { + expr_ty value; + res = obj2ast_expr(PyList_GET_ITEM(tmp, i), &value, arena); + if (res != 0) goto failed; + asdl_seq_SET(kw_defaults, i, value); + } + Py_XDECREF(tmp); + tmp = NULL; + } else { + PyErr_SetString(PyExc_TypeError, "required field \"kw_defaults\" missing from arguments"); + return 1; + } + *out = arguments(args, vararg, varargannotation, kwonlyargs, kwarg, + kwargannotation, defaults, kw_defaults, arena); + return 0; +failed: + Py_XDECREF(tmp); + return 1; +} + +int +obj2ast_arg(PyObject* obj, arg_ty* out, PyArena* arena) +{ + PyObject* tmp = NULL; + identifier arg; + expr_ty annotation; + + 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_XDECREF(tmp); + tmp = NULL; + } else { + PyErr_SetString(PyExc_TypeError, "required field \"arg\" missing from arg"); + return 1; + } + if (PyObject_HasAttrString(obj, "annotation")) { + int res; + tmp = PyObject_GetAttrString(obj, "annotation"); + if (tmp == NULL) goto failed; + res = obj2ast_expr(tmp, &annotation, arena); + if (res != 0) goto failed; + Py_XDECREF(tmp); + tmp = NULL; + } else { + annotation = NULL; + } + *out = arg(arg, annotation, 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_XDECREF(tmp); + tmp = NULL; + } else { + PyErr_SetString(PyExc_TypeError, "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_XDECREF(tmp); + tmp = NULL; + } else { + PyErr_SetString(PyExc_TypeError, "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_XDECREF(tmp); + tmp = NULL; + } else { + PyErr_SetString(PyExc_TypeError, "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_XDECREF(tmp); + tmp = NULL; + } else { + asname = NULL; + } + *out = alias(name, asname, arena); + return 0; +failed: + Py_XDECREF(tmp); + return 1; +} + + PyMODINIT_FUNC init_ast(void) { @@ -3330,4 +6415,25 @@ PyObject* PyAST_mod2obj(mod_ty t) return ast2obj_mod(t); } +mod_ty PyAST_obj2mod(PyObject* ast, PyArena* arena) +{ + mod_ty res; + init_types(); + if (!PyObject_IsInstance(ast, mod_type)) { + PyErr_SetString(PyExc_TypeError, "expected either Module, Interactive " + "or Expression node"); + return NULL; + } + 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); +} + diff --git a/Python/bltinmodule.c b/Python/bltinmodule.c index b3d8b16..ccfce06 100644 --- a/Python/bltinmodule.c +++ b/Python/bltinmodule.c @@ -1,6 +1,7 @@ /* Built-in functions */ #include "Python.h" +#include "Python-ast.h" #include "node.h" #include "code.h" @@ -527,10 +528,43 @@ builtin_compile(PyObject *self, PyObject *args, PyObject *kwds) cf.cf_flags = supplied_flags | PyCF_SOURCE_IS_UTF8; - str = source_as_string(cmd); - if (str == NULL) + if (supplied_flags & + ~(PyCF_MASK | PyCF_MASK_OBSOLETE | PyCF_DONT_IMPLY_DEDENT | PyCF_ONLY_AST)) + { + PyErr_SetString(PyExc_ValueError, + "compile(): unrecognised flags"); return NULL; + } + /* XXX Warn if (supplied_flags & PyCF_MASK_OBSOLETE) != 0? */ + if (!dont_inherit) { + PyEval_MergeCompilerFlags(&cf); + } + + if (PyAST_Check(cmd)) { + PyObject *result; + 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); + return NULL; + } + result = (PyObject*)PyAST_Compile(mod, filename, + &cf, arena); + PyArena_Free(arena); + } + return result; + } + + /* 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) @@ -539,22 +573,15 @@ builtin_compile(PyObject *self, PyObject *args, PyObject *kwds) start = Py_single_input; else { PyErr_SetString(PyExc_ValueError, - "compile() arg 3 must be 'exec' or 'eval' or 'single'"); + "compile() arg 3 must be 'exec'" + "or 'eval' or 'single'"); return NULL; } - if (supplied_flags & - ~(PyCF_MASK | PyCF_MASK_OBSOLETE | PyCF_DONT_IMPLY_DEDENT | PyCF_ONLY_AST)) - { - PyErr_SetString(PyExc_ValueError, - "compile(): unrecognised flags"); + str = source_as_string(cmd); + if (str == NULL) return NULL; - } - /* XXX Warn if (supplied_flags & PyCF_MASK_OBSOLETE) != 0? */ - if (!dont_inherit) { - PyEval_MergeCompilerFlags(&cf); - } return Py_CompileStringFlags(str, filename, start, &cf); } diff --git a/Python/compile.c b/Python/compile.c index 7d5ada6..ab51c7b 100644 --- a/Python/compile.c +++ b/Python/compile.c @@ -2356,8 +2356,11 @@ unaryop(unaryop_ty op) 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 @@ -2388,8 +2391,11 @@ binop(struct compiler *c, operator_ty op) 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 @@ -2416,8 +2422,9 @@ cmpop(cmpop_ty op) return PyCmp_IN; case NotIn: return PyCmp_NOT_IN; + default: + return PyCmp_BAD; } - return PyCmp_BAD; } static int @@ -2448,10 +2455,11 @@ inplace_binop(struct compiler *c, operator_ty op) 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 |