[Zope-CVS] CVS: Packages/ContextWrapper - wrapper.c:1.9

Fred Drake Jr fdrake@acm.org
Fri, 16 Nov 2001 11:35:32 -0500


Update of /cvs-repository/Packages/ContextWrapper
In directory cvs.zope.org:/tmp/cvs-serv11133

Modified Files:
	wrapper.c 
Log Message:
Add proxy support for most of the slots defined in the type.
The wrappers are very simple, and the numeric slots are not implemented
(probably OK for this case; there are specific reasons for not doing this
that I need to document).


=== Packages/ContextWrapper/wrapper.c 1.8 => 1.9 ===
 #include "wrapper.h"
 
+#define Wrapper_Check(wrapper) \
+        (((wrapper)->ob_type == &WrapperType) \
+         || (PyObject_TypeCheck(wrapper, &WrapperType)))
+
+#define Wrapper_GetObject(wrapper) \
+        (((WrapperObject *)wrapper)->wrap_object)
+
+#define Wrapper_GetContext(wrapper) \
+        (((WrapperObject *)wrapper)->wrap_context)
+
+#define Wrapper_GetDict(wrapper) \
+        (((WrapperObject *)wrapper)->wrap_dict)
+
 
 static PyObject *
 empty_tuple = NULL;
 
+
+#define WRAP_UNARY(method, generic) \
+    static PyObject * \
+    method(PyObject *wrapper) { \
+        return generic(Wrapper_GetObject(wrapper)); \
+    }
+
+#define WRAP_BINARY(method, generic) \
+    static PyObject * \
+    method(PyObject *wrapper, PyObject *v) { \
+        return generic(Wrapper_GetObject(wrapper), v); \
+    }
+
+#define WRAP_TERNARY(method, generic) \
+    static PyObject * \
+    method(PyObject *wrapper, PyObject *v, PyObject *w) { \
+        return generic(Wrapper_GetObject(wrapper), v, w); \
+    }
+
+
+WRAP_UNARY(wrap_str, PyObject_Str)
 static int
-wrap_init(WrapperObject *self, PyObject *args, PyObject *kwds)
+wrap_init(PyObject *self, PyObject *args, PyObject *kwds)
 {
     int result = -1;
     PyObject *context = NULL;
     PyObject *object;
 
     if (PyArg_UnpackTuple(args, "__init__", 1, 2, &object, &context)) {
-        if (PyType_Type.tp_init((PyObject *)self, empty_tuple, NULL) < 0)
+        WrapperObject *wrapper = (WrapperObject *)self;
+        if (PyType_Type.tp_init(self, empty_tuple, NULL) < 0)
             goto finally;
         Py_INCREF(object);
-        self->wrap_object = object;
+        wrapper->wrap_object = object;
         Py_XINCREF(context);
-        self->wrap_context = context;
-        self->wrap_dict = NULL;
+        wrapper->wrap_context = context;
+        wrapper->wrap_dict = NULL;
         result = 0;
     }
  finally:
@@ -29,81 +64,183 @@
 }
 
 static int
-wrap_traverse(WrapperObject *self, visitproc visit, void *arg)
+wrap_traverse(PyObject *self, visitproc visit, void *arg)
 {
-    int err = visit(self->wrap_object, arg);
+    int err = visit(Wrapper_GetObject(self), arg);
 
-    if (!err && self->wrap_context != NULL)
-        err = visit(self->wrap_context, arg);
-    if (!err && self->wrap_dict != NULL)
-        err = visit(self->wrap_dict, arg);
+    if (!err && Wrapper_GetContext(self) != NULL)
+        err = visit(Wrapper_GetContext(self), arg);
+    if (!err && Wrapper_GetDict(self) != NULL)
+        err = visit(Wrapper_GetDict(self), arg);
     return err;
 }
 
 static int
