[Zope3-checkins] SVN: Zope3/trunk/src/zope/security/_proxy.c
Changed to use precomuted strings when doing method lookup and when
Jim Fulton
jim at zope.com
Wed Jun 16 14:26:52 EDT 2004
Log message for revision 25884:
Changed to use precomuted strings when doing method lookup and when
passing operation names to the checker. This yielded around a 4%
speedup when viewing a test page.
-=-
Modified: Zope3/trunk/src/zope/security/_proxy.c
===================================================================
--- Zope3/trunk/src/zope/security/_proxy.c 2004-06-16 17:15:35 UTC (rev 25883)
+++ Zope3/trunk/src/zope/security/_proxy.c 2004-06-16 18:26:51 UTC (rev 25884)
@@ -21,140 +21,203 @@
static PyObject *__class__str = 0, *__name__str = 0, *__module__str = 0;
+#define DECLARE_STRING(N) static PyObject *str_##N
+
+DECLARE_STRING(__3pow__);
+DECLARE_STRING(__call__);
+DECLARE_STRING(check);
+DECLARE_STRING(check_getattr);
+DECLARE_STRING(check_setattr);
+DECLARE_STRING(__cmp__);
+DECLARE_STRING(__coerce__);
+DECLARE_STRING(__contains__);
+DECLARE_STRING(__delitem__);
+DECLARE_STRING(__getitem__);
+DECLARE_STRING(__getslice__);
+DECLARE_STRING(__hash__);
+DECLARE_STRING(__iter__);
+DECLARE_STRING(__len__);
+DECLARE_STRING(next);
+DECLARE_STRING(__nonzero__);
+DECLARE_STRING(op_abs);
+DECLARE_STRING(op_add);
+DECLARE_STRING(op_and);
+DECLARE_STRING(op_div);
+DECLARE_STRING(op_divmod);
+DECLARE_STRING(op_float);
+DECLARE_STRING(op_floordiv);
+DECLARE_STRING(op_hex);
+DECLARE_STRING(op_iadd);
+DECLARE_STRING(op_iand);
+DECLARE_STRING(op_idiv);
+DECLARE_STRING(op_ifloordiv);
+DECLARE_STRING(op_ilshift);
+DECLARE_STRING(op_imod);
+DECLARE_STRING(op_imul);
+DECLARE_STRING(op_int);
+DECLARE_STRING(op_invert);
+DECLARE_STRING(op_ior);
+DECLARE_STRING(op_ipow);
+DECLARE_STRING(op_irshift);
+DECLARE_STRING(op_isub);
+DECLARE_STRING(op_itruediv);
+DECLARE_STRING(op_ixor);
+DECLARE_STRING(op_long);
+DECLARE_STRING(op_lshift);
+DECLARE_STRING(op_mod);
+DECLARE_STRING(op_mul);
+DECLARE_STRING(op_neg);
+DECLARE_STRING(op_oct);
+DECLARE_STRING(op_or);
+DECLARE_STRING(op_pos);
+DECLARE_STRING(op_radd);
+DECLARE_STRING(op_rand);
+DECLARE_STRING(op_rdiv);
+DECLARE_STRING(op_rdivmod);
+DECLARE_STRING(op_rfloordiv);
+DECLARE_STRING(op_rlshift);
+DECLARE_STRING(op_rmod);
+DECLARE_STRING(op_rmul);
+DECLARE_STRING(op_ror);
+DECLARE_STRING(op_rrshift);
+DECLARE_STRING(op_rshift);
+DECLARE_STRING(op_rsub);
+DECLARE_STRING(op_rtruediv);
+DECLARE_STRING(op_rxor);
+DECLARE_STRING(op_sub);
+DECLARE_STRING(op_truediv);
+DECLARE_STRING(op_xor);
+DECLARE_STRING(__pow__);
+DECLARE_STRING(proxy);
+DECLARE_STRING(__repr__);
+DECLARE_STRING(__rpow__);
+DECLARE_STRING(__setitem__);
+DECLARE_STRING(__setslice__);
+DECLARE_STRING(__str__);
+
typedef struct {
- ProxyObject proxy;
- PyObject *proxy_checker;
+ ProxyObject proxy;
+ PyObject *proxy_checker;
} SecurityProxy;
+#define CLEAR(O) if (O) {PyObject *t = O; O = 0; Py_DECREF(t); }
+
#undef Proxy_Check
#define Proxy_Check(proxy) \
PyObject_TypeCheck(proxy, &SecurityProxyType)
-#define Proxy_GetChecker(proxy) \
- (((SecurityProxy *)proxy)->proxy_checker)
-
-/* Replace the "safe" version from the proxy.h API with a faster version. */
-#undef Proxy_GetObject
-#define Proxy_GetObject(o) \
- (((SecurityProxy *)o)->proxy.proxy_object)
-
-
static PyTypeObject SecurityProxyType;
-
/*
* Machinery to call the checker.
*/
-typedef PyObject *(*function1)(PyObject *);
-
static int
-check(PyObject *checker, char *opname, PyObject *object)
+check(SecurityProxy *self, PyObject *meth, PyObject *name)
{
- PyObject *checked;
+ PyObject *r;
- checked = PyObject_CallMethod(checker, "check", "(Os)",
- object, opname);
- if (checked == NULL)
- return 0;
- Py_DECREF(checked);
- return 1;
-}
-static int
-checkattr(PyObject *checker, char *check_method,
- PyObject *object, PyObject *name)
-{
- PyObject *checked;
+ r = PyObject_CallMethodObjArgs(self->proxy_checker, meth,
+ self->proxy.proxy_object, name,
+ NULL);
+ if (r == NULL)
+ return -1;
- checked = PyObject_CallMethod(checker, check_method, "(OO)",
- object, name);
- if (checked == NULL)
- return 0;
- Py_DECREF(checked);
- return 1;
+ Py_DECREF(r);
+ return 0;
}
+#define PROXY_RESULT(self, result) \
+if (result != NULL) { \
+ PyObject *tmp = PyObject_CallMethodObjArgs(self->proxy_checker, str_proxy, \
+ result, NULL); \
+ Py_DECREF(result); \
+ result = tmp; \
+}
+
+typedef PyObject *(*function1)(PyObject *);
+
static PyObject *
-check1(SecurityProxy *self, char *opname, function1 operation)
+check1(SecurityProxy *self, PyObject *opname, function1 operation)
{
- PyObject *result = NULL;
- PyObject *object = Proxy_GetObject(self);
- PyObject *checker = Proxy_GetChecker(self);
+ PyObject *result = NULL;
- if (check(checker, opname, object)) {
- result = operation(object);
- if (result != NULL)
- result = PyObject_CallMethod(checker, "proxy",
- "(N)", result);
- }
- return result;
+ if (check(self, str_check, opname) >= 0) {
+ result = operation(self->proxy.proxy_object);
+ PROXY_RESULT(self, result);
+ }
+ return result;
}
static PyObject *
check2(PyObject *self, PyObject *other,
- char *opname, char *ropname, binaryfunc operation)
+ PyObject *opname, PyObject *ropname, binaryfunc operation)
{
- PyObject *result = NULL;
- PyObject *object;
- PyObject *checker;
+ PyObject *result = NULL;
- if (Proxy_Check(self)) {
- object = Proxy_GetObject(self);
- checker = Proxy_GetChecker(self);
- if (check(checker, opname, object))
- result = operation(object, other);
- }
- else if (Proxy_Check(other)) {
- object = Proxy_GetObject(other);
- checker = Proxy_GetChecker(other);
- if (check(checker, ropname, object))
- result = operation(self, object);
- }
- else {
- Py_INCREF(Py_NotImplemented);
- return Py_NotImplemented;
- }
- if (result != NULL)
- result = PyObject_CallMethod(checker, "proxy", "(N)", result);
- return result;
+ if (Proxy_Check(self))
+ {
+ if (check((SecurityProxy*)self, str_check, opname) >= 0)
+ {
+ result = operation(((SecurityProxy*)self)->proxy.proxy_object,
+ other);
+ PROXY_RESULT(((SecurityProxy*)self), result);
+ }
+ }
+ else if (Proxy_Check(other))
+ {
+ if (check((SecurityProxy*)other, str_check, ropname) >= 0)
+ {
+ result = operation(self,
+ ((SecurityProxy*)other)->proxy.proxy_object);
+
+ PROXY_RESULT(((SecurityProxy*)other), result);
+ }
+ }
+ else
+ {
+ Py_INCREF(Py_NotImplemented);
+ return Py_NotImplemented;
+ }
+
+ return result;
}
static PyObject *
check2i(SecurityProxy *self, PyObject *other,
- char *opname, binaryfunc operation)
+ PyObject *opname, binaryfunc operation)
{
- PyObject *result = NULL;
- PyObject *object = Proxy_GetObject(self);
- PyObject *checker = Proxy_GetChecker(self);
+ PyObject *result = NULL;
- if (check(checker, opname, object)) {
- result = operation(object, other);
- if (result == object) {
- /* If the operation was really carried out inplace,
- don't create a new proxy, but use the old one. */
- Py_DECREF(object);
- Py_INCREF((PyObject *)self);
- result = (PyObject *)self;
- }
- else if (result != NULL)
- result = PyObject_CallMethod(checker, "proxy",
- "(N)", result);
- }
- return result;
+ if (check(self, str_check, opname) >= 0)
+ {
+ result = operation(self->proxy.proxy_object, other);
+ if (result == self->proxy.proxy_object)
+ {
+ /* If the operation was really carried out inplace,
+ don't create a new proxy, but use the old one. */
+ Py_DECREF(result);
+ Py_INCREF((PyObject *)self);
+ result = (PyObject *)self;
+ }
+ else
+ PROXY_RESULT(self, result);
+ }
+ return result;
}
#define UNOP(NAME, CALL) \
static PyObject *proxy_##NAME(PyObject *self) \
- { return check1((SecurityProxy *)self, "__"#NAME"__", CALL); }
+ { return check1((SecurityProxy *)self, str_op_##NAME, CALL); }
#define BINOP(NAME, CALL) \
static PyObject *proxy_##NAME(PyObject *self, PyObject *other) \
- { return check2(self, other, "__"#NAME"__", "__r"#NAME"__", CALL); }
+ { return check2(self, other, str_op_##NAME, str_op_r##NAME, CALL); }
#define INPLACE(NAME, CALL) \
static PyObject *proxy_i##NAME(PyObject *self, PyObject *other) \
- { return check2i((SecurityProxy *)self, other, "__i"#NAME"__", CALL); }
+ { return check2i((SecurityProxy *)self, other, str_op_i##NAME, CALL); }
/*
@@ -164,23 +227,23 @@
static PyObject *
proxy_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
{
- static char *kwlist[] = {"object", "checker", 0};
- SecurityProxy *self;
- PyObject *object;
- PyObject *checker;
+ static char *kwlist[] = {"object", "checker", 0};
+ SecurityProxy *self;
+ PyObject *object;
+ PyObject *checker;
- if (!PyArg_ParseTupleAndKeywords(args, kwds,
- "OO:_Proxy.__new__", kwlist,
- &object, &checker))
- return NULL;
- self = (SecurityProxy *)type->tp_alloc(type, 0);
- if (self == NULL)
- return NULL;
- Py_INCREF(object);
- Py_INCREF(checker);
- self->proxy.proxy_object = object;
- self->proxy_checker = checker;
- return (PyObject *)self;
+ if (!PyArg_ParseTupleAndKeywords(args, kwds,
+ "OO:_Proxy.__new__", kwlist,
+ &object, &checker))
+ return NULL;
+ self = (SecurityProxy *)type->tp_alloc(type, 0);
+ if (self == NULL)
+ return NULL;
+ Py_INCREF(object);
+ Py_INCREF(checker);
+ self->proxy.proxy_object = object;
+ self->proxy_checker = checker;
+ return (PyObject *)self;
}
/* This is needed to avoid calling the base class tp_init, which we
@@ -188,293 +251,226 @@
static int
proxy_init(PyObject *self, PyObject *args, PyObject *kw)
{
- return 0;
+ return 0;
}
+static int
+proxy_clear(SecurityProxy *self)
+{
+ CLEAR(self->proxy_checker);
+ SecurityProxyType.tp_base->tp_clear((PyObject*)self);
+ return 0;
+}
+
static void
-proxy_dealloc(PyObject *self)
+proxy_dealloc(SecurityProxy *self)
{
- Py_DECREF(Proxy_GetChecker(self));
- SecurityProxyType.tp_base->tp_dealloc(self);
+ proxy_clear(self);
+ SecurityProxyType.tp_base->tp_dealloc((PyObject*)self);
}
static int
-proxy_traverse(PyObject *self, visitproc visit, void *arg)
+proxy_traverse(SecurityProxy *self, visitproc visit, void *arg)
{
- int err = visit(Proxy_GetObject(self), arg);
- if (err == 0)
- err = visit(Proxy_GetChecker(self), arg);
- return err;
+ if (visit(self->proxy.proxy_object, arg) < 0)
+ return -1;
+ if (visit(self->proxy_checker, arg) < 0)
+ return -1;
+ return 0;
}
/* Map rich comparison operators to their __xx__ namesakes */
-static char *name_op[] = {
- "__lt__",
- "__le__",
- "__eq__",
- "__ne__",
- "__gt__",
- "__ge__",
-};
+static PyObject *name_op[6];
static PyObject *
-proxy_richcompare(PyObject* self, PyObject* other, int op)
+proxy_richcompare(SecurityProxy* self, PyObject* other, int op)
{
- PyObject *result = NULL;
- PyObject *object = Proxy_GetObject(self);
- PyObject *checker = Proxy_GetChecker(self);
+ PyObject *result = NULL;
- if (check(checker, name_op[op], object)) {
- result = PyObject_RichCompare(object, other, op);
- if (result != NULL)
- result = PyObject_CallMethod(
- checker, "proxy", "(N)", result);
- }
- return result;
+ if (check(self, str_check, name_op[op]) >= 0)
+ {
+ result = PyObject_RichCompare(self->proxy.proxy_object, other, op);
+ PROXY_RESULT(self, result);
+ }
+ return result;
}
static PyObject *
-proxy_iter(PyObject *self)
+proxy_iter(SecurityProxy *self)
{
- PyObject *result = NULL;
- PyObject *object = Proxy_GetObject(self);
- PyObject *checker = Proxy_GetChecker(self);
+ PyObject *result = NULL;
- if (check(checker, "__iter__", object)) {
- result = PyObject_GetIter(object);
- if (result != NULL)
- result = PyObject_CallMethod(
- checker, "proxy", "(N)", result);
- }
- return result;
+ if (check(self, str_check, str___iter__) >= 0)
+ {
+ result = PyObject_GetIter(self->proxy.proxy_object);
+ PROXY_RESULT(self, result);
+ }
+ return result;
}
static PyObject *
-proxy_iternext(PyObject *self)
+proxy_iternext(SecurityProxy *self)
{
- PyObject *result = NULL;
- PyObject *object = Proxy_GetObject(self);
- PyObject *checker = Proxy_GetChecker(self);
+ PyObject *result = NULL;
- if (check(checker, "next", object)) {
- result = PyIter_Next(object);
- if (result != NULL)
- result = PyObject_CallMethod(
- checker, "proxy", "(N)", result);
- }
- return result;
+ if (check(self, str_check_getattr, str_next) >= 0)
+ {
+ result = PyIter_Next(self->proxy.proxy_object);
+ PROXY_RESULT(self, result);
+ }
+ return result;
}
static PyObject *
-proxy_getattro(PyObject *self, PyObject *name)
+proxy_getattro(SecurityProxy *self, PyObject *name)
{
- PyObject *result = NULL;
- PyObject *object = Proxy_GetObject(self);
- PyObject *checker = Proxy_GetChecker(self);
+ PyObject *result = NULL;
- if (checkattr(checker, "check_getattr", object, name)) {
- result = PyObject_GetAttr(object, name);
- if (result != NULL)
- result = PyObject_CallMethod(
- checker, "proxy", "(N)", result);
- }
- return result;
+ if (check(self, str_check_getattr, name) >= 0)
+ {
+ result = PyObject_GetAttr(self->proxy.proxy_object, name);
+ PROXY_RESULT(self, result);
+ }
+ return result;
}
static int
-proxy_setattro(PyObject *self, PyObject *name, PyObject *value)
+proxy_setattro(SecurityProxy *self, PyObject *name, PyObject *value)
{
- PyObject *object = Proxy_GetObject(self);
- PyObject *checker = Proxy_GetChecker(self);
-
- if (checkattr(checker, "check_setattr", object, name))
- return PyObject_SetAttr(object, name, value);
- return -1;
+ if (check(self, str_check_setattr, name) >= 0)
+ return PyObject_SetAttr(self->proxy.proxy_object, name, value);
+ return -1;
}
static PyObject *
default_repr(PyObject *object)
{
- PyObject *klass, *name = 0, *module = 0, *result = 0;
- char *sname, *smodule;
+ PyObject *klass, *name = 0, *module = 0, *result = 0;
+ char *sname, *smodule;
- klass = PyObject_GetAttr(object, __class__str);
- if (klass == NULL)
- return NULL;
+ klass = PyObject_GetAttr(object, __class__str);
+ if (klass == NULL)
+ return NULL;
- name = PyObject_GetAttr(klass, __name__str);
- if (name == NULL)
- goto err;
- sname = PyString_AsString(name);
- if (sname == NULL)
- goto err;
+ name = PyObject_GetAttr(klass, __name__str);
+ if (name == NULL)
+ goto err;
+ sname = PyString_AsString(name);
+ if (sname == NULL)
+ goto err;
- module = PyObject_GetAttr(klass, __module__str);
- if (module != NULL) {
- smodule = PyString_AsString(module);
- if (smodule == NULL)
- goto err;
- result = PyString_FromFormat(
- "<security proxied %s.%s instance at %p>",
- smodule, sname, object);
- }
- else {
- PyErr_Clear();
- result = PyString_FromFormat(
- "<security proxied %s instance at %p>",
- sname, object);
- }
+ module = PyObject_GetAttr(klass, __module__str);
+ if (module != NULL) {
+ smodule = PyString_AsString(module);
+ if (smodule == NULL)
+ goto err;
+ result = PyString_FromFormat("<security proxied %s.%s instance at %p>",
+ smodule, sname, object);
+ }
+ else {
+ PyErr_Clear();
+ result = PyString_FromFormat("<security proxied %s instance at %p>",
+ sname, object);
+ }
- err:
- Py_DECREF(klass);
- Py_XDECREF(name);
- Py_XDECREF(module);
-
- return result;
+ err:
+ Py_DECREF(klass);
+ Py_XDECREF(name);
+ Py_XDECREF(module);
+
+ return result;
}
static PyObject *
-proxy_str(PyObject *self)
+proxy_str(SecurityProxy *self)
{
- PyObject *result = NULL;
- PyObject *object = Proxy_GetObject(self);
- PyObject *checker = Proxy_GetChecker(self);
+ PyObject *result = NULL;
- if (check(checker, "__str__", object)) {
- result = PyObject_Str(object);
- }
- else {
- PyErr_Clear();
- result = default_repr(object);
- }
- return result;
+ if (check(self, str_check, str___str__) >= 0)
+ {
+ result = PyObject_Str(self->proxy.proxy_object);
+ }
+ else
+ {
+ PyErr_Clear();
+ result = default_repr(self->proxy.proxy_object);
+ }
+ return result;
}
static PyObject *
-proxy_repr(PyObject *self)
+proxy_repr(SecurityProxy *self)
{
- PyObject *result = NULL;
- PyObject *object = Proxy_GetObject(self);
- PyObject *checker = Proxy_GetChecker(self);
+ PyObject *result = NULL;
- if (check(checker, "__repr__", object)) {
- result = PyObject_Repr(object);
- }
- else {
- PyErr_Clear();
- result = default_repr(object);
- }
- return result;
+ if (check(self, str_check, str___repr__) >= 0) {
+ result = PyObject_Repr(self->proxy.proxy_object);
+ }
+ else {
+ PyErr_Clear();
+ result = default_repr(self->proxy.proxy_object);
+ }
+ return result;
}
static int
-proxy_compare(PyObject *self, PyObject *other)
+proxy_compare(SecurityProxy *self, PyObject *other)
{
- PyObject *object = Proxy_GetObject(self);
- PyObject *checker = Proxy_GetChecker(self);
-
- if (check(checker, "__cmp__", object))
- return PyObject_Compare(object, other);
- return -1;
+ if (check(self, str_check, str___cmp__) >= 0)
+ return PyObject_Compare(self->proxy.proxy_object, other);
+ return -1;
}
static long
-proxy_hash(PyObject *self)
+proxy_hash(SecurityProxy *self)
{
- PyObject *object = Proxy_GetObject(self);
- PyObject *checker = Proxy_GetChecker(self);
-
- if (check(checker, "__hash__", object))
- return PyObject_Hash(object);
- return -1;
+ if (check(self, str_check, str___hash__) >= 0)
+ return PyObject_Hash(self->proxy.proxy_object);
+ return -1;
}
static PyObject *
-proxy_call(PyObject *self, PyObject *args, PyObject *kwds)
+proxy_call(SecurityProxy *self, PyObject *args, PyObject *kwds)
{
- PyObject *result = NULL;
- PyObject *object = Proxy_GetObject(self);
- PyObject *checker = Proxy_GetChecker(self);
+ PyObject *result = NULL;
- if (check(checker, "__call__", object)) {
- result = PyObject_Call(object, args, kwds);
- if (result != NULL)
- result = PyObject_CallMethod(
- checker, "proxy", "(N)", result);
- }
- return result;
+ if (check(self, str_check, str___call__) >= 0)
+ {
+ result = PyObject_Call(self->proxy.proxy_object, args, kwds);
+ PROXY_RESULT(self, result);
+ }
+ return result;
}
/*
* Number methods.
*/
-static PyObject *
-call_int(PyObject *self)
-{
- PyNumberMethods *nb = self->ob_type->tp_as_number;
- if (nb == NULL || nb->nb_int == NULL) {
- PyErr_SetString(PyExc_TypeError,
- "object can't be converted to int");
- return NULL;
- }
- return nb->nb_int(self);
+#define NUMBER_METHOD(M) \
+static PyObject * \
+call_##M(PyObject *self) \
+{ \
+ PyNumberMethods *nb = self->ob_type->tp_as_number; \
+ if (nb == NULL || nb->nb_##M == NULL) { \
+ PyErr_SetString(PyExc_TypeError, \
+ "object can't be converted to " #M); \
+ return NULL; \
+ } \
+ return nb->nb_##M(self); \
}
-static PyObject *
-call_long(PyObject *self)
-{
- PyNumberMethods *nb = self->ob_type->tp_as_number;
- if (nb == NULL || nb->nb_long == NULL) {
- PyErr_SetString(PyExc_TypeError,
- "object can't be converted to long");
- return NULL;
- }
- return nb->nb_long(self);
-}
+NUMBER_METHOD(int)
+NUMBER_METHOD(long)
+NUMBER_METHOD(float)
+NUMBER_METHOD(oct)
+NUMBER_METHOD(hex)
static PyObject *
-call_float(PyObject *self)
-{
- PyNumberMethods *nb = self->ob_type->tp_as_number;
- if (nb == NULL || nb->nb_float== NULL) {
- PyErr_SetString(PyExc_TypeError,
- "object can't be converted to float");
- return NULL;
- }
- return nb->nb_float(self);
-}
-
-static PyObject *
-call_oct(PyObject *self)
-{
- PyNumberMethods *nb = self->ob_type->tp_as_number;
- if (nb == NULL || nb->nb_oct== NULL) {
- PyErr_SetString(PyExc_TypeError,
- "object can't be converted to oct");
- return NULL;
- }
- return nb->nb_oct(self);
-}
-
-static PyObject *
-call_hex(PyObject *self)
-{
- PyNumberMethods *nb = self->ob_type->tp_as_number;
- if (nb == NULL || nb->nb_hex == NULL) {
- PyErr_SetString(PyExc_TypeError,
- "object can't be converted to hex");
- return NULL;
- }
- return nb->nb_hex(self);
-}
-
-static PyObject *
call_ipow(PyObject *self, PyObject *other)
{
- /* PyNumber_InPlacePower has three args. How silly. :-) */
- return PyNumber_InPlacePower(self, other, Py_None);
+ /* PyNumber_InPlacePower has three args. How silly. :-) */
+ return PyNumber_InPlacePower(self, other, Py_None);
}
BINOP(add, PyNumber_Add)
@@ -487,35 +483,41 @@
static PyObject *
proxy_pow(PyObject *self, PyObject *other, PyObject *modulus)
{
- PyObject *result = NULL;
- PyObject *object;
- PyObject *checker;
+ PyObject *result = NULL;
- if (Proxy_Check(self)) {
- object = Proxy_GetObject(self);
- checker = Proxy_GetChecker(self);
- if (check(checker, "__pow__", object))
- result = PyNumber_Power(object, other, modulus);
- }
- else if (Proxy_Check(other)) {
- object = Proxy_GetObject(other);
- checker = Proxy_GetChecker(other);
- if (check(checker, "__rpow__", object))
- result = PyNumber_Power(self, object, modulus);
- }
- else if (modulus != NULL && Proxy_Check(modulus)) {
- object = Proxy_GetObject(modulus);
- checker = Proxy_GetChecker(modulus);
- if (check(checker, "__3pow__", object))
- result = PyNumber_Power(self, other, modulus);
- }
- else {
- Py_INCREF(Py_NotImplemented);
- return Py_NotImplemented;
- }
- if (result != NULL)
- result = PyObject_CallMethod(checker, "proxy", "(N)", result);
- return result;
+ if (Proxy_Check(self))
+ {
+ if (check((SecurityProxy*)self, str_check, str___pow__) >= 0)
+ {
+ result = PyNumber_Power(((SecurityProxy*)self)->proxy.proxy_object,
+ other, modulus);
+ PROXY_RESULT(((SecurityProxy*)self), result);
+ }
+ }
+ else if (Proxy_Check(other))
+ {
+ if (check((SecurityProxy*)other, str_check, str___rpow__) >= 0)
+ {
+ result = PyNumber_Power(self,
+ ((SecurityProxy*)other)->proxy.proxy_object,
+ modulus);
+ PROXY_RESULT(((SecurityProxy*)other), result);
+ }
+ }
+ else if (modulus != NULL && Proxy_Check(modulus))
+ {
+ if (check((SecurityProxy*)modulus, str_check, str___3pow__) >= 0)
+ {
+ result = PyNumber_Power(self, other,
+ ((SecurityProxy*)modulus)->proxy.proxy_object);
+ PROXY_RESULT(((SecurityProxy*)modulus), result);
+ }
+ }
+ else {
+ Py_INCREF(Py_NotImplemented);
+ return Py_NotImplemented;
+ }
+ return result;
}
BINOP(lshift, PyNumber_Lshift)
@@ -527,52 +529,47 @@
static int
proxy_coerce(PyObject **p_self, PyObject **p_other)
{
- PyObject *self = *p_self;
- PyObject *other = *p_other;
- PyObject *object;
- PyObject *checker;
+ PyObject *self = *p_self;
+ PyObject *other = *p_other;
- assert(Proxy_Check(self));
- object = Proxy_GetObject(self);
- checker = Proxy_GetChecker(self);
+ assert(Proxy_Check(self));
- if (check(checker, "__coerce__", object)) {
- PyObject *left = object;
- PyObject *right = other;
- int r;
- r = PyNumber_CoerceEx(&left, &right);
- if (r != 0)
- return r;
- /* Now left and right have been INCREF'ed.
- Any new value that comes out is proxied;
- any unchanged value is left unchanged. */
- if (left == object) {
- /* Keep the old proxy */
- Py_DECREF(left);
- Py_INCREF(self);
- left = self;
- }
- else {
- left = PyObject_CallMethod(checker, "proxy",
- "(N)", left);
- if (left == NULL) {
- Py_DECREF(right);
- return -1;
- }
- }
- if (right != other) {
- right = PyObject_CallMethod(checker, "proxy",
- "(N)", right);
- if (right == NULL) {
- Py_DECREF(left);
- return -1;
- }
- }
- *p_self = left;
- *p_other = right;
- return 0;
- }
- return -1;
+ if (check((SecurityProxy*)self, str_check, str___coerce__) >= 0)
+ {
+ PyObject *left = ((SecurityProxy*)self)->proxy.proxy_object;
+ PyObject *right = other;
+ int r;
+ r = PyNumber_CoerceEx(&left, &right);
+ if (r != 0)
+ return r;
+ /* Now left and right have been INCREF'ed.
+ Any new value that comes out is proxied;
+ any unchanged value is left unchanged. */
+ if (left == ((SecurityProxy*)self)->proxy.proxy_object) {
+ /* Keep the old proxy */
+ Py_DECREF(left);
+ Py_INCREF(self);
+ left = self;
+ }
+ else {
+ PROXY_RESULT(((SecurityProxy*)self), left);
+ if (left == NULL) {
+ Py_DECREF(right);
+ return -1;
+ }
+ }
+ if (right != other) {
+ PROXY_RESULT(((SecurityProxy*)self), right);
+ if (right == NULL) {
+ Py_DECREF(left);
+ return -1;
+ }
+ }
+ *p_self = left;
+ *p_other = right;
+ return 0;
+ }
+ return -1;
}
UNOP(neg, PyNumber_Negative)
@@ -582,12 +579,9 @@
static int
proxy_nonzero(PyObject *self)
{
- PyObject *object = Proxy_GetObject(self);
- PyObject *checker = Proxy_GetChecker(self);
-
- if (check(checker, "__nonzero__", object))
- return PyObject_IsTrue(object);
- return -1;
+ if (check(((SecurityProxy*)self), str_check, str___nonzero__) >= 0)
+ return PyObject_IsTrue(((SecurityProxy*)self)->proxy.proxy_object);
+ return -1;
}
UNOP(invert, PyNumber_Invert)
@@ -619,83 +613,70 @@
*/
static int
-proxy_length(PyObject *self)
+proxy_length(SecurityProxy *self)
{
- PyObject *object = Proxy_GetObject(self);
- PyObject *checker = Proxy_GetChecker(self);
-
- if (check(checker, "__len__", object))
- return PyObject_Length(object);
- return -1;
+ if (check(self, str_check, str___len__) >= 0)
+ return PyObject_Length(self->proxy.proxy_object);
+ return -1;
}
/* sq_item and sq_ass_item may be called by PySequece_{Get,Set}Item(). */
-static PyObject *proxy_getitem(PyObject *, PyObject *);
-static int proxy_setitem(PyObject *, PyObject *, PyObject *);
+static PyObject *proxy_getitem(SecurityProxy *, PyObject *);
+static int proxy_setitem(SecurityProxy *, PyObject *, PyObject *);
static PyObject *
-proxy_igetitem(PyObject *self, int i)
+proxy_igetitem(SecurityProxy *self, int i)
{
- PyObject *key = PyInt_FromLong(i);
- PyObject *res = NULL;
+ PyObject *key = PyInt_FromLong(i);
+ PyObject *res = NULL;
- if (key != NULL) {
- res = proxy_getitem(self, key);
- Py_DECREF(key);
- }
- return res;
+ if (key != NULL) {
+ res = proxy_getitem(self, key);
+ Py_DECREF(key);
+ }
+ return res;
}
static int
-proxy_isetitem(PyObject *self, int i, PyObject *value)
+proxy_isetitem(SecurityProxy *self, int i, PyObject *value)
{
- PyObject *key = PyInt_FromLong(i);
- int res = -1;
+ PyObject *key = PyInt_FromLong(i);
+ int res = -1;
- if (key != NULL) {
- res = proxy_setitem(self, key, value);
- Py_DECREF(key);
- }
- return res;
+ if (key != NULL) {
+ res = proxy_setitem(self, key, value);
+ Py_DECREF(key);
+ }
+ return res;
}
static PyObject *
-proxy_slice(PyObject *self, int start, int end)
+proxy_slice(SecurityProxy *self, int start, int end)
{
- PyObject *result = NULL;
- PyObject *object = Proxy_GetObject(self);
- PyObject *checker = Proxy_GetChecker(self);
+ PyObject *result = NULL;
- if (check(checker, "__getslice__", object)) {
- result = PySequence_GetSlice(object, start, end);
- if (result != NULL)
- result = PyObject_CallMethod(
- checker, "proxy", "(N)", result);
- }
- return result;
+ if (check(self, str_check, str___getslice__) >= 0) {
+ result = PySequence_GetSlice(self->proxy.proxy_object, start, end);
+ PROXY_RESULT(self, result);
+ }
+ return result;
}
static int
-proxy_ass_slice(PyObject *self, int i, int j, PyObject *value)
+proxy_ass_slice(SecurityProxy *self, int i, int j, PyObject *value)
{
- PyObject *object = Proxy_GetObject(self);
- PyObject *checker = Proxy_GetChecker(self);
-
- if (check(checker, "__setslice__", object))
- return PySequence_SetSlice(object, i, j, value);
- return -1;
+ if (check(self, str_check, str___setslice__) >= 0)
+ return PySequence_SetSlice(self->proxy.proxy_object, i, j, value);
+ return -1;
}
static int
-proxy_contains(PyObject *self, PyObject *value)
+proxy_contains(SecurityProxy *self, PyObject *value)
{
- PyObject *object = Proxy_GetObject(self);
- PyObject *checker = Proxy_GetChecker(self);
-
- if (check(checker, "__contains__", object))
- return PySequence_Contains(object, value);
- return -1;
+ if (check(self, str_check, str___contains__) >= 0)
+ return PySequence_Contains(self->proxy.proxy_object, value);
+ return -1;
}
/*
@@ -703,36 +684,30 @@
*/
static PyObject *
-proxy_getitem(PyObject *self, PyObject *key)
+proxy_getitem(SecurityProxy *self, PyObject *key)
{
- PyObject *result = NULL;
- PyObject *object = Proxy_GetObject(self);
- PyObject *checker = Proxy_GetChecker(self);
+ PyObject *result = NULL;
- if (check(checker, "__getitem__", object)) {
- result = PyObject_GetItem(object, key);
- if (result != NULL)
- result = PyObject_CallMethod(
- checker, "proxy", "(N)", result);
- }
- return result;
+ if (check(self, str_check, str___getitem__) >= 0)
+ {
+ result = PyObject_GetItem(self->proxy.proxy_object, key);
+ PROXY_RESULT(self, result);
+ }
+ return result;
}
static int
-proxy_setitem(PyObject *self, PyObject *key, PyObject *value)
+proxy_setitem(SecurityProxy *self, PyObject *key, PyObject *value)
{
- PyObject *object = Proxy_GetObject(self);
- PyObject *checker = Proxy_GetChecker(self);
-
- if (value == NULL) {
- if (check(checker, "__delitem__", object))
- return PyObject_DelItem(object, key);
- }
- else {
- if (check(checker, "__setitem__", object))
- return PyObject_SetItem(object, key, value);
- }
- return -1;
+ if (value == NULL) {
+ if (check(self, str_check, str___delitem__) >= 0)
+ return PyObject_DelItem(self->proxy.proxy_object, key);
+ }
+ else {
+ if (check(self, str_check, str___setitem__) >= 0)
+ return PyObject_SetItem(self->proxy.proxy_object, key, value);
+ }
+ return -1;
}
/*
@@ -789,21 +764,21 @@
static PySequenceMethods
proxy_as_sequence = {
- proxy_length, /* sq_length */
- 0, /* sq_concat */
- 0, /* sq_repeat */
- proxy_igetitem, /* sq_item */
- proxy_slice, /* sq_slice */
- proxy_isetitem, /* sq_ass_item */
- proxy_ass_slice, /* sq_ass_slice */
- proxy_contains, /* sq_contains */
+ (inquiry)proxy_length, /* sq_length */
+ 0, /* sq_concat */
+ 0, /* sq_repeat */
+ (intargfunc)proxy_igetitem, /* sq_item */
+ (intintargfunc)proxy_slice, /* sq_slice */
+ (intobjargproc)proxy_isetitem, /* sq_ass_item */
+ (intintobjargproc)proxy_ass_slice, /* sq_ass_slice */
+ (objobjproc)proxy_contains, /* sq_contains */
};
static PyMappingMethods
proxy_as_mapping = {
- proxy_length, /* mp_length */
- proxy_getitem, /* mp_subscript */
- proxy_setitem, /* mp_ass_subscript */
+ (inquiry)proxy_length, /* mp_length */
+ (binaryfunc)proxy_getitem, /* mp_subscript */
+ (objobjargproc)proxy_setitem, /* mp_ass_subscript */
};
static char proxy_doc[] = "\
@@ -822,43 +797,43 @@
statichere PyTypeObject
SecurityProxyType = {
- PyObject_HEAD_INIT(NULL)
- 0,
- "zope.security._proxy._Proxy",
- sizeof(SecurityProxy),
- 0,
- proxy_dealloc, /* tp_dealloc */
- 0, /* tp_print */
- 0, /* tp_getattr */
- 0, /* tp_setattr */
- proxy_compare, /* tp_compare */
- proxy_repr, /* tp_repr */
- &proxy_as_number, /* tp_as_number */
- &proxy_as_sequence, /* tp_as_sequence */
- &proxy_as_mapping, /* tp_as_mapping */
- proxy_hash, /* tp_hash */
- proxy_call, /* tp_call */
- proxy_str, /* tp_str */
- proxy_getattro, /* tp_getattro */
- proxy_setattro, /* tp_setattro */
- 0, /* tp_as_buffer */
- Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_CHECKTYPES |
- Py_TPFLAGS_HAVE_GC, /* tp_flags */
- proxy_doc, /* tp_doc */
- proxy_traverse, /* tp_traverse */
- 0, /* tp_clear */
- proxy_richcompare, /* tp_richcompare */
- 0, /* tp_weaklistoffset */
- proxy_iter, /* tp_iter */
- proxy_iternext, /* tp_iternext */
- 0, /* tp_methods */
- 0, /* tp_members */
- 0, /* tp_getset */
- 0, /* tp_base */
- 0, /* tp_dict */
- 0, /* tp_descr_get */
- 0, /* tp_descr_set */
- 0, /* tp_dictoffset */
+ PyObject_HEAD_INIT(NULL)
+ 0,
+ "zope.security._proxy._Proxy",
+ sizeof(SecurityProxy),
+ 0,
+ (destructor)proxy_dealloc, /* tp_dealloc */
+ 0, /* tp_print */
+ 0, /* tp_getattr */
+ 0, /* tp_setattr */
+ (cmpfunc)proxy_compare, /* tp_compare */
+ (reprfunc)proxy_repr, /* tp_repr */
+ &proxy_as_number, /* tp_as_number */
+ &proxy_as_sequence, /* tp_as_sequence */
+ &proxy_as_mapping, /* tp_as_mapping */
+ (hashfunc)proxy_hash, /* tp_hash */
+ (ternaryfunc)proxy_call, /* tp_call */
+ (reprfunc)proxy_str, /* tp_str */
+ (getattrofunc)proxy_getattro, /* tp_getattro */
+ (setattrofunc)proxy_setattro, /* tp_setattro */
+ 0, /* tp_as_buffer */
+ Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_CHECKTYPES |
+ Py_TPFLAGS_HAVE_GC, /* tp_flags */
+ proxy_doc, /* tp_doc */
+ (traverseproc)proxy_traverse, /* tp_traverse */
+ 0, /* tp_clear */
+ (richcmpfunc)proxy_richcompare, /* tp_richcompare */
+ 0, /* tp_weaklistoffset */
+ (getiterfunc)proxy_iter, /* tp_iter */
+ (iternextfunc)proxy_iternext, /* tp_iternext */
+ 0, /* tp_methods */
+ 0, /* tp_members */
+ 0, /* tp_getset */
+ 0, /* tp_base */
+ 0, /* tp_dict */
+ 0, /* tp_descr_get */
+ 0, /* tp_descr_set */
+ 0, /* tp_dictoffset */
proxy_init, /* tp_init */
0, /*PyType_GenericAlloc,*/ /* tp_alloc */
proxy_new, /* tp_new */
@@ -868,22 +843,22 @@
static PyObject *
module_getChecker(PyObject *self, PyObject *arg)
{
- PyObject *result;
+ PyObject *result;
- if (!Proxy_Check(arg)) {
- PyErr_SetString(PyExc_TypeError,
- "getChecker argument must be a _Proxy");
- return NULL;
- }
- result = Proxy_GetChecker(arg);
- Py_INCREF(result);
- return result;
+ if (!Proxy_Check(arg)) {
+ PyErr_SetString(PyExc_TypeError,
+ "getChecker argument must be a _Proxy");
+ return NULL;
+ }
+ result = ((SecurityProxy*)arg)->proxy_checker;
+ Py_INCREF(result);
+ return result;
}
static PyMethodDef
module_functions[] = {
- {"getChecker", module_getChecker, METH_O, "get checker from proxy"},
- {NULL}
+ {"getChecker", module_getChecker, METH_O, "get checker from proxy"},
+ {NULL}
};
static char
@@ -892,31 +867,116 @@
void
init_proxy(void)
{
- PyObject *m;
+ PyObject *m;
- if (Proxy_Import() < 0)
- return;
+ if (Proxy_Import() < 0)
+ return;
- __class__str = PyString_FromString("__class__");
- if (! __class__str) return;
+ name_op[0] = PyString_FromString("__lt__");
+ name_op[1] = PyString_FromString("__le__");
+ name_op[2] = PyString_FromString("__eq__");
+ name_op[3] = PyString_FromString("__ne__");
+ name_op[4] = PyString_FromString("__gt__");
+ name_op[5] = PyString_FromString("__ge__");
- __name__str = PyString_FromString("__name__");
- if (! __name__str) return;
+#define INIT_STRING(S) \
+if((str_##S = PyString_InternFromString(#S)) == NULL) return
+#define INIT_STRING_OP(S) \
+if((str_op_##S = PyString_InternFromString("__" #S "__")) == NULL) return
- __module__str = PyString_FromString("__module__");
- if (! __module__str) return;
+ INIT_STRING(__3pow__);
+ INIT_STRING(__call__);
+ INIT_STRING(check);
+ INIT_STRING(check_getattr);
+ INIT_STRING(check_setattr);
+ INIT_STRING(__cmp__);
+ INIT_STRING(__coerce__);
+ INIT_STRING(__contains__);
+ INIT_STRING(__delitem__);
+ INIT_STRING(__getitem__);
+ INIT_STRING(__getslice__);
+ INIT_STRING(__hash__);
+ INIT_STRING(__iter__);
+ INIT_STRING(__len__);
+ INIT_STRING(next);
+ INIT_STRING(__nonzero__);
+ INIT_STRING_OP(abs);
+ INIT_STRING_OP(add);
+ INIT_STRING_OP(and);
+ INIT_STRING_OP(div);
+ INIT_STRING_OP(divmod);
+ INIT_STRING_OP(float);
+ INIT_STRING_OP(floordiv);
+ INIT_STRING_OP(hex);
+ INIT_STRING_OP(iadd);
+ INIT_STRING_OP(iand);
+ INIT_STRING_OP(idiv);
+ INIT_STRING_OP(ifloordiv);
+ INIT_STRING_OP(ilshift);
+ INIT_STRING_OP(imod);
+ INIT_STRING_OP(imul);
+ INIT_STRING_OP(int);
+ INIT_STRING_OP(invert);
+ INIT_STRING_OP(ior);
+ INIT_STRING_OP(ipow);
+ INIT_STRING_OP(irshift);
+ INIT_STRING_OP(isub);
+ INIT_STRING_OP(itruediv);
+ INIT_STRING_OP(ixor);
+ INIT_STRING_OP(long);
+ INIT_STRING_OP(lshift);
+ INIT_STRING_OP(mod);
+ INIT_STRING_OP(mul);
+ INIT_STRING_OP(neg);
+ INIT_STRING_OP(oct);
+ INIT_STRING_OP(or);
+ INIT_STRING_OP(pos);
+ INIT_STRING_OP(radd);
+ INIT_STRING_OP(rand);
+ INIT_STRING_OP(rdiv);
+ INIT_STRING_OP(rdivmod);
+ INIT_STRING_OP(rfloordiv);
+ INIT_STRING_OP(rlshift);
+ INIT_STRING_OP(rmod);
+ INIT_STRING_OP(rmul);
+ INIT_STRING_OP(ror);
+ INIT_STRING_OP(rrshift);
+ INIT_STRING_OP(rshift);
+ INIT_STRING_OP(rsub);
+ INIT_STRING_OP(rtruediv);
+ INIT_STRING_OP(rxor);
+ INIT_STRING_OP(sub);
+ INIT_STRING_OP(truediv);
+ INIT_STRING_OP(xor);
+ INIT_STRING(__pow__);
+ INIT_STRING(proxy);
+ INIT_STRING(__repr__);
+ INIT_STRING(__rpow__);
+ INIT_STRING(__setitem__);
+ INIT_STRING(__setslice__);
+ INIT_STRING(__str__);
+
- SecurityProxyType.ob_type = &PyType_Type;
- SecurityProxyType.tp_alloc = PyType_GenericAlloc;
- SecurityProxyType.tp_free = _PyObject_GC_Del;
- SecurityProxyType.tp_base = &ProxyType;
- if (PyType_Ready(&SecurityProxyType) < 0)
- return;
-
- m = Py_InitModule3("_proxy", module_functions, module___doc__);
- if (m == NULL)
- return;
-
- Py_INCREF(&SecurityProxyType);
- PyModule_AddObject(m, "_Proxy", (PyObject *)&SecurityProxyType);
+ __class__str = PyString_FromString("__class__");
+ if (! __class__str) return;
+
+ __name__str = PyString_FromString("__name__");
+ if (! __name__str) return;
+
+ __module__str = PyString_FromString("__module__");
+ if (! __module__str) return;
+
+ SecurityProxyType.ob_type = &PyType_Type;
+ SecurityProxyType.tp_alloc = PyType_GenericAlloc;
+ SecurityProxyType.tp_free = _PyObject_GC_Del;
+ SecurityProxyType.tp_base = &ProxyType;
+ if (PyType_Ready(&SecurityProxyType) < 0)
+ return;
+
+ m = Py_InitModule3("_proxy", module_functions, module___doc__);
+ if (m == NULL)
+ return;
+
+ Py_INCREF(&SecurityProxyType);
+ PyModule_AddObject(m, "_Proxy", (PyObject *)&SecurityProxyType);
}
More information about the Zope3-Checkins
mailing list