diff --git a/Parser/asdl_c.py b/Parser/asdl_c.py index 9fba049683e..acaa99bfc25 100755 --- a/Parser/asdl_c.py +++ b/Parser/asdl_c.py @@ -609,13 +609,21 @@ class ObjVisitor(PickleVisitor): def set(self, field, value, depth): if field.seq: + # XXX should really check for is_simple, but that requires a symbol table if field.type.value == "cmpop": - # XXX check that this cast is safe, i.e. works independent on whether - # sizeof(cmpop_ty) != sizeof(void*) - cast = "(PyObject*(*)(void*))" + # While the sequence elements are stored as void*, + # ast2obj_cmpop expects an enum + self.emit("{", depth) + self.emit("int i, n = asdl_seq_LEN(%s);" % value, depth+1) + self.emit("value = PyList_New(n);", depth+1) + self.emit("if (!value) goto failed;", depth+1) + self.emit("for(i = 0; i < n; i++)", depth+1) + # This cannot fail, so no need for error handling + self.emit("PyList_SET_ITEM(value, i, ast2obj_%s((%s_ty)asdl_seq_GET(%s, i)));" % + (field.type, field.type, value), depth+2, reflow=False) + self.emit("}", depth) else: - cast = "" - self.emit("value = ast2obj_list(%s, %sast2obj_%s);" % (value, cast, field.type), depth) + self.emit("value = ast2obj_list(%s, ast2obj_%s);" % (value, field.type), depth) else: ctype = get_c_type(field.type) self.emit("value = ast2obj_%s(%s);" % (field.type, value), depth, reflow=False) diff --git a/Python/Python-ast.c b/Python/Python-ast.c index f881c474ba6..ee6a5380f4e 100644 --- a/Python/Python-ast.c +++ b/Python/Python-ast.c @@ -2216,8 +2216,13 @@ ast2obj_expr(void* _o) if (PyObject_SetAttrString(result, "left", value) == -1) goto failed; Py_DECREF(value); - value = ast2obj_list(o->v.Compare.ops, - (PyObject*(*)(void*))ast2obj_cmpop); + { + int i, n = asdl_seq_LEN(o->v.Compare.ops); + value = PyList_New(n); + if (!value) goto failed; + for(i = 0; i < n; i++) + PyList_SET_ITEM(value, i, ast2obj_cmpop((cmpop_ty)asdl_seq_GET(o->v.Compare.ops, i))); + } if (!value) goto failed; if (PyObject_SetAttrString(result, "ops", value) == -1) goto failed;