@@ -578,6 +578,98 @@ class PyTypesVisitor(PickleVisitor):
578578
579579 def visitModule (self , mod ):
580580 self .emit ("""
581+ static int
582+ ast_type_init(PyObject *self, PyObject *args, PyObject *kw)
583+ {
584+ Py_ssize_t i, numfields = 0;
585+ int res = -1;
586+ PyObject *key, *value, *fields;
587+ fields = PyObject_GetAttrString((PyObject*)Py_TYPE(self), "_fields");
588+ if (!fields)
589+ PyErr_Clear();
590+ if (fields) {
591+ numfields = PySequence_Size(fields);
592+ if (numfields == -1)
593+ goto cleanup;
594+ }
595+ res = 0; /* if no error occurs, this stays 0 to the end */
596+ if (PyTuple_GET_SIZE(args) > 0) {
597+ if (numfields != PyTuple_GET_SIZE(args)) {
598+ PyErr_Format(PyExc_TypeError, "%.400s constructor takes either 0 or "
599+ "%d positional argument%s", Py_TYPE(self)->tp_name,
600+ numfields, numfields == 1 ? "" : "s");
601+ res = -1;
602+ goto cleanup;
603+ }
604+ for (i = 0; i < PyTuple_GET_SIZE(args); i++) {
605+ /* cannot be reached when fields is NULL */
606+ PyObject *name = PySequence_GetItem(fields, i);
607+ if (!name) {
608+ res = -1;
609+ goto cleanup;
610+ }
611+ res = PyObject_SetAttr(self, name, PyTuple_GET_ITEM(args, i));
612+ Py_DECREF(name);
613+ if (res < 0)
614+ goto cleanup;
615+ }
616+ }
617+ if (kw) {
618+ i = 0; /* needed by PyDict_Next */
619+ while (PyDict_Next(kw, &i, &key, &value)) {
620+ res = PyObject_SetAttr(self, key, value);
621+ if (res < 0)
622+ goto cleanup;
623+ }
624+ }
625+ cleanup:
626+ Py_XDECREF(fields);
627+ return res;
628+ }
629+
630+ static PyTypeObject AST_type = {
631+ PyVarObject_HEAD_INIT(&PyType_Type, 0)
632+ "AST",
633+ sizeof(PyObject),
634+ 0,
635+ 0, /* tp_dealloc */
636+ 0, /* tp_print */
637+ 0, /* tp_getattr */
638+ 0, /* tp_setattr */
639+ 0, /* tp_compare */
640+ 0, /* tp_repr */
641+ 0, /* tp_as_number */
642+ 0, /* tp_as_sequence */
643+ 0, /* tp_as_mapping */
644+ 0, /* tp_hash */
645+ 0, /* tp_call */
646+ 0, /* tp_str */
647+ PyObject_GenericGetAttr, /* tp_getattro */
648+ PyObject_GenericSetAttr, /* tp_setattro */
649+ 0, /* tp_as_buffer */
650+ Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */
651+ 0, /* tp_doc */
652+ 0, /* tp_traverse */
653+ 0, /* tp_clear */
654+ 0, /* tp_richcompare */
655+ 0, /* tp_weaklistoffset */
656+ 0, /* tp_iter */
657+ 0, /* tp_iternext */
658+ 0, /* tp_methods */
659+ 0, /* tp_members */
660+ 0, /* tp_getset */
661+ 0, /* tp_base */
662+ 0, /* tp_dict */
663+ 0, /* tp_descr_get */
664+ 0, /* tp_descr_set */
665+ 0, /* tp_dictoffset */
666+ (initproc)ast_type_init, /* tp_init */
667+ PyType_GenericAlloc, /* tp_alloc */
668+ PyType_GenericNew, /* tp_new */
669+ PyObject_Del, /* tp_free */
670+ };
671+
672+
581673static PyTypeObject* make_type(char *type, PyTypeObject* base, char**fields, int num_fields)
582674{
583675 PyObject *fnames, *result;
@@ -606,15 +698,15 @@ def visitModule(self, mod):
606698static int add_attributes(PyTypeObject* type, char**attrs, int num_fields)
607699{
608700 int i, result;
609- PyObject *s, *l = PyList_New (num_fields);
701+ PyObject *s, *l = PyTuple_New (num_fields);
610702 if (!l) return 0;
611703 for(i = 0; i < num_fields; i++) {
612704 s = PyString_FromString(attrs[i]);
613705 if (!s) {
614706 Py_DECREF(l);
615707 return 0;
616708 }
617- PyList_SET_ITEM (l, i, s);
709+ PyTuple_SET_ITEM (l, i, s);
618710 }
619711 result = PyObject_SetAttrString((PyObject*)type, "_attributes", l) >= 0;
620712 Py_DECREF(l);
@@ -716,7 +808,6 @@ def visitModule(self, mod):
716808 self .emit ("{" , 0 )
717809 self .emit ("static int initialized;" , 1 )
718810 self .emit ("if (initialized) return 1;" , 1 )
719- self .emit ('AST_type = make_type("AST", &PyBaseObject_Type, NULL, 0);' , 1 )
720811 for dfn in mod .dfns :
721812 self .visit (dfn )
722813 self .emit ("initialized = 1;" , 1 )
@@ -728,12 +819,13 @@ def visitProduct(self, prod, name):
728819 fields = name .value + "_fields"
729820 else :
730821 fields = "NULL"
731- self .emit ('%s_type = make_type("%s", AST_type, %s, %d);' %
822+ self .emit ('%s_type = make_type("%s", & AST_type, %s, %d);' %
732823 (name , name , fields , len (prod .fields )), 1 )
733824 self .emit ("if (!%s_type) return 0;" % name , 1 )
734825
735826 def visitSum (self , sum , name ):
736- self .emit ('%s_type = make_type("%s", AST_type, NULL, 0);' % (name , name ), 1 )
827+ self .emit ('%s_type = make_type("%s", &AST_type, NULL, 0);' %
828+ (name , name ), 1 )
737829 self .emit ("if (!%s_type) return 0;" % name , 1 )
738830 if sum .attributes :
739831 self .emit ("if (!add_attributes(%s_type, %s_attributes, %d)) return 0;" %
@@ -772,7 +864,7 @@ def visitModule(self, mod):
772864 self .emit ('m = Py_InitModule3("_ast", NULL, NULL);' , 1 )
773865 self .emit ("if (!m) return;" , 1 )
774866 self .emit ("d = PyModule_GetDict(m);" , 1 )
775- self .emit ('if (PyDict_SetItemString(d, "AST", (PyObject*)AST_type) < 0) return;' , 1 )
867+ self .emit ('if (PyDict_SetItemString(d, "AST", (PyObject*)& AST_type) < 0) return;' , 1 )
776868 self .emit ('if (PyModule_AddIntConstant(m, "PyCF_ONLY_AST", PyCF_ONLY_AST) < 0)' , 1 )
777869 self .emit ("return;" , 2 )
778870 # Value of version: "$Revision$"
@@ -979,7 +1071,7 @@ class PartingShots(StaticVisitor):
9791071int PyAST_Check(PyObject* obj)
9801072{
9811073 init_types();
982- return PyObject_IsInstance(obj, (PyObject*)AST_type);
1074+ return PyObject_IsInstance(obj, (PyObject*)& AST_type);
9831075}
9841076"""
9851077
@@ -1035,7 +1127,7 @@ def main(srcfile):
10351127 print >> f , '#include "Python.h"'
10361128 print >> f , '#include "%s-ast.h"' % mod .name
10371129 print >> f
1038- print >> f , "static PyTypeObject* AST_type;"
1130+ print >> f , "static PyTypeObject AST_type;"
10391131 v = ChainOfVisitors (
10401132 PyTypesDeclareVisitor (f ),
10411133 PyTypesVisitor (f ),
0 commit comments