[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