[Zope3-checkins] CVS: Zope3/src/zope/proxy/context - decorator.c:1.1 decorator.h:1.1
Steve Alexander
steve@cat-box.net
Thu, 8 May 2003 06:57:00 -0400
Update of /cvs-repository/Zope3/src/zope/proxy/context
In directory cvs.zope.org:/tmp/cvs-serv18548/src/zope/proxy/context
Added Files:
decorator.c decorator.h
Log Message:
Add new decorator type, with tests.
Add this to the build directives in setup.py.
=== Added File Zope3/src/zope/proxy/context/decorator.c === (1003/1103 lines abridged)
#include <Python.h>
#include "structmember.h"
#include "modsupport.h"
#include "zope/proxy/proxy.h"
#include "zope/proxy/context/wrapper.h"
#define DECORATOR_MODULE
#include "zope/proxy/context/decorator.h"
/* XXX perhaps all these wrapper args should be renamed to decorator? */
/* XXX provides should probably be renamed to providedBy */
#define Decorator_Check(wrapper) (PyObject_TypeCheck(wrapper, &DecoratorType))
#define Decorator_GetObject(wrapper) Proxy_GET_OBJECT((wrapper))
#define Decorator_GetMixinFactory(wrapper) \
(((DecoratorObject *)wrapper)->mixin_factory)
#define Decorator_GetMixin(wrapper) \
(((DecoratorObject *)wrapper)->mixin)
#define Decorator_GetNames(wrapper) \
(((DecoratorObject *)wrapper)->names)
#define Decorator_GetNamesDict(wrapper) \
(((DecoratorObject *)wrapper)->names_dict)
#define Decorator_GetProvides(wrapper) \
(((DecoratorObject *)wrapper)->provides)
static PyTypeObject DecoratorType;
static PyObject *empty_tuple = NULL;
/* We need to use PyStrings for the various python special method names,
* such as __len__ and next and __getitem__.
* At module initialisation, we create the strings, and cache them here.
*/
static PyObject *SlotStrings[10];
#define LEN_IDX 0
#define NONZERO_IDX 1
#define GETITEM_IDX 2
#define SETITEM_IDX 3
#define DELITEM_IDX 4
#define ITER_IDX 5
#define NEXT_IDX 6
#define CONTAINS_IDX 7
#define CALL_IDX 8
#define STR_IDX 9
/* Helper for decorate_new/decorate_init; return the base class args tuple
[-=- -=- -=- 1003 lines omitted -=- -=- -=-]
";
static PyObject *api_object = NULL;
void
initdecorator(void)
{
PyObject *m;
if (Proxy_Import() < 0)
return;
if (Wrapper_Import() < 0)
return;
m = Py_InitModule3("decorator", module_functions, module___doc__);
if (m == NULL)
return;
SlotStrings[LEN_IDX] = PyString_InternFromString("__len__");
SlotStrings[NONZERO_IDX] = PyString_InternFromString("__nonzero__");
SlotStrings[GETITEM_IDX] = PyString_InternFromString("__getitem__");
SlotStrings[SETITEM_IDX] = PyString_InternFromString("__setitem__");
SlotStrings[DELITEM_IDX] = PyString_InternFromString("__delitem__");
SlotStrings[ITER_IDX] = PyString_InternFromString("__iter__");
SlotStrings[NEXT_IDX] = PyString_InternFromString("next");
SlotStrings[CONTAINS_IDX] = PyString_InternFromString("__contains__");
SlotStrings[CALL_IDX] = PyString_InternFromString("__call__");
SlotStrings[STR_IDX] = PyString_InternFromString("__str__");
DecoratorType.tp_base = &WrapperType;
DecoratorType.tp_alloc = PyType_GenericAlloc;
DecoratorType.tp_free = _PyObject_GC_Del;
if (PyType_Ready(&DecoratorType) < 0)
return;
Py_INCREF(&DecoratorType);
PyModule_AddObject(m, "Decorator", (PyObject *)&DecoratorType);
if (api_object == NULL) {
api_object = PyCObject_FromVoidPtr(&decorator_capi, NULL);
if (api_object == NULL)
return;
}
Py_INCREF(api_object);
PyModule_AddObject(m, "_CAPI", api_object);
if (empty_tuple == NULL)
empty_tuple = PyTuple_New(0);
}
=== Added File Zope3/src/zope/proxy/context/decorator.h ===
/* Decorator objects.
*
* This is intended for use with Python 2.2.
*
* Created by Steve Alexander and Marius Gedminas, 2003-May-7.
*/
#ifndef _decorator_H_
#define _decorator_H_
#ifndef _wrapper_H_
#include "zope/proxy/context/wrapper.h"
#endif
typedef struct {
WrapperObject wrapperobject;
PyObject *mixin_factory;
PyObject *mixin;
PyObject *names;
PyObject *names_dict;
PyObject *provides;
} DecoratorObject;
typedef struct {
int (*check)(PyObject *obj);
PyObject *(*create)(PyObject *object, PyObject *context,
PyObject *mixin_factory, PyObject *names, PyObject *provides);
PyObject *(*getmixin)(PyObject *wrapper);
PyObject *(*getmixinfactory)(PyObject *wrapper);
PyObject *(*getnames)(PyObject *wrapper);
PyObject *(*getprovides)(PyObject *wrapper);
int (*setprovides)(PyObject *wrapper, PyObject *provides);
} DecoratorInterface;
#ifndef DECORATOR_MODULE
/* These are only defined in the public interface, and are not
* available within the module implementation. There we use the
* classic Python/C API only.
*/
static DecoratorInterface *_decorator_api = NULL;
static int
Decorator_Import(void)
{
if (_decorator_api == NULL) {
PyObject *m = PyImport_ImportModule("zope.proxy.context.decorator");
if (m != NULL) {
PyObject *tmp = PyObject_GetAttrString(m, "_CAPI");
if (tmp != NULL) {
if (PyCObject_Check(tmp))
_decorator_api = (DecoratorInterface *)
PyCObject_AsVoidPtr(tmp);
Py_DECREF(tmp);
}
}
}
return (_decorator_api == NULL) ? -1 : 0;
}
#define Decorator_Check(obj) \
(_decorator_api->check((obj)))
#define Decorator_New(object, context, mixin_factory, names, provides) \
(_decorator_api->create((object), (context), (mixin_factory), \
(names), (provides)))
#define Decorator_GetMixin(wrapper) \
(_decorator_api->getmixin((wrapper)))
#define Decorator_GetMixinFactory(wrapper) \
(_decorator_api->getmixinfactory((wrapper)))
#define Decorator_GetNames(wrapper) \
(_decorator_api->getnames((wrapper)))
#define Decorator_GetProvides(wrapper) \
(_decorator_api->getprovides((wrapper)))
#define Decorator_SetProvides(wrapper, provides) \
(_decorator_api->setprovides((wrapper), (provides)))
#endif
#endif