[Python-Dev] Good news about ExtensionClass and Python 2.2a1

Neil Schemenauer nascheme@mems-exchange.org
Tue, 31 Jul 2001 13:54:57 -0400


After a few tweaks to ExtensionClass and a few small fixes to some of
our introspection code I'm happy to say that Python 2.2a1 passes our
unit test suite.  This is significant since there are about 45000 lines
of code (counted by "wc -l") tested by 3569 test cases.  Since we use
ZODB ExtensionClasses are quite widely used.  Merging descr_branch into
HEAD sounds like a good idea to me.  Well done Guido.

I'm going to spend a bit of time trying to rewrite the ZODB Persistent
class as a type.  Attached is a diff of the changes I made to
ExtensionClass.

  Neil

--- ExtensionClass.h.dist	Tue Jul 31 11:50:39 2001
+++ ExtensionClass.h	Tue Jul 31 12:15:21 2001
@@ -143,12 +143,48 @@
 	reprfunc tp_str;
 	getattrofunc tp_getattro;
 	setattrofunc tp_setattro;
-	/* Space for future expansion */
-	long tp_xxx3;
-	long tp_xxx4;
+
+	/* Functions to access object as input/output buffer */
+	PyBufferProcs *tp_as_buffer;
+
+	/* Flags to define presence of optional/expanded features */
+	long tp_flags;
 
 	char *tp_doc; /* Documentation string */
 
+	/* call function for all accessible objects */
+	traverseproc tp_traverse;
+	
+	/* delete references to contained objects */
+	inquiry tp_clear;
+
+	/* rich comparisons */
+	richcmpfunc tp_richcompare;
+
+	/* weak reference enabler */
+	long tp_weaklistoffset;
+
+	/* Iterators */
+	getiterfunc tp_iter;
+	iternextfunc tp_iternext;
+
+	/* Attribute descriptor and subclassing stuff */
+	struct PyMethodDef *tp_methods;
+	struct memberlist *tp_members;
+	struct getsetlist *tp_getset;
+	struct _typeobject *tp_base;
+	PyObject *tp_dict;
+	descrgetfunc tp_descr_get;
+	descrsetfunc tp_descr_set;
+	long tp_dictoffset;
+	initproc tp_init;
+	allocfunc tp_alloc;
+	newfunc tp_new;
+	destructor tp_free; /* Low-level free-memory routine */
+	PyObject *tp_bases;
+	PyObject *tp_mro; /* method resolution order */
+	PyObject *tp_defined;
+
 #ifdef COUNT_ALLOCS
 	/* these must be last */
 	int tp_alloc;
@@ -302,7 +338,9 @@
    { PyExtensionClassCAPI->Export(D,N,&T); }
 
 /* Convert a method list to a method chain.  */
-#define METHOD_CHAIN(DEF) { DEF, NULL }
+#define METHOD_CHAIN(DEF) \
+	0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, \
+	{ DEF, NULL }
 
 /* The following macro checks whether a type is an extension class: */
 #define PyExtensionClass_Check(TYPE) \
@@ -336,7 +374,9 @@
 #define PURE_MIXIN_CLASS(NAME,DOC,METHODS) \
 static PyExtensionClass NAME ## Type = { PyObject_HEAD_INIT(NULL) \
 	0, # NAME, sizeof(PyPureMixinObject), 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, \
-	0, 0, 0, 0, 0, 0, 0, DOC, {METHODS, NULL}, \
+	0, 0, 0, 0, 0, 0, 0, DOC, \
+	0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, \
+	{METHODS, NULL}, \
         EXTENSIONCLASS_BASICNEW_FLAG}
 
 /* The following macros provide limited access to extension-class
--- ExtensionClass.c.dist	Tue Jul 31 11:01:20 2001
+++ ExtensionClass.c	Tue Jul 31 12:15:24 2001
@@ -119,7 +119,7 @@
 static PyObject *subclass_watcher=0;  /* Object that subclass events */
 
 static void
-init_py_names()
+init_py_names(void)
 {
 #define INIT_PY_NAME(N) py ## N = PyString_FromString(#N)
   INIT_PY_NAME(__add__);
@@ -1800,8 +1800,8 @@
 
   if (PyFunction_Check(r) || NeedsToBeBound(r))
     ASSIGN(r,newPMethod(self,r));
-  else if (PyMethod_Check(r) && ! PyMethod_Self(r))
-    ASSIGN(r,newPMethod(self, PyMethod_Function(r)));
+  else if (PyMethod_Check(r) && ! PyMethod_GET_SELF(r))
+    ASSIGN(r,newPMethod(self, PyMethod_GET_FUNCTION(r)));
 
   return r;
 }
@@ -3527,7 +3527,7 @@
 };
 
 void
-initExtensionClass()
+initExtensionClass(void)
 {
   PyObject *m, *d;
   char *rev="$Revision: 1.1 $";