[Zope-CVS] CVS: Packages/ContextWrapper - wrapper.c:1.5
Fred Drake Jr
fdrake@acm.org
Wed, 14 Nov 2001 14:34:24 -0500
Update of /cvs-repository/Packages/ContextWrapper
In directory cvs.zope.org:/tmp/cvs-serv8479
Modified Files:
wrapper.c
Log Message:
Update to the latest clarifications of the API in the Wiki:
- non-wrapper objects can be passed to the module functions
- callable version of the wrapper is removed since there is no need for it
=== Packages/ContextWrapper/wrapper.c 1.4 => 1.5 ===
static int
-noncall_init(WrapperObject *self, PyObject *args, PyObject *kwds)
+wrap_init(WrapperObject *self, PyObject *args, PyObject *kwds)
{
int result = -1;
PyObject *context = NULL;
@@ -29,26 +29,6 @@
}
static int
-callable_init(WrapperObject *self, PyObject *args, PyObject *kwds)
-{
- if (PyTuple_GET_SIZE(args)) {
- PyObject *object = PyTuple_GET_ITEM(args, 0);
- if (!PyCallable_Check(object)) {
- PyErr_SetString(PyExc_ValueError,
- "expected callable object as arg1");
- return -1;
- }
- }
- return noncall_init(self, args, kwds);
-}
-
-static PyObject *
-callable_call(WrapperObject *self, PyObject *args, PyObject *kwds)
-{
- return PyEval_CallObjectWithKeywords(self->wrap_object, args, kwds);
-}
-
-static int
wrap_traverse(WrapperObject *self, visitproc visit, void *arg)
{
int err = visit(self->wrap_object, arg);
@@ -136,52 +116,7 @@
0, /* tp_descr_get */
0, /* tp_descr_set */
0, /* tp_dictoffset */
- (initproc)noncall_init, /* tp_init */
- PyType_GenericAlloc, /* tp_alloc */
- PyType_GenericNew, /* tp_new */
- _PyObject_GC_Del, /* tp_free */
-};
-
-
-static PyTypeObject
-CallableWrapperType = {
- PyObject_HEAD_INIT(NULL)
- 0,
- "wrapper.CallableWrapperType",
- sizeof(WrapperObject),
- 0,
- 0, /* tp_dealloc */
- 0, /* tp_print */
- 0, /* tp_getattr */
- 0, /* tp_setattr */
- 0, /* tp_compare */
- 0, /* tp_repr */
- 0, /* tp_as_number */
- 0, /* tp_as_sequence */
- 0, /* tp_as_mapping */
- 0, /* tp_hash */
- (ternaryfunc)callable_call, /* tp_call */
- 0, /* tp_str */
- 0, /* tp_getattro */
- 0, /* tp_setattro */
- 0, /* tp_as_buffer */
- Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */
- 0, /* tp_doc */
- 0, /* tp_traverse */
- 0, /* tp_clear */
- 0, /* tp_richcompare */
- 0, /* tp_weaklistoffset */
- 0, /* tp_iter */
- 0, /* tp_iternext */
- 0, /* tp_methods */
- 0, /* tp_members */
- 0, /* tp_getset */
- &WrapperType, /* tp_base */
- 0, /* tp_dict */
- 0, /* tp_descr_get */
- 0, /* tp_descr_set */
- 0, /* tp_dictoffset */
- (initproc)callable_init, /* tp_init */
+ (initproc)wrap_init, /* tp_init */
PyType_GenericAlloc, /* tp_alloc */
PyType_GenericNew, /* tp_new */
_PyObject_GC_Del, /* tp_free */
@@ -190,22 +125,16 @@
#define Wrapper_Check(wrapper) \
(((wrapper)->ob_type == &WrapperType) \
- || ((wrapper)->ob_type == &CallableWrapperType) \
|| (PyObject_TypeCheck(wrapper, &WrapperType)))
static PyObject *
create_wrapper(PyObject *object, PyObject *context)
{
PyObject *result = NULL;
- PyObject *wrappertype;
PyObject *args;
if (context == Py_None)
context = NULL;
- if (PyCallable_Check(object))
- wrappertype = (PyObject *)&CallableWrapperType;
- else
- wrappertype = (PyObject *)&WrapperType;
args = PyTuple_New(context ? 2 : 1);
if (args != NULL) {
if (context != NULL) {
@@ -214,7 +143,7 @@
}
PyTuple_SET_ITEM(args, 0, object);
Py_INCREF(object);
- result = PyObject_CallObject(wrappertype, args);
+ result = PyObject_CallObject((PyObject *)&WrapperType, args);
Py_DECREF(args);
}
return result;
@@ -238,12 +167,19 @@
return create_wrapper(object, context);
}
+static PyObject *
+missing_wrapper(const char *funcname)
+{
+ PyErr_Format(PyExc_RuntimeError,
+ "cannot pass NULL to WrapperAPI.%s()", funcname);
+ return NULL;
+}
+
static int
check_wrapper(PyObject *wrapper, const char *funcname)
{
if (wrapper == NULL) {
- PyErr_Format(PyExc_RuntimeError,
- "cannot pass NULL to WrapperAPI.%s()", funcname);
+ (void) missing_wrapper(funcname);
return 0;
}
if (!Wrapper_Check(wrapper)) {
@@ -257,16 +193,20 @@
static PyObject *
api_getobject(PyObject *wrapper)
{
- if (check_wrapper(wrapper, "getobject"))
+ if (wrapper == NULL)
+ return missing_wrapper("getobject");
+ if (Wrapper_Check(wrapper))
return ((WrapperObject *)wrapper)->wrap_object;
else
- return NULL;
+ return wrapper;
}
static PyObject *
api_getcontext(PyObject *wrapper)
{
- if (check_wrapper(wrapper, "getcontext"))
+ if (wrapper == NULL)
+ return NULL;
+ if (Wrapper_Check(wrapper))
return ((WrapperObject *)wrapper)->wrap_context;
else
return NULL;
@@ -275,7 +215,9 @@
static PyObject *
api_getdict(PyObject *wrapper)
{
- if (check_wrapper(wrapper, "getdict"))
+ if (wrapper == NULL)
+ return NULL;
+ if (Wrapper_Check(wrapper))
return ((WrapperObject *)wrapper)->wrap_dict;
else
return NULL;
@@ -308,16 +250,6 @@
}
if (!check_wrapper(wrapper, "setobject"))
return 0;
- if (PyObject_TypeCheck(wrapper, &CallableWrapperType)) {
- /* If the wrapper is callable, make sure we enforce the
- * restriction that the referent is callable as well.
- */
- if (!PyCallable_Check(object)) {
- PyErr_SetString(PyExc_TypeError,
- "object for a callable wrapper must be callable");
- return 0;
- }
- }
wrap = (WrapperObject *) wrapper;
oldobject = wrap->wrap_object;
Py_INCREF(object);
@@ -356,41 +288,40 @@
};
static char
-create__doc__[] =
-"new(object[, context]) --> wrapper\n"
+getobject__doc__[] =
+"getobject(wrapper) --> object\n"
"\n"
-"Return a new wrapper object around object and context. If context\n"
-"is omitted, there is no context object, but one can be added.";
+"Return the underlying object for wrapper.";
static PyObject *
-create(PyObject *unused, PyObject *args)
+getobject(PyObject *unused, PyObject *obj)
{
- PyObject *object;
- PyObject *context = NULL;
PyObject *result = NULL;
- if (PyArg_UnpackTuple(args, "new", 1, 2, &object, &context)) {
- result = create_wrapper(object, context);
- }
+ if (Wrapper_Check(obj))
+ result = ((WrapperObject *)obj)->wrap_object;
+ else
+ result = Py_None;
+ Py_INCREF(result);
return result;
}
static char
-getobject__doc__[] =
-"getobject(wrapper) --> object\n"
+getinnerobject__doc__[] =
+"getinnerobject(wrapper) --> object\n"
"\n"
-"Return the underlying object for wrapper.";
+"Return the underlying object for the innermost wrapper in a chain of\n"
+"wrappers with 'wrapper' at the head. Returns None if 'wrapper' isn't a\n"
+"wrapper at all.";
static PyObject *
-getobject(PyObject *unused, PyObject *obj)
+getinnerobject(PyObject *unused, PyObject *obj)
{
- PyObject *result = NULL;
-
- if (check_wrapper(obj, "getobject")) {
- result = ((WrapperObject *)obj)->wrap_object;
- Py_INCREF(result);
+ while (Wrapper_Check(obj)) {
+ obj = ((WrapperObject *)obj)->wrap_object;
}
- return result;
+ Py_INCREF(obj);
+ return obj;
}
static char
@@ -404,12 +335,46 @@
{
PyObject *result = NULL;
- if (check_wrapper(obj, "getcontext")) {
+ if (Wrapper_Check(obj)) {
result = ((WrapperObject *)obj)->wrap_context;
if (result == NULL)
result = Py_None;
- Py_XINCREF(result);
}
+ else {
+ result = Py_None;
+ }
+ Py_XINCREF(result);
+ return result;
+}
+
+static char
+getinnercontext__doc__[] =
+"getinnercontext(wrapper) --> object | None\n"
+"\n"
+"Return the context object for the innermost wrapper in a chain of wrappers\n"
+"with 'wrapper' at the head, or None if there isn't one. Returns None if\n"
+"'wrapper' isn't a wrapper at all.";
+
+static PyObject *
+getinnercontext(PyObject *unused, PyObject *obj)
+{
+ PyObject *result;
+
+ if (Wrapper_Check(obj)) {
+ WrapperObject *wrapper = (WrapperObject *)obj;
+ obj = wrapper->wrap_object;
+ while (Wrapper_Check(obj)) {
+ wrapper = (WrapperObject *)obj;
+ obj = wrapper->wrap_object;
+ }
+ result = wrapper->wrap_context;
+ if (result == NULL)
+ result = Py_None;
+ }
+ else {
+ result = Py_None;
+ }
+ Py_INCREF(result);
return result;
}
@@ -424,12 +389,14 @@
{
PyObject *result = NULL;
- if (check_wrapper(obj, "getdict")) {
+ if (Wrapper_Check(obj)) {
result = ((WrapperObject *)obj)->wrap_dict;
if (result == NULL)
result = Py_None;
- Py_XINCREF(result);
}
+ else
+ result = Py_None;
+ Py_INCREF(result);
return result;
}
@@ -502,13 +469,14 @@
static PyMethodDef
module_functions[] = {
- {"new", create, METH_VARARGS, create__doc__},
- {"getobject", getobject, METH_O, getobject__doc__},
- {"getcontext", getcontext, METH_O, getcontext__doc__},
- {"getdict", getdict, METH_O, getdict__doc__},
- {"getdictcreate", getdictcreate, METH_O, getdictcreate__doc__},
- {"setobject", setobject, METH_VARARGS, setobject__doc__},
- {"setcontext", setcontext, METH_VARARGS, setcontext__doc__},
+ {"getobject", getobject, METH_O, getobject__doc__},
+ {"getinnerobject", getinnerobject, METH_O, getinnerobject__doc__},
+ {"getcontext", getcontext, METH_O, getcontext__doc__},
+ {"getinnercontext", getinnercontext, METH_O, getinnercontext__doc__},
+ {"getdict", getdict, METH_O, getdict__doc__},
+ {"getdictcreate", getdictcreate, METH_O, getdictcreate__doc__},
+ {"setobject", setobject, METH_VARARGS, setobject__doc__},
+ {"setcontext", setcontext, METH_VARARGS, setcontext__doc__},
{NULL, NULL, 0, NULL}
};
@@ -535,24 +503,20 @@
return;
WrapperType.ob_type = &PyType_Type;
- CallableWrapperType.ob_type = &PyType_Type;
if (PyType_Ready(&WrapperType) < 0)
return;
- if (PyType_Ready(&CallableWrapperType) < 0)
- return;
- if (api_object == NULL)
- api_object = PyCObject_FromVoidPtr(&wrapper_capi, NULL);
- if (empty_tuple == NULL)
- empty_tuple = PyDict_New();
Py_INCREF(&WrapperType);
- PyModule_AddObject(m, "WrapperType",
- (PyObject *)&WrapperType);
- Py_INCREF(&CallableWrapperType);
- PyModule_AddObject(m, "CallableWrapperType",
- (PyObject *)&CallableWrapperType);
- if (api_object != NULL) {
- Py_INCREF(api_object);
- PyModule_AddObject(m, "_CAPI", api_object);
+ PyModule_AddObject(m, "Wrapper", (PyObject *)&WrapperType);
+
+ if (api_object == NULL) {
+ api_object = PyCObject_FromVoidPtr(&wrapper_capi, NULL);
+ if (api_object == NULL)
+ return;
}
+ Py_INCREF(api_object);
+ PyModule_AddObject(m, "_CAPI", api_object);
+
+ if (empty_tuple == NULL)
+ empty_tuple = PyDict_New();
}