@@ -577,6 +577,100 @@ class PyTypesVisitor(PickleVisitor):
577577
578578 def visitModule (self , mod ):
579579 self .emit ("""
580+ static int
581+ ast_type_init(PyObject *self, PyObject *args, PyObject *kw)
582+ {
583+ Py_ssize_t i, numfields = 0;
584+ int res = -1;
585+ PyObject *key, *value, *fields;
586+ fields = PyObject_GetAttrString((PyObject*)Py_TYPE(self), "_fields");
587+ if (!fields)
588+ PyErr_Clear();
589+ if (fields) {
590+ numfields = PySequence_Size(fields);
591+ if (numfields == -1)
592+ goto cleanup;
593+ }
594+ res = 0; /* if no error occurs, this stays 0 to the end */
595+ if (PyTuple_GET_SIZE(args) > 0) {
596+ if (numfields != PyTuple_GET_SIZE(args)) {
597+ PyErr_Format(PyExc_TypeError, "%.400s constructor takes %s"
598+ "%" PY_FORMAT_SIZE_T "d positional argument%s",
599+ Py_TYPE(self)->tp_name,
600+ numfields == 0 ? "" : "either 0 or ",
601+ numfields, numfields == 1 ? "" : "s");
602+ res = -1;
603+ goto cleanup;
604+ }
605+ for (i = 0; i < PyTuple_GET_SIZE(args); i++) {
606+ /* cannot be reached when fields is NULL */
607+ PyObject *name = PySequence_GetItem(fields, i);
608+ if (!name) {
609+ res = -1;
610+ goto cleanup;
611+ }
612+ res = PyObject_SetAttr(self, name, PyTuple_GET_ITEM(args, i));
613+ Py_DECREF(name);
614+ if (res < 0)
615+ goto cleanup;
616+ }
617+ }
618+ if (kw) {
619+ i = 0; /* needed by PyDict_Next */
620+ while (PyDict_Next(kw, &i, &key, &value)) {
621+ res = PyObject_SetAttr(self, key, value);
622+ if (res < 0)
623+ goto cleanup;
624+ }
625+ }
626+ cleanup:
627+ Py_XDECREF(fields);
628+ return res;
629+ }
630+
631+ static PyTypeObject AST_type = {
632+ PyVarObject_HEAD_INIT(&PyType_Type, 0)
633+ "AST",
634+ sizeof(PyObject),
635+ 0,
636+ 0, /* tp_dealloc */
637+ 0, /* tp_print */
638+ 0, /* tp_getattr */
639+ 0, /* tp_setattr */
640+ 0, /* tp_compare */
641+ 0, /* tp_repr */
642+ 0, /* tp_as_number */
643+ 0, /* tp_as_sequence */
644+ 0, /* tp_as_mapping */
645+ 0, /* tp_hash */
646+ 0, /* tp_call */
647+ 0, /* tp_str */
648+ PyObject_GenericGetAttr, /* tp_getattro */
649+ PyObject_GenericSetAttr, /* tp_setattro */
650+ 0, /* tp_as_buffer */
651+ Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */
652+ 0, /* tp_doc */
653+ 0, /* tp_traverse */
654+ 0, /* tp_clear */
655+ 0, /* tp_richcompare */
656+ 0, /* tp_weaklistoffset */
657+ 0, /* tp_iter */
658+ 0, /* tp_iternext */
659+ 0, /* tp_methods */
660+ 0, /* tp_members */
661+ 0, /* tp_getset */
662+ 0, /* tp_base */
663+ 0, /* tp_dict */
664+ 0, /* tp_descr_get */
665+ 0, /* tp_descr_set */
666+ 0, /* tp_dictoffset */
667+ (initproc)ast_type_init, /* tp_init */
668+ PyType_GenericAlloc, /* tp_alloc */
669+ PyType_GenericNew, /* tp_new */
670+ PyObject_Del, /* tp_free */
671+ };
672+
673+
580674static PyTypeObject* make_type(char *type, PyTypeObject* base, char**fields, int num_fields)
581675{
582676 PyObject *fnames, *result;
@@ -605,15 +699,15 @@ def visitModule(self, mod):
605699static int add_attributes(PyTypeObject* type, char**attrs, int num_fields)
606700{
607701 int i, result;
608- PyObject *s, *l = PyList_New (num_fields);
702+ PyObject *s, *l = PyTuple_New (num_fields);
609703 if (!l) return 0;
610704 for(i = 0; i < num_fields; i++) {
611705 s = PyUnicode_FromString(attrs[i]);
612706 if (!s) {
613707 Py_DECREF(l);
614708 return 0;
615709 }
616- PyList_SET_ITEM (l, i, s);
710+ PyTuple_SET_ITEM (l, i, s);
617711 }
618712 result = PyObject_SetAttrString((PyObject*)type, "_attributes", l) >= 0;
619713 Py_DECREF(l);
@@ -696,7 +790,6 @@ def visitModule(self, mod):
696790 self .emit ("{" , 0 )
697791 self .emit ("static int initialized;" , 1 )
698792 self .emit ("if (initialized) return 1;" , 1 )
699- self .emit ('AST_type = make_type("AST", &PyBaseObject_Type, NULL, 0);' , 1 )
700793 for dfn in mod .dfns :
701794 self .visit (dfn )
702795 self .emit ("initialized = 1;" , 1 )
@@ -708,12 +801,13 @@ def visitProduct(self, prod, name):
708801 fields = name .value + "_fields"
709802 else :
710803 fields = "NULL"
711- self .emit ('%s_type = make_type("%s", AST_type, %s, %d);' %
804+ self .emit ('%s_type = make_type("%s", & AST_type, %s, %d);' %
712805 (name , name , fields , len (prod .fields )), 1 )
713806 self .emit ("if (!%s_type) return 0;" % name , 1 )
714807
715808 def visitSum (self , sum , name ):
716- self .emit ('%s_type = make_type("%s", AST_type, NULL, 0);' % (name , name ), 1 )
809+ self .emit ('%s_type = make_type("%s", &AST_type, NULL, 0);' %
810+ (name , name ), 1 )
717811 self .emit ("if (!%s_type) return 0;" % name , 1 )
718812 if sum .attributes :
719813 self .emit ("if (!add_attributes(%s_type, %s_attributes, %d)) return 0;" %
@@ -752,7 +846,7 @@ def visitModule(self, mod):
752846 self .emit ('m = Py_InitModule3("_ast", NULL, NULL);' , 1 )
753847 self .emit ("if (!m) return;" , 1 )
754848 self .emit ("d = PyModule_GetDict(m);" , 1 )
755- self .emit ('if (PyDict_SetItemString(d, "AST", (PyObject*)AST_type) < 0) return;' , 1 )
849+ self .emit ('if (PyDict_SetItemString(d, "AST", (PyObject*)& AST_type) < 0) return;' , 1 )
756850 self .emit ('if (PyModule_AddIntConstant(m, "PyCF_ONLY_AST", PyCF_ONLY_AST) < 0)' , 1 )
757851 self .emit ("return;" , 2 )
758852 # Value of version: "$Revision$"
@@ -959,7 +1053,7 @@ class PartingShots(StaticVisitor):
9591053int PyAST_Check(PyObject* obj)
9601054{
9611055 init_types();
962- return PyObject_IsInstance(obj, (PyObject*)AST_type);
1056+ return PyObject_IsInstance(obj, (PyObject*)& AST_type);
9631057}
9641058"""
9651059
@@ -1016,7 +1110,7 @@ def main(srcfile):
10161110 f .write ('#include "Python.h"\n ' )
10171111 f .write ('#include "%s-ast.h"\n ' % mod .name )
10181112 f .write ('\n ' )
1019- f .write ("static PyTypeObject* AST_type;\n " )
1113+ f .write ("static PyTypeObject AST_type;\n " )
10201114 v = ChainOfVisitors (
10211115 PyTypesDeclareVisitor (f ),
10221116 PyTypesVisitor (f ),
0 commit comments