[Zope3-checkins] CVS: Zope3/lib/python/Persistence - cPersistence.c:1.23
Jeremy Hylton
jeremy@zope.com
Thu, 10 Oct 2002 17:54:42 -0400
Update of /cvs-repository/Zope3/lib/python/Persistence
In directory cvs.zope.org:/tmp/cvs-serv24581
Modified Files:
cPersistence.c
Log Message:
Only use a custom metaclass for Python 2.2.
If the code is compiled with other versions of Python, make
PersistentMetaClass an alias for type.
=== Zope3/lib/python/Persistence/cPersistence.c 1.22 => 1.23 ===
--- Zope3/lib/python/Persistence/cPersistence.c:1.22 Thu Oct 10 17:36:18 2002
+++ Zope3/lib/python/Persistence/cPersistence.c Thu Oct 10 17:54:42 2002
@@ -20,7 +20,12 @@
"\n"
"$Id$\n";
+/* A custom metaclass is only needed to support Python 2.2. */
+#if PY_MAJOR_VERSION == 2 && PY_MINOR_VERSION == 2
static PyTypeObject PyPersist_MetaType;
+#else
+#define PyPersist_MetaType PyType_Type
+#endif
/* Python version of the simple_new function; */
static PyObject *py_simple_new = NULL;
@@ -666,37 +671,6 @@
*/
#define DEFERRED_ADDRESS(ADDR) 0
-/* Make persistent objects work with Python 2.2.
-
- The rules for deciding whether to give an object an __dict__ or an
- __weakref__ are different in 2.2 than in later versions of Python.
- In particular, an object will not get an __dict__ if it has a
- custom setattr.
-*/
-
-static PyObject *
-persist_dict(PyObject *obj, void *context)
-{
- PyObject **dictptr;
-
- dictptr = _PyObject_GetDictPtr(obj);
- assert(dictptr);
-
- if (!*dictptr) {
- PyObject *dict = PyDict_New();
- if (!dict)
- return NULL;
- *dictptr = dict;
- }
- Py_INCREF(*dictptr);
- return *dictptr;
-}
-
-static PyGetSetDef persist_meta_getsets[] = {
- {"__dict__", (getter)persist_dict, NULL, NULL},
- {NULL}
-};
-
static PyTypeObject PyPersist_Type = {
PyObject_HEAD_INIT(&PyPersist_MetaType)
0, /* ob_size */
@@ -740,20 +714,44 @@
0, /* tp_new */
};
-/* PyPersist_New is the tp_new of PersistentMetaClass, which exists
- only for compatibility with Python 2.2.
-
- This new function must determine whether to create an __dict__.
- XXX In the future, it might also handle __weakref__.
+#if PY_MAJOR_VERSION == 2 && PY_MINOR_VERSION == 2
- Python 2.2 and 2.3 have fairly different rules for whether an
- instance should get a dict. The 2.3 rules will often create an
- __dict__; we don't want to emulate that functionality because it
- would make persistent classes different from non-persistent
- new-style classes.
+/* PyPersist_MetaType / PersistentMetaClass exists to work around
+ problems with the way Python 2.2 determines whether a class's
+ instances will get an __dict__, or, more concretely, what the value
+ of tp_dictoffset should be.
+
+ The metaclass uses a custom tp_alloc function PyPersist_Alloc() to
+ set tp_dictoffset to -1. This assignment prevents type_new() from
+ doing anything with dictoffset. Later the metaclass tp_new
+ function PyPersist_New() assigns a reasonable value for
+ tp_dictoffset and creates an __dict__ descriptor.
*/
static PyObject *
+persist_dict(PyObject *obj, void *context)
+{
+ PyObject **dictptr;
+
+ dictptr = _PyObject_GetDictPtr(obj);
+ assert(dictptr);
+
+ if (!*dictptr) {
+ PyObject *dict = PyDict_New();
+ if (!dict)
+ return NULL;
+ *dictptr = dict;
+ }
+ Py_INCREF(*dictptr);
+ return *dictptr;
+}
+
+static PyGetSetDef persist_meta_getsets[] = {
+ {"__dict__", (getter)persist_dict, NULL, NULL},
+ {NULL}
+};
+
+static PyObject *
PyPersist_Alloc(PyTypeObject *metatype, int nitems)
{
PyObject *type = PyType_GenericAlloc(metatype, nitems);
@@ -811,6 +809,8 @@
"Persistence.PersistentMetaClass", /* tp_name */
};
+#endif
+
static PyObject *
simple_new(PyObject *self, PyObject *type_object)
{
@@ -875,9 +875,15 @@
{
PyObject *m, *d, *v;
- /* It's easier to initialize a few fields by assignment than to
- fill out the entire type structure in an initializer.
- */
+ m = Py_InitModule3("cPersistence", PyPersist_methods,
+ PyPersist_doc_string);
+ if (m == NULL)
+ return;
+ d = PyModule_GetDict(m);
+ if (d == NULL)
+ return;
+
+#if PY_MAJOR_VERSION == 2 && PY_MINOR_VERSION == 2
PyPersist_MetaType.ob_type = &PyType_Type;
PyPersist_MetaType.tp_alloc = PyPersist_Alloc;
PyPersist_MetaType.tp_new = PyPersist_New;
@@ -888,27 +894,26 @@
PyPersist_MetaType.tp_clear = PyType_Type.tp_clear;
if (PyType_Ready(&PyPersist_MetaType) < 0)
return;
+ Py_INCREF(&PyPersist_MetaType);
+ if (PyDict_SetItemString(d, "PersistentMetaClass",
+ (PyObject *)&PyPersist_MetaType) < 0)
+ return;
+#else
+ Py_INCREF(&PyType_Type);
+ if (PyDict_SetItemString(d, "PersistentMetaClass",
+ (PyObject *)&PyType_Type) < 0)
+ return;
+#endif
+ PyPersist_Type.ob_type = &PyPersist_MetaType;
PyPersist_Type.tp_new = PyType_GenericNew;
if (PyType_Ready(&PyPersist_Type) < 0)
return;
if (persist_set_interface(&PyPersist_Type) < 0)
return;
- m = Py_InitModule3("cPersistence", PyPersist_methods,
- PyPersist_doc_string);
- if (m == NULL)
- return;
- d = PyModule_GetDict(m);
- if (d == NULL)
- return;
-
Py_INCREF(&PyPersist_Type);
if (PyDict_SetItemString(d, "Persistent", (PyObject *)&PyPersist_Type) < 0)
- return;
- Py_INCREF(&PyPersist_MetaType);
- if (PyDict_SetItemString(d, "PersistentMetaClass",
- (PyObject *)&PyPersist_MetaType) < 0)
return;
v = PyCObject_FromVoidPtr(&c_api, NULL);