-wrap_clear(WrapperObject *self)
+wrap_clear(PyObject *self)
 {
+    WrapperObject *wrapper = (WrapperObject *)self;
     PyObject *temp;
 
-    if ((temp = self->wrap_dict) != NULL) {
-        self->wrap_dict = NULL;
+    if ((temp = wrapper->wrap_dict) != NULL) {
+        wrapper->wrap_dict = NULL;
         Py_DECREF(temp);
     }
-    if ((temp = self->wrap_context) != NULL) {
-        self->wrap_context = NULL;
+    if ((temp = wrapper->wrap_context) != NULL) {
+        wrapper->wrap_context = NULL;
         Py_DECREF(temp);
     }
-    if ((temp = self->wrap_object) != NULL) {
-        self->wrap_object = NULL;
+    if ((temp = wrapper->wrap_object) != NULL) {
+        wrapper->wrap_object = NULL;
         Py_DECREF(temp);
     }
     return 0;
 }
 
 static void
-wrap_dealloc(WrapperObject *self)
+wrap_dealloc(PyObject *self)
 {
     (void) wrap_clear(self);
 }
 
 static PyObject *
-wrap_getattro(WrapperObject *self, PyObject *name)
+wrap_getattro(PyObject *self, PyObject *name)
 {
     PyObject *result;
-    result = PyObject_GenericGetAttr((PyObject *)self, name);
+    result = PyObject_GenericGetAttr(self, name);
     if (result == NULL) {
         PyErr_Clear();
-        result = PyObject_GetAttr(self->wrap_object, name);
+        result = PyObject_GetAttr(Wrapper_GetObject(self), name);
     }
     return result;
 }
 
+static int
+wrap_setattro(PyObject *self, PyObject *name, PyObject *value)
+{
+    if (Wrapper_GetObject(self) != NULL)
+        return PyObject_SetAttr(Wrapper_GetObject(self), name, value);
+    PyErr_Format(PyExc_RuntimeError,
+                 "object is NULL; requested to set attribute '%s'",
+                 PyString_AS_STRING(name));
+    return -1;
+}
+
+static int
+wrap_print(PyObject *wrapper, FILE *fp, int flags)
+{
+    return PyObject_Print(Wrapper_GetObject(wrapper), fp, flags);
+}
+
+static PyObject *
+wrap_repr(PyObject *wrapper)
+{
+    return PyObject_Repr(Wrapper_GetObject(wrapper));
+}
+
+
+static int
+wrap_setattr(PyObject *wrapper, PyObject *name, PyObject *value)
+{
+    return PyObject_SetAttr(Wrapper_GetObject(wrapper), name, value);
+}
+
+static int
+wrap_compare(PyObject *wrapper, PyObject *v)
+{
+    return PyObject_Compare(Wrapper_GetObject(wrapper), v);
+}
+
+static long
+wrap_hash(PyObject *self)
+{
+    return PyObject_Hash(Wrapper_GetObject(self));
+}
+
+/*
+ *   Sequence methods
+ */
+
+static int
+wrap_length(PyObject *self)
+{
+    return PyObject_Length(Wrapper_GetObject(self));
+}
+
+static PyObject *
+wrap_slice(PyObject *self, int start, int end)
+{
+    return PySequence_GetSlice(Wrapper_GetObject(self), start, end);
+}
+
+static int
+wrap_ass_slice(PyObject *self, int i, int j, PyObject *value)
+{
+    return PySequence_SetSlice(Wrapper_GetObject(self), i, j, value);
+}
+
+static int
+wrap_contains(PyObject *self, PyObject *value)
+{
+    return PySequence_Contains(Wrapper_GetObject(self), value);
+}
+
+/*
+ *   Mapping methods
+ */
+
+WRAP_BINARY(wrap_getitem, PyObject_GetItem)
+
+static int
+wrap_setitem(PyObject *self, PyObject *key, PyObject *value)
+{
+    return PyObject_SetItem(Wrapper_GetObject(self), key, value);
+}
+
+static PySequenceMethods
+wrap_as_sequence = {
+    wrap_length,			/* sq_length */
+    0,					/* sq_concat */
+    0,					/* sq_repeat */
+    0,					/* sq_item */
+    wrap_slice,				/* sq_slice */
+    0,					/* sq_ass_item */
+    wrap_ass_slice,			/* sq_ass_slice */
+    wrap_contains,			/* sq_contains */
+};
+
+static PyMappingMethods
+wrap_as_mapping = {
+    wrap_length,			/* mp_length */
+    wrap_getitem,			/* mp_subscript */
+    wrap_setitem,			/* mp_ass_subscript */
+};
+
 static PyTypeObject
 WrapperType = {
     PyObject_HEAD_INIT(NULL)
     0,
-    "wrapper.WrapperType",
+    "wrapper.Wrapper",
     sizeof(WrapperObject),
     0,
-    (destructor)wrap_dealloc,		/* tp_dealloc */
-    0,					/* tp_print */
+    wrap_dealloc,			/* tp_dealloc */
+    wrap_print,				/* tp_print */
     0,					/* tp_getattr */
     0,					/* tp_setattr */
-    0,					/* tp_compare */
-    0,					/* tp_repr */
+    wrap_compare,			/* tp_compare */
+    wrap_repr,				/* tp_repr */
     0,					/* tp_as_number */
-    0,					/* tp_as_sequence */
-    0,					/* tp_as_mapping */
-    0,					/* tp_hash */
+    &wrap_as_sequence,			/* tp_as_sequence */
+    &wrap_as_mapping,			/* tp_as_mapping */
+    wrap_hash,				/* tp_hash */
     0,					/* tp_call */
-    0,					/* tp_str */
-    (getattrofunc)wrap_getattro,	/* tp_getattro */
-    0,					/* tp_setattro */
+    wrap_str,				/* tp_str */
+    wrap_getattro,			/* tp_getattro */
+    wrap_setattro,			/* tp_setattro */
     0,					/* tp_as_buffer */
     Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */
     0,					/* tp_doc */
-    (traverseproc)wrap_traverse,	/* tp_traverse */
-    (inquiry)wrap_clear,		/* tp_clear */
+    wrap_traverse,			/* tp_traverse */
+    wrap_clear,				/* tp_clear */
     0,					/* tp_richcompare */
     0,					/* tp_weaklistoffset */
     0,					/* tp_iter */
@@ -116,17 +253,13 @@
     0,					/* tp_descr_get */
     0,					/* tp_descr_set */
     0,					/* tp_dictoffset */
-    (initproc)wrap_init,		/* tp_init */
+    wrap_init,				/* tp_init */
     PyType_GenericAlloc,		/* tp_alloc */
     PyType_GenericNew,			/* tp_new */
     _PyObject_GC_Del,			/* tp_free */
 };
 
 
-#define Wrapper_Check(wrapper) \
-        (((wrapper)->ob_type == &WrapperType) \
-         || (PyObject_TypeCheck(wrapper, &WrapperType)))
-
 static PyObject *
 create_wrapper(PyObject *object, PyObject *context)
 {
@@ -196,7 +329,7 @@
     if (wrapper == NULL)
         return missing_wrapper("getobject");
     if (Wrapper_Check(wrapper))
-        return ((WrapperObject *)wrapper)->wrap_object;
+        return Wrapper_GetObject(wrapper);
     else
         return wrapper;
 }
@@ -207,7 +340,7 @@
     if (obj == NULL)
         return missing_wrapper("getinnerobject");
     while (Wrapper_Check(obj)) {
-        obj = ((WrapperObject *)obj)->wrap_object;
+        obj = Wrapper_GetObject(obj);
     }
     return obj;
 }
@@ -218,7 +351,7 @@
     if (wrapper == NULL)
         return missing_wrapper("getcontext");
     if (Wrapper_Check(wrapper))
-        return ((WrapperObject *)wrapper)->wrap_context;
+        return Wrapper_GetContext(wrapper);
     else
         return NULL;
 }
@@ -229,13 +362,13 @@
     if (obj == NULL)
         return missing_wrapper("getinnercontext");
     if (Wrapper_Check(obj)) {
-        WrapperObject *wrapper = (WrapperObject *)obj;
-        obj = wrapper->wrap_object;
+        PyObject *wrapper = obj;
+        obj = Wrapper_GetObject(wrapper);
         while (Wrapper_Check(obj)) {
-            wrapper = (WrapperObject *)obj;
-            obj = wrapper->wrap_object;
+            wrapper = obj;
+            obj = Wrapper_GetObject(wrapper);
         }
-        return wrapper->wrap_context;
+        return Wrapper_GetContext(wrapper);
     }
     else
         return NULL;
@@ -247,7 +380,7 @@
     if (wrapper == NULL)
         return missing_wrapper("getdict");
     if (Wrapper_Check(wrapper))
-        return ((WrapperObject *)wrapper)->wrap_dict;
+        return Wrapper_GetDict(wrapper);
     else
         return NULL;
 }
@@ -258,7 +391,7 @@
     PyObject *dict = NULL;
 
     if (check_wrapper(wrapper, "getdictcreate")) {
-        dict = ((WrapperObject *)wrapper)->wrap_dict;
+        dict = Wrapper_GetDict(wrapper);
         if (dict == NULL) {
             dict = PyDict_New();
             ((WrapperObject *)wrapper)->wrap_dict = dict;
@@ -280,7 +413,7 @@
     if (!check_wrapper(wrapper, "setobject"))
         return 0;
     wrap = (WrapperObject *) wrapper;
-    oldobject = wrap->wrap_object;
+    oldobject = Wrapper_GetObject(wrap);
     Py_INCREF(object);
     wrap->wrap_object = object;
     Py_DECREF(oldobject);
@@ -330,7 +463,7 @@
     PyObject *result = NULL;
 
     if (Wrapper_Check(obj))
-        result = ((WrapperObject *)obj)->wrap_object;
+        result = Wrapper_GetObject(obj);
     else
         result = Py_None;
     Py_INCREF(result);