Index: Python/Python-ast.c =================================================================== --- Python/Python-ast.c (Revision 62039) +++ Python/Python-ast.c (Arbeitskopie) @@ -12,7 +12,7 @@ #include "Python.h" #include "Python-ast.h" -static PyTypeObject* AST_type; +static PyTypeObject AST_type; static PyTypeObject *mod_type; static PyObject* ast2obj_mod(void*); static PyTypeObject *Module_type; @@ -366,6 +366,104 @@ }; +static int +ast_type_init(PyObject *self, PyObject *args, PyObject *kw) +{ + Py_ssize_t i = 0; + PyObject *key, *value; + if (PyTuple_GET_SIZE(args) > 0) { + PyErr_Format(PyExc_TypeError, + "%.400s object doesn't take positional arguments", + Py_TYPE(self)->tp_name); + return -1; + } + if (!kw) return 0; + while (PyDict_Next(kw, &i, &key, &value)) { + if (PyObject_SetAttr(self, key, value) < 0) + return -1; + } + return 0; +} + +static int +ast_type_setattr(PyObject *self, PyObject *name, PyObject *value) +{ + PyObject *fields = NULL, *attrs = NULL; + int res = -1; + fields = PyObject_GetAttrString((PyObject*)Py_TYPE(self), "_fields"); + if (!fields) + PyErr_Clear(); + attrs = PyObject_GetAttrString((PyObject*)Py_TYPE(self), "_attributes"); + if (!attrs) + PyErr_Clear(); + if (fields && fields != Py_None) { + res = PySequence_Contains(fields, name); + if (res == -1) + goto cleanup; + else if (res == 1) { + res = PyObject_GenericSetAttr(self, name, value); + goto cleanup; + } + } + if (attrs && attrs != Py_None) { + res = PySequence_Contains(attrs, name); + if (res == -1) + goto cleanup; + else if (res == 1) { + res = PyObject_GenericSetAttr(self, name, value); + goto cleanup; + } + } + PyErr_SetObject(PyExc_AttributeError, name); + cleanup: + Py_XDECREF(fields); + Py_XDECREF(attrs); + return res; +} + + +static PyTypeObject AST_type = { + PyVarObject_HEAD_INIT(&PyType_Type, 0) + "AST", + sizeof(PyObject), + 0, + 0, /* tp_dealloc */ + 0, /* tp_print */ + 0, /* tp_getattr */ + 0, /* tp_setattr */ + 0, /* tp_compare */ + 0, /* tp_repr */ + 0, /* tp_as_number */ + 0, /* tp_as_sequence */ + 0, /* tp_as_mapping */ + 0, /* tp_hash */ + 0, /* tp_call */ + 0, /* tp_str */ + PyObject_GenericGetAttr, /* tp_getattro */ + ast_type_setattr, /* tp_setattro */ + 0, /* tp_as_buffer */ + Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */ + 0, /* tp_doc */ + 0, /* tp_traverse */ + 0, /* tp_clear */ + 0, /* tp_richcompare */ + 0, /* tp_weaklistoffset */ + 0, /* tp_iter */ + 0, /* tp_iternext */ + 0, /* tp_methods */ + 0, /* tp_members */ + 0, /* tp_getset */ + 0, /* tp_base */ + 0, /* tp_dict */ + 0, /* tp_descr_get */ + 0, /* tp_descr_set */ + 0, /* tp_dictoffset */ + (initproc)ast_type_init, /* tp_init */ + PyType_GenericAlloc, /* tp_alloc */ + PyType_GenericNew, /* tp_new */ + PyObject_Del, /* tp_free */ +}; + static PyTypeObject* make_type(char *type, PyTypeObject* base, char**fields, int num_fields) { PyObject *fnames, *result; @@ -394,7 +492,7 @@ static int add_attributes(PyTypeObject* type, char**attrs, int num_fields) { int i, result; - PyObject *s, *l = PyList_New(num_fields); + PyObject *s, *l = PyTuple_New(num_fields); if (!l) return 0; for(i = 0; i < num_fields; i++) { s = PyString_FromString(attrs[i]); @@ -402,7 +500,7 @@ Py_DECREF(l); return 0; } - PyList_SET_ITEM(l, i, s); + PyTuple_SET_ITEM(l, i, s); } result = PyObject_SetAttrString((PyObject*)type, "_attributes", l) >= 0; Py_DECREF(l); @@ -503,8 +601,7 @@ { static int initialized; if (initialized) return 1; - AST_type = make_type("AST", &PyBaseObject_Type, NULL, 0); - mod_type = make_type("mod", AST_type, NULL, 0); + mod_type = make_type("mod", &AST_type, NULL, 0); if (!mod_type) return 0; if (!add_attributes(mod_type, NULL, 0)) return 0; Module_type = make_type("Module", mod_type, Module_fields, 1); @@ -517,7 +614,7 @@ if (!Expression_type) return 0; Suite_type = make_type("Suite", mod_type, Suite_fields, 1); if (!Suite_type) return 0; - stmt_type = make_type("stmt", AST_type, NULL, 0); + stmt_type = make_type("stmt", &AST_type, NULL, 0); if (!stmt_type) return 0; if (!add_attributes(stmt_type, stmt_attributes, 2)) return 0; FunctionDef_type = make_type("FunctionDef", stmt_type, @@ -569,7 +666,7 @@ if (!Break_type) return 0; Continue_type = make_type("Continue", stmt_type, NULL, 0); if (!Continue_type) return 0; - expr_type = make_type("expr", AST_type, NULL, 0); + expr_type = make_type("expr", &AST_type, NULL, 0); if (!expr_type) return 0; if (!add_attributes(expr_type, expr_attributes, 2)) return 0; BoolOp_type = make_type("BoolOp", expr_type, BoolOp_fields, 2); @@ -611,7 +708,7 @@ if (!List_type) return 0; Tuple_type = make_type("Tuple", expr_type, Tuple_fields, 2); if (!Tuple_type) return 0; - expr_context_type = make_type("expr_context", AST_type, NULL, 0); + expr_context_type = make_type("expr_context", &AST_type, NULL, 0); if (!expr_context_type) return 0; if (!add_attributes(expr_context_type, NULL, 0)) return 0; Load_type = make_type("Load", expr_context_type, NULL, 0); @@ -638,7 +735,7 @@ if (!Param_type) return 0; Param_singleton = PyType_GenericNew(Param_type, NULL, NULL); if (!Param_singleton) return 0; - slice_type = make_type("slice", AST_type, NULL, 0); + slice_type = make_type("slice", &AST_type, NULL, 0); if (!slice_type) return 0; if (!add_attributes(slice_type, NULL, 0)) return 0; Ellipsis_type = make_type("Ellipsis", slice_type, NULL, 0); @@ -649,7 +746,7 @@ if (!ExtSlice_type) return 0; Index_type = make_type("Index", slice_type, Index_fields, 1); if (!Index_type) return 0; - boolop_type = make_type("boolop", AST_type, NULL, 0); + boolop_type = make_type("boolop", &AST_type, NULL, 0); if (!boolop_type) return 0; if (!add_attributes(boolop_type, NULL, 0)) return 0; And_type = make_type("And", boolop_type, NULL, 0); @@ -660,7 +757,7 @@ if (!Or_type) return 0; Or_singleton = PyType_GenericNew(Or_type, NULL, NULL); if (!Or_singleton) return 0; - operator_type = make_type("operator", AST_type, NULL, 0); + operator_type = make_type("operator", &AST_type, NULL, 0); if (!operator_type) return 0; if (!add_attributes(operator_type, NULL, 0)) return 0; Add_type = make_type("Add", operator_type, NULL, 0); @@ -711,7 +808,7 @@ if (!FloorDiv_type) return 0; FloorDiv_singleton = PyType_GenericNew(FloorDiv_type, NULL, NULL); if (!FloorDiv_singleton) return 0; - unaryop_type = make_type("unaryop", AST_type, NULL, 0); + unaryop_type = make_type("unaryop", &AST_type, NULL, 0); if (!unaryop_type) return 0; if (!add_attributes(unaryop_type, NULL, 0)) return 0; Invert_type = make_type("Invert", unaryop_type, NULL, 0); @@ -730,7 +827,7 @@ if (!USub_type) return 0; USub_singleton = PyType_GenericNew(USub_type, NULL, NULL); if (!USub_singleton) return 0; - cmpop_type = make_type("cmpop", AST_type, NULL, 0); + cmpop_type = make_type("cmpop", &AST_type, NULL, 0); if (!cmpop_type) return 0; if (!add_attributes(cmpop_type, NULL, 0)) return 0; Eq_type = make_type("Eq", cmpop_type, NULL, 0); @@ -773,17 +870,17 @@ if (!NotIn_type) return 0; NotIn_singleton = PyType_GenericNew(NotIn_type, NULL, NULL); if (!NotIn_singleton) return 0; - comprehension_type = make_type("comprehension", AST_type, + comprehension_type = make_type("comprehension", &AST_type, comprehension_fields, 3); if (!comprehension_type) return 0; - excepthandler_type = make_type("excepthandler", AST_type, + excepthandler_type = make_type("excepthandler", &AST_type, excepthandler_fields, 5); if (!excepthandler_type) return 0; - arguments_type = make_type("arguments", AST_type, arguments_fields, 4); + arguments_type = make_type("arguments", &AST_type, arguments_fields, 4); if (!arguments_type) return 0; - keyword_type = make_type("keyword", AST_type, keyword_fields, 2); + keyword_type = make_type("keyword", &AST_type, keyword_fields, 2); if (!keyword_type) return 0; - alias_type = make_type("alias", AST_type, alias_fields, 2); + alias_type = make_type("alias", &AST_type, alias_fields, 2); if (!alias_type) return 0; initialized = 1; return 1; @@ -5790,7 +5887,7 @@ m = Py_InitModule3("_ast", NULL, NULL); if (!m) return; d = PyModule_GetDict(m); - if (PyDict_SetItemString(d, "AST", (PyObject*)AST_type) < 0) return; + if (PyDict_SetItemString(d, "AST", (PyObject*)&AST_type) < 0) return; if (PyModule_AddIntConstant(m, "PyCF_ONLY_AST", PyCF_ONLY_AST) < 0) return; if (PyModule_AddStringConstant(m, "__version__", "60978") < 0) @@ -5969,7 +6066,7 @@ int PyAST_Check(PyObject* obj) { init_types(); - return PyObject_IsInstance(obj, (PyObject*)AST_type); + return PyObject_IsInstance(obj, (PyObject*)&AST_type); } Index: Parser/asdl_c.py =================================================================== --- Parser/asdl_c.py (Revision 62039) +++ Parser/asdl_c.py (Arbeitskopie) @@ -578,6 +578,104 @@ def visitModule(self, mod): self.emit(""" +static int +ast_type_init(PyObject *self, PyObject *args, PyObject *kw) +{ + Py_ssize_t i = 0; + PyObject *key, *value; + if (PyTuple_GET_SIZE(args) > 0) { + PyErr_Format(PyExc_TypeError, + "%.400s object doesn't take positional arguments", + Py_TYPE(self)->tp_name); + return -1; + } + if (!kw) return 0; + while (PyDict_Next(kw, &i, &key, &value)) { + if (PyObject_SetAttr(self, key, value) < 0) + return -1; + } + return 0; +} + +static int +ast_type_setattr(PyObject *self, PyObject *name, PyObject *value) +{ + PyObject *fields = NULL, *attrs = NULL; + int res = -1; + fields = PyObject_GetAttrString((PyObject*)Py_TYPE(self), "_fields"); + if (!fields) + PyErr_Clear(); + attrs = PyObject_GetAttrString((PyObject*)Py_TYPE(self), "_attributes"); + if (!attrs) + PyErr_Clear(); + if (fields && fields != Py_None) { + res = PySequence_Contains(fields, name); + if (res == -1) + goto cleanup; + else if (res == 1) { + res = PyObject_GenericSetAttr(self, name, value); + goto cleanup; + } + } + if (attrs && attrs != Py_None) { + res = PySequence_Contains(attrs, name); + if (res == -1) + goto cleanup; + else if (res == 1) { + res = PyObject_GenericSetAttr(self, name, value); + goto cleanup; + } + } + PyErr_SetObject(PyExc_AttributeError, name); + cleanup: + Py_XDECREF(fields); + Py_XDECREF(attrs); + return res; +} + + +static PyTypeObject AST_type = { + PyVarObject_HEAD_INIT(&PyType_Type, 0) + "AST", + sizeof(PyObject), + 0, + 0, /* tp_dealloc */ + 0, /* tp_print */ + 0, /* tp_getattr */ + 0, /* tp_setattr */ + 0, /* tp_compare */ + 0, /* tp_repr */ + 0, /* tp_as_number */ + 0, /* tp_as_sequence */ + 0, /* tp_as_mapping */ + 0, /* tp_hash */ + 0, /* tp_call */ + 0, /* tp_str */ + PyObject_GenericGetAttr, /* tp_getattro */ + ast_type_setattr, /* tp_setattro */ + 0, /* tp_as_buffer */ + Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */ + 0, /* tp_doc */ + 0, /* tp_traverse */ + 0, /* tp_clear */ + 0, /* tp_richcompare */ + 0, /* tp_weaklistoffset */ + 0, /* tp_iter */ + 0, /* tp_iternext */ + 0, /* tp_methods */ + 0, /* tp_members */ + 0, /* tp_getset */ + 0, /* tp_base */ + 0, /* tp_dict */ + 0, /* tp_descr_get */ + 0, /* tp_descr_set */ + 0, /* tp_dictoffset */ + (initproc)ast_type_init, /* tp_init */ + PyType_GenericAlloc, /* tp_alloc */ + PyType_GenericNew, /* tp_new */ + PyObject_Del, /* tp_free */ +}; + static PyTypeObject* make_type(char *type, PyTypeObject* base, char**fields, int num_fields) { PyObject *fnames, *result; @@ -606,7 +704,7 @@ static int add_attributes(PyTypeObject* type, char**attrs, int num_fields) { int i, result; - PyObject *s, *l = PyList_New(num_fields); + PyObject *s, *l = PyTuple_New(num_fields); if (!l) return 0; for(i = 0; i < num_fields; i++) { s = PyString_FromString(attrs[i]); @@ -614,7 +712,7 @@ Py_DECREF(l); return 0; } - PyList_SET_ITEM(l, i, s); + PyTuple_SET_ITEM(l, i, s); } result = PyObject_SetAttrString((PyObject*)type, "_attributes", l) >= 0; Py_DECREF(l); @@ -716,7 +814,6 @@ self.emit("{", 0) self.emit("static int initialized;", 1) self.emit("if (initialized) return 1;", 1) - self.emit('AST_type = make_type("AST", &PyBaseObject_Type, NULL, 0);', 1) for dfn in mod.dfns: self.visit(dfn) self.emit("initialized = 1;", 1) @@ -728,12 +825,13 @@ fields = name.value+"_fields" else: fields = "NULL" - self.emit('%s_type = make_type("%s", AST_type, %s, %d);' % + self.emit('%s_type = make_type("%s", &AST_type, %s, %d);' % (name, name, fields, len(prod.fields)), 1) self.emit("if (!%s_type) return 0;" % name, 1) def visitSum(self, sum, name): - self.emit('%s_type = make_type("%s", AST_type, NULL, 0);' % (name, name), 1) + self.emit('%s_type = make_type("%s", &AST_type, NULL, 0);' % + (name, name), 1) self.emit("if (!%s_type) return 0;" % name, 1) if sum.attributes: self.emit("if (!add_attributes(%s_type, %s_attributes, %d)) return 0;" % @@ -772,7 +870,7 @@ self.emit('m = Py_InitModule3("_ast", NULL, NULL);', 1) self.emit("if (!m) return;", 1) self.emit("d = PyModule_GetDict(m);", 1) - self.emit('if (PyDict_SetItemString(d, "AST", (PyObject*)AST_type) < 0) return;', 1) + self.emit('if (PyDict_SetItemString(d, "AST", (PyObject*)&AST_type) < 0) return;', 1) self.emit('if (PyModule_AddIntConstant(m, "PyCF_ONLY_AST", PyCF_ONLY_AST) < 0)', 1) self.emit("return;", 2) # Value of version: "$Revision$" @@ -979,7 +1077,7 @@ int PyAST_Check(PyObject* obj) { init_types(); - return PyObject_IsInstance(obj, (PyObject*)AST_type); + return PyObject_IsInstance(obj, (PyObject*)&AST_type); } """ @@ -1035,7 +1133,7 @@ print >> f, '#include "Python.h"' print >> f, '#include "%s-ast.h"' % mod.name print >> f - print >>f, "static PyTypeObject* AST_type;" + print >>f, "static PyTypeObject AST_type;" v = ChainOfVisitors( PyTypesDeclareVisitor(f), PyTypesVisitor(f),