[Checkins] SVN: ExtensionClass/trunk/ Added support for method cache in ExtensionClass. Patch contributed by Yoshinori K. Okuji. See LP #486182.

Hanno Schlichting hannosch at hannosch.eu
Sun Feb 14 16:35:34 EST 2010


Log message for revision 109054:
  Added support for method cache in ExtensionClass. Patch contributed by Yoshinori K. Okuji. See LP #486182.
  

Changed:
  U   ExtensionClass/trunk/CHANGES.txt
  U   ExtensionClass/trunk/src/ExtensionClass/_ExtensionClass.c

-=-
Modified: ExtensionClass/trunk/CHANGES.txt
===================================================================
--- ExtensionClass/trunk/CHANGES.txt	2010-02-14 18:53:26 UTC (rev 109053)
+++ ExtensionClass/trunk/CHANGES.txt	2010-02-14 21:35:34 UTC (rev 109054)
@@ -1,10 +1,11 @@
 ExtensionClass Changelog
 ========================
 
-2.11.4 (unreleased)
+2.12.0 (unreleased)
 -------------------
 
-- TBD
+- Added support for method cache in ExtensionClass. Patch contributed by
+  Yoshinori K. Okuji. See https://bugs.launchpad.net/zope2/+bug/486182.
 
 
 2.11.3 (2009-08-02)

Modified: ExtensionClass/trunk/src/ExtensionClass/_ExtensionClass.c
===================================================================
--- ExtensionClass/trunk/src/ExtensionClass/_ExtensionClass.c	2010-02-14 18:53:26 UTC (rev 109053)
+++ ExtensionClass/trunk/src/ExtensionClass/_ExtensionClass.c	2010-02-14 21:35:34 UTC (rev 109054)
@@ -18,7 +18,6 @@
 ;
 
 #include "ExtensionClass/ExtensionClass.h"
-
 #define EC PyTypeObject
 
 static PyObject *str__of__, *str__get__, *str__class_init__, *str__init__;
@@ -80,7 +79,9 @@
 			goto done;
 	}
 
+#if !defined(Py_TPFLAGS_HAVE_VERSION_TAG)
 	/* Inline _PyType_Lookup */
+	/* this is not quite _PyType_Lookup anymore */
 	{
 		int i, n;
 		PyObject *mro, *base, *dict;
@@ -104,13 +105,19 @@
 				break;
 		}
 	}
+#else
+    descr = _PyType_Lookup(tp, name);
+#endif
 
+    Py_XINCREF(descr);
+
 	f = NULL;
 	if (descr != NULL &&
 	    PyType_HasFeature(descr->ob_type, Py_TPFLAGS_HAVE_CLASS)) {
 		f = descr->ob_type->tp_descr_get;
 		if (f != NULL && PyDescr_IsData(descr)) {
 			res = f(descr, obj, (PyObject *)obj->ob_type);
+            Py_DECREF(descr);
 			goto done;
 		}
 	}
@@ -135,8 +142,12 @@
 		dictptr = (PyObject **) ((char *)obj + dictoffset);
 		dict = *dictptr;
 		if (dict != NULL) {
+			Py_INCREF(dict);
 			res = PyDict_GetItem(dict, name);
 			if (res != NULL) {
+				Py_INCREF(res);
+				Py_XDECREF(descr);
+				Py_DECREF(dict);
 
                           /* CHANGED!
                              If the tp_descr_get of res is of_get, 
@@ -144,25 +155,29 @@
 
                           if (PyObject_TypeCheck(res->ob_type,
                                                  &ExtensionClassType)
-                              && res->ob_type->tp_descr_get != NULL)
-                            res = res->ob_type->tp_descr_get(
+                              && res->ob_type->tp_descr_get != NULL) {
+                            PyObject *tres;
+                            tres = res->ob_type->tp_descr_get(
                                                  res, obj, 
                                                  OBJECT(obj->ob_type));
-                          else
-                            Py_INCREF(res);
+                            Py_DECREF(res);
+                            res = tres;
+                          }
                           goto done;
 			}
+			Py_DECREF(dict);
 		}
 	}
 
 	if (f != NULL) {
 		res = f(descr, obj, (PyObject *)obj->ob_type);
+		Py_DECREF(descr);
 		goto done;
 	}
 
 	if (descr != NULL) {
-		Py_INCREF(descr);
 		res = descr;
+        /* descr was already increfed above */
 		goto done;
 	}
 
@@ -189,7 +204,11 @@
         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
         /* tp_getattro       */ (getattrofunc)Base_getattro,
         0, 0,
-        Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE,
+        (Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE
+#ifdef Py_TPFLAGS_HAVE_VERSION_TAG
+         | Py_TPFLAGS_HAVE_VERSION_TAG
+#endif
+        ),
 	"Standard ExtensionClass base type",
         0, 0, 0, 0, 0, 0, 
         Base_methods,
@@ -201,7 +220,11 @@
 	/* tp_name           */ "ExtensionClass."
                                 "NoInstanceDictionaryBase",
         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-        Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE,
+        (Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE
+#ifdef Py_TPFLAGS_HAVE_VERSION_TAG
+         | Py_TPFLAGS_HAVE_VERSION_TAG
+#endif
+        ),
 	"Base types for subclasses without instance dictionaries",
 };
 
@@ -424,9 +447,15 @@
             }
         }
       
-      return PyObject_GenericSetAttr(OBJECT(type), name, value);
+      if (PyObject_GenericSetAttr(OBJECT(type), name, value) < 0)
+        return -1;
     }
-  return PyType_Type.tp_setattro(OBJECT(type), name, value);
+  else if (PyType_Type.tp_setattro(OBJECT(type), name, value) < 0)
+    return -1;
+#ifdef Py_TPFLAGS_HAVE_VERSION_TAG
+  PyType_Modified(type);
+#endif
+  return 0;
 }
 
 
@@ -621,6 +650,9 @@
         /* tp_flags          */ Py_TPFLAGS_DEFAULT
                                 | Py_TPFLAGS_HAVE_GC
                                 | Py_TPFLAGS_BASETYPE
+#ifdef Py_TPFLAGS_HAVE_VERSION_TAG
+                                | Py_TPFLAGS_HAVE_VERSION_TAG
+#endif
                                 ,
 	/* tp_doc            */ "Meta-class for extension classes",
         /* tp_traverse       */ (traverseproc)0,
@@ -812,6 +844,9 @@
               < 0)
             return -1;
         }      
+#ifdef Py_TPFLAGS_HAVE_VERSION_TAG
+      PyType_Modified(typ);
+#endif
     }
   else if (mdef && mdef->ml_name)
     {
@@ -824,6 +859,9 @@
         return -1;
       if (PyDict_SetItemString(typ->tp_dict, mdef->ml_name, m) < 0)
         return -1;
+#ifdef Py_TPFLAGS_HAVE_VERSION_TAG
+      PyType_Modified(typ);
+#endif
     }
 
   if (PyMapping_SetItemString(dict, name, (PyObject*)typ) < 0)  



More information about the checkins mailing list