Commit 7fac324f authored by Albertas Agejevas's avatar Albertas Agejevas

Replaced _zope_proxy_proxy.c with a new version.

This one comes from zope.proxy commit 2938c335, version 4.1.2dev.
parent 000a5a03
...@@ -14,7 +14,7 @@ ...@@ -14,7 +14,7 @@
/* /*
* This file is also used as a really extensive macro in * This file is also used as a really extensive macro in
* ../app/container/_zope_container_contained.c. If you need to * ../container/_zope_container_contained.c. If you need to
* change this file, you need to "svn copy" it to ../container/. * change this file, you need to "svn copy" it to ../container/.
* *
* This approach is taken to allow the sources for the two packages * This approach is taken to allow the sources for the two packages
...@@ -28,7 +28,7 @@ ...@@ -28,7 +28,7 @@
#include "modsupport.h" #include "modsupport.h"
#define PROXY_MODULE #define PROXY_MODULE
#include "zope.proxy/proxy.h" #include "proxy.h"
static PyTypeObject ProxyType; static PyTypeObject ProxyType;
...@@ -38,6 +38,47 @@ static PyObject * ...@@ -38,6 +38,47 @@ static PyObject *
empty_tuple = NULL; empty_tuple = NULL;
#if PY_VERSION_HEX < 0x02070000
#define PyCapsule_New(pointer, name, destr) \
PyCObject_FromVoidPtr(pointer, destr)
#endif
// Compatibility with Python 2
#if PY_MAJOR_VERSION < 3
#define IS_STRING PyString_Check
#define MAKE_STRING(name) PyString_AS_STRING(name)
#define MOD_ERROR_VAL
#define MOD_SUCCESS_VAL(val)
#define MOD_INIT(name) void init##name(void)
#define MOD_DEF(ob, name, doc, methods) \
ob = Py_InitModule3(name, methods, doc);
#else
#define IS_STRING PyUnicode_Check
#define MAKE_STRING(name) PyBytes_AS_STRING( \
PyUnicode_AsUTF8String(name))
#define MOD_ERROR_VAL NULL
#define MOD_SUCCESS_VAL(val) val
#define MOD_INIT(name) PyMODINIT_FUNC PyInit_##name(void)
#define MOD_DEF(ob, name, doc, methods) \
static struct PyModuleDef moduledef = { \
PyModuleDef_HEAD_INIT, name, doc, -1, methods, }; \
ob = PyModule_Create(&moduledef);
#endif
/* /*
* Slot methods. * Slot methods.
*/ */
...@@ -166,19 +207,23 @@ WrapperType_Lookup(PyTypeObject *type, PyObject *name) ...@@ -166,19 +207,23 @@ WrapperType_Lookup(PyTypeObject *type, PyObject *name)
assert(PyTuple_Check(mro)); assert(PyTuple_Check(mro));
n = PyTuple_GET_SIZE(mro) n = PyTuple_GET_SIZE(mro)
- 1; /* We don't want to look at the last item, which is object. */ - 1; /* We don't want to look at the last item, which is object. */
for (i = 0; i < n; i++) { for (i = 0; i < n; i++) {
base = PyTuple_GET_ITEM(mro, i); base = PyTuple_GET_ITEM(mro, i);
if (((PyTypeObject *)base) != &ProxyType) { if (((PyTypeObject *)base) != &ProxyType) {
#if PY_MAJOR_VERSION < 3
if (PyClass_Check(base)) if (PyClass_Check(base))
dict = ((PyClassObject *)base)->cl_dict; dict = ((PyClassObject *)base)->cl_dict;
else { else
#endif
{
assert(PyType_Check(base)); assert(PyType_Check(base));
dict = ((PyTypeObject *)base)->tp_dict; dict = ((PyTypeObject *)base)->tp_dict;
} }
assert(dict && PyDict_Check(dict)); assert(dict && PyDict_Check(dict));
res = PyDict_GetItem(dict, name); res = PyDict_GetItem(dict, name);
if (res != NULL) if (res != NULL)
...@@ -195,13 +240,13 @@ wrap_getattro(PyObject *self, PyObject *name) ...@@ -195,13 +240,13 @@ wrap_getattro(PyObject *self, PyObject *name)
PyObject *wrapped; PyObject *wrapped;
PyObject *descriptor; PyObject *descriptor;
PyObject *res = NULL; PyObject *res = NULL;
char *name_as_string; const char *name_as_string;
int maybe_special_name; int maybe_special_name;
#ifdef Py_USING_UNICODE #if PY_MAJOR_VERSION < 3 && defined(Py_USING_UNICODE)
/* The Unicode to string conversion is done here because the /* The Unicode to string conversion is done here because the
existing tp_getattro slots expect a string object as name existing tp_setattro slots expect a string object as name
and we wouldn't want to break those. */ (except under Python 3) and we wouldn't want to break those. */
if (PyUnicode_Check(name)) { if (PyUnicode_Check(name)) {
name = PyUnicode_AsEncodedString(name, NULL, NULL); name = PyUnicode_AsEncodedString(name, NULL, NULL);
if (name == NULL) if (name == NULL)
...@@ -209,14 +254,16 @@ wrap_getattro(PyObject *self, PyObject *name) ...@@ -209,14 +254,16 @@ wrap_getattro(PyObject *self, PyObject *name)
} }
else else
#endif #endif
if (!PyString_Check(name)){
if (!IS_STRING(name)){
PyErr_SetString(PyExc_TypeError, "attribute name must be string"); PyErr_SetString(PyExc_TypeError, "attribute name must be string");
return NULL; return NULL;
} }
else else
Py_INCREF(name); Py_INCREF(name);
name_as_string = PyString_AS_STRING(name); name_as_string = MAKE_STRING(name);
wrapped = Proxy_GET_OBJECT(self); wrapped = Proxy_GET_OBJECT(self);
if (wrapped == NULL) { if (wrapped == NULL) {
PyErr_Format(PyExc_RuntimeError, PyErr_Format(PyExc_RuntimeError,
...@@ -232,16 +279,33 @@ wrap_getattro(PyObject *self, PyObject *name) ...@@ -232,16 +279,33 @@ wrap_getattro(PyObject *self, PyObject *name)
descriptor = WrapperType_Lookup(self->ob_type, name); descriptor = WrapperType_Lookup(self->ob_type, name);
if (descriptor != NULL) { if (descriptor != NULL) {
if (PyType_HasFeature(descriptor->ob_type, Py_TPFLAGS_HAVE_CLASS) if (descriptor->ob_type->tp_descr_get != NULL
&& descriptor->ob_type->tp_descr_get != NULL) { #if PY_MAJOR_VERSION < 3 // Always true in Python 3
&& PyType_HasFeature(descriptor->ob_type, Py_TPFLAGS_HAVE_CLASS)
#endif
){
if (descriptor->ob_type->tp_descr_set == NULL)
{
res = PyObject_GetAttr(wrapped, name);
if (res != NULL)
goto finally;
if (PyErr_ExceptionMatches(PyExc_AttributeError))
PyErr_Clear();
else
goto finally;
}
res = descriptor->ob_type->tp_descr_get( res = descriptor->ob_type->tp_descr_get(
descriptor, descriptor,
self, self,
(PyObject *)self->ob_type); (PyObject *)self->ob_type);
} else { }
else
{
Py_INCREF(descriptor); Py_INCREF(descriptor);
res = descriptor; res = descriptor;
} }
goto finally; goto finally;
} }
} }
...@@ -257,12 +321,14 @@ wrap_setattro(PyObject *self, PyObject *name, PyObject *value) ...@@ -257,12 +321,14 @@ wrap_setattro(PyObject *self, PyObject *name, PyObject *value)
{ {
PyObject *wrapped; PyObject *wrapped;
PyObject *descriptor; PyObject *descriptor;
const char *name_as_string;
int res = -1; int res = -1;
#ifdef Py_USING_UNICODE #if PY_MAJOR_VERSION < 3 && defined(Py_USING_UNICODE)
/* The Unicode to string conversion is done here because the /* The Unicode to string conversion is done here because the
existing tp_setattro slots expect a string object as name existing tp_setattro slots expect a string object as name
and we wouldn't want to break those. */ (except under Python 3) and we wouldn't want to break those. */
if (PyUnicode_Check(name)) { if (PyUnicode_Check(name)) {
name = PyUnicode_AsEncodedString(name, NULL, NULL); name = PyUnicode_AsEncodedString(name, NULL, NULL);
if (name == NULL) if (name == NULL)
...@@ -270,7 +336,8 @@ wrap_setattro(PyObject *self, PyObject *name, PyObject *value) ...@@ -270,7 +336,8 @@ wrap_setattro(PyObject *self, PyObject *name, PyObject *value)
} }
else else
#endif #endif
if (!PyString_Check(name)){
if (!IS_STRING(name)){
PyErr_SetString(PyExc_TypeError, "attribute name must be string"); PyErr_SetString(PyExc_TypeError, "attribute name must be string");
return -1; return -1;
} }
...@@ -278,23 +345,24 @@ wrap_setattro(PyObject *self, PyObject *name, PyObject *value) ...@@ -278,23 +345,24 @@ wrap_setattro(PyObject *self, PyObject *name, PyObject *value)
Py_INCREF(name); Py_INCREF(name);
descriptor = WrapperType_Lookup(self->ob_type, name); descriptor = WrapperType_Lookup(self->ob_type, name);
if (descriptor != NULL) {
if (PyType_HasFeature(descriptor->ob_type, Py_TPFLAGS_HAVE_CLASS) && if (descriptor != NULL
descriptor->ob_type->tp_descr_set != NULL) { #if PY_MAJOR_VERSION < 3 // This is always true in Python 3 (I think)
res = descriptor->ob_type->tp_descr_set(descriptor, self, value); && PyType_HasFeature(descriptor->ob_type, Py_TPFLAGS_HAVE_CLASS)
} else { #endif
PyErr_Format(PyExc_TypeError, && descriptor->ob_type->tp_descr_set != NULL)
"Tried to set attribute '%s' on wrapper, but it is not" {
" a data descriptor", PyString_AS_STRING(name)); res = descriptor->ob_type->tp_descr_set(descriptor, self, value);
}
goto finally; goto finally;
} }
name_as_string = MAKE_STRING(name);
wrapped = Proxy_GET_OBJECT(self); wrapped = Proxy_GET_OBJECT(self);
if (wrapped == NULL) { if (wrapped == NULL) {
PyErr_Format(PyExc_RuntimeError, PyErr_Format(PyExc_RuntimeError,
"object is NULL; requested to set attribute '%s'", "object is NULL; requested to set attribute '%s'",
PyString_AS_STRING(name)); name_as_string);
goto finally; goto finally;
} }
res = PyObject_SetAttr(wrapped, name, value); res = PyObject_SetAttr(wrapped, name, value);
...@@ -321,12 +389,13 @@ wrap_repr(PyObject *wrapper) ...@@ -321,12 +389,13 @@ wrap_repr(PyObject *wrapper)
return PyObject_Repr(Proxy_GET_OBJECT(wrapper)); return PyObject_Repr(Proxy_GET_OBJECT(wrapper));
} }
#if PY_MAJOR_VERSION < 3
static int static int
wrap_compare(PyObject *wrapper, PyObject *v) wrap_compare(PyObject *wrapper, PyObject *v)
{ {
return PyObject_Compare(Proxy_GET_OBJECT(wrapper), v); return PyObject_Compare(Proxy_GET_OBJECT(wrapper), v);
} }
#endif
static long static long
wrap_hash(PyObject *self) wrap_hash(PyObject *self)
...@@ -339,15 +408,11 @@ wrap_call(PyObject *self, PyObject *args, PyObject *kw) ...@@ -339,15 +408,11 @@ wrap_call(PyObject *self, PyObject *args, PyObject *kw)
{ {
if (kw) if (kw)
return PyEval_CallObjectWithKeywords(Proxy_GET_OBJECT(self), return PyEval_CallObjectWithKeywords(Proxy_GET_OBJECT(self),
args, kw); args, kw);
else else
return PyObject_CallObject(Proxy_GET_OBJECT(self), args); return PyObject_CallObject(Proxy_GET_OBJECT(self), args);
} }
/*
* Number methods
*/
/* /*
* Number methods. * Number methods.
*/ */
...@@ -364,6 +429,7 @@ call_int(PyObject *self) ...@@ -364,6 +429,7 @@ call_int(PyObject *self)
return nb->nb_int(self); return nb->nb_int(self);
} }
#if PY_MAJOR_VERSION < 3 // Python 3 has no long, oct or hex methods.
static PyObject * static PyObject *
call_long(PyObject *self) call_long(PyObject *self)
{ {
...@@ -376,18 +442,6 @@ call_long(PyObject *self) ...@@ -376,18 +442,6 @@ call_long(PyObject *self)
return nb->nb_long(self); return nb->nb_long(self);
} }
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 * static PyObject *
call_oct(PyObject *self) call_oct(PyObject *self)
{ {
...@@ -412,6 +466,32 @@ call_hex(PyObject *self) ...@@ -412,6 +466,32 @@ call_hex(PyObject *self)
return nb->nb_hex(self); return nb->nb_hex(self);
} }
#endif
static PyObject *
call_index(PyObject *self)
{
PyNumberMethods *nb = self->ob_type->tp_as_number;
if (nb == NULL || nb->nb_index == NULL) {
PyErr_SetString(PyExc_TypeError,
"object can't be converted to index");
return NULL;
}
return nb->nb_index(self);
}
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 * static PyObject *
call_ipow(PyObject *self, PyObject *other) call_ipow(PyObject *self, PyObject *other)
{ {
...@@ -464,10 +544,10 @@ check2(PyObject *self, PyObject *other, ...@@ -464,10 +544,10 @@ check2(PyObject *self, PyObject *other,
static PyObject * static PyObject *
check2i(ProxyObject *self, PyObject *other, check2i(ProxyObject *self, PyObject *other,
char *opname, binaryfunc operation) char *opname, binaryfunc operation)
{ {
PyObject *result = NULL; PyObject *result = NULL;
PyObject *object = Proxy_GET_OBJECT(self); PyObject *object = Proxy_GET_OBJECT(self);
result = operation(object, other); result = operation(object, other);
if (result == object) { if (result == object) {
...@@ -482,25 +562,27 @@ check2i(ProxyObject *self, PyObject *other, ...@@ -482,25 +562,27 @@ check2i(ProxyObject *self, PyObject *other,
/* ??? create proxy for result? */ /* ??? create proxy for result? */
; ;
#endif #endif
return result; return result;
} }
#define UNOP(NAME, CALL) \ #define UNOP(NAME, CALL) \
static PyObject *wrap_##NAME(PyObject *self) \ static PyObject *wrap_##NAME(PyObject *self) \
{ return check1((ProxyObject *)self, "__"#NAME"__", CALL); } { return check1((ProxyObject *)self, "__"#NAME"__", CALL); }
#define BINOP(NAME, CALL) \ #define BINOP(NAME, CALL) \
static PyObject *wrap_##NAME(PyObject *self, PyObject *other) \ static PyObject *wrap_##NAME(PyObject *self, PyObject *other) \
{ return check2(self, other, "__"#NAME"__", "__r"#NAME"__", CALL); } { return check2(self, other, "__"#NAME"__", "__r"#NAME"__", CALL); }
#define INPLACE(NAME, CALL) \ #define INPLACE(NAME, CALL) \
static PyObject *wrap_i##NAME(PyObject *self, PyObject *other) \ static PyObject *wrap_i##NAME(PyObject *self, PyObject *other) \
{ return check2i((ProxyObject *)self, other, "__i"#NAME"__", CALL); } { return check2i((ProxyObject *)self, other, "__i"#NAME"__", CALL); }
BINOP(add, PyNumber_Add) BINOP(add, PyNumber_Add)
BINOP(sub, PyNumber_Subtract) BINOP(sub, PyNumber_Subtract)
BINOP(mul, PyNumber_Multiply) BINOP(mul, PyNumber_Multiply)
#if PY_MAJOR_VERSION < 3 // Python 3 doesn't support the old integer division
BINOP(div, PyNumber_Divide) BINOP(div, PyNumber_Divide)
#endif
BINOP(mod, PyNumber_Remainder) BINOP(mod, PyNumber_Remainder)
BINOP(divmod, PyNumber_Divmod) BINOP(divmod, PyNumber_Divmod)
...@@ -535,6 +617,7 @@ BINOP(and, PyNumber_And) ...@@ -535,6 +617,7 @@ BINOP(and, PyNumber_And)
BINOP(xor, PyNumber_Xor) BINOP(xor, PyNumber_Xor)
BINOP(or, PyNumber_Or) BINOP(or, PyNumber_Or)
#if PY_MAJOR_VERSION < 3 // Coercion is gone in Python 3
static int static int
wrap_coerce(PyObject **p_self, PyObject **p_other) wrap_coerce(PyObject **p_self, PyObject **p_other)
{ {
...@@ -573,6 +656,7 @@ wrap_coerce(PyObject **p_self, PyObject **p_other) ...@@ -573,6 +656,7 @@ wrap_coerce(PyObject **p_self, PyObject **p_other)
*p_other = right; *p_other = right;
return 0; return 0;
} }
#endif
UNOP(neg, PyNumber_Negative) UNOP(neg, PyNumber_Negative)
UNOP(pos, PyNumber_Positive) UNOP(pos, PyNumber_Positive)
...@@ -580,15 +664,19 @@ UNOP(abs, PyNumber_Absolute) ...@@ -580,15 +664,19 @@ UNOP(abs, PyNumber_Absolute)
UNOP(invert, PyNumber_Invert) UNOP(invert, PyNumber_Invert)
UNOP(int, call_int) UNOP(int, call_int)
UNOP(long, call_long)
UNOP(float, call_float) UNOP(float, call_float)
#if PY_MAJOR_VERSION < 3 // Python 3 has no long, oct or hex methods
UNOP(long, call_long)
UNOP(oct, call_oct) UNOP(oct, call_oct)
UNOP(hex, call_hex) UNOP(hex, call_hex)
#endif
INPLACE(add, PyNumber_InPlaceAdd) INPLACE(add, PyNumber_InPlaceAdd)
INPLACE(sub, PyNumber_InPlaceSubtract) INPLACE(sub, PyNumber_InPlaceSubtract)
INPLACE(mul, PyNumber_InPlaceMultiply) INPLACE(mul, PyNumber_InPlaceMultiply)
#if PY_MAJOR_VERSION < 3 // The old integer division operator is gone in Python 3
INPLACE(div, PyNumber_InPlaceDivide) INPLACE(div, PyNumber_InPlaceDivide)
#endif
INPLACE(mod, PyNumber_InPlaceRemainder) INPLACE(mod, PyNumber_InPlaceRemainder)
INPLACE(pow, call_ipow) INPLACE(pow, call_ipow)
INPLACE(lshift, PyNumber_InPlaceLshift) INPLACE(lshift, PyNumber_InPlaceLshift)
...@@ -601,6 +689,7 @@ BINOP(floordiv, PyNumber_FloorDivide) ...@@ -601,6 +689,7 @@ BINOP(floordiv, PyNumber_FloorDivide)
BINOP(truediv, PyNumber_TrueDivide) BINOP(truediv, PyNumber_TrueDivide)
INPLACE(floordiv, PyNumber_InPlaceFloorDivide) INPLACE(floordiv, PyNumber_InPlaceFloorDivide)
INPLACE(truediv, PyNumber_InPlaceTrueDivide) INPLACE(truediv, PyNumber_InPlaceTrueDivide)
UNOP(index, call_index)
static int static int
wrap_nonzero(PyObject *self) wrap_nonzero(PyObject *self)
...@@ -621,13 +710,28 @@ wrap_length(PyObject *self) ...@@ -621,13 +710,28 @@ wrap_length(PyObject *self)
static PyObject * static PyObject *
wrap_slice(PyObject *self, Py_ssize_t start, Py_ssize_t end) wrap_slice(PyObject *self, Py_ssize_t start, Py_ssize_t end)
{ {
return PySequence_GetSlice(Proxy_GET_OBJECT(self), start, end); PyObject *obj = Proxy_GET_OBJECT(self);
if (PyList_Check(obj)) {
return PyList_GetSlice(obj, start, end);
}
else if (PyTuple_Check(obj)) {
return PyTuple_GetSlice(obj, start, end);
}
else {
return PySequence_GetSlice(obj, start, end);
}
} }
static int static int
wrap_ass_slice(PyObject *self, Py_ssize_t i, Py_ssize_t j, PyObject *value) wrap_ass_slice(PyObject *self, Py_ssize_t i, Py_ssize_t j, PyObject *value)
{ {
return PySequence_SetSlice(Proxy_GET_OBJECT(self), i, j, value); PyObject *obj = Proxy_GET_OBJECT(self);
if (PyList_Check(obj)) {
return PyList_SetSlice(obj, i, j, value);
}
else {
return PySequence_SetSlice(obj, i, j, value);
}
} }
static int static int
...@@ -649,9 +753,9 @@ static int ...@@ -649,9 +753,9 @@ static int
wrap_setitem(PyObject *self, PyObject *key, PyObject *value) wrap_setitem(PyObject *self, PyObject *key, PyObject *value)
{ {
if (value == NULL) if (value == NULL)
return PyObject_DelItem(Proxy_GET_OBJECT(self), key); return PyObject_DelItem(Proxy_GET_OBJECT(self), key);
else else
return PyObject_SetItem(Proxy_GET_OBJECT(self), key, value); return PyObject_SetItem(Proxy_GET_OBJECT(self), key, value);
} }
/* /*
...@@ -689,69 +793,82 @@ wrap_reduce(PyObject *self) ...@@ -689,69 +793,82 @@ wrap_reduce(PyObject *self)
static PyNumberMethods static PyNumberMethods
wrap_as_number = { wrap_as_number = {
wrap_add, /* nb_add */ wrap_add, /* nb_add */
wrap_sub, /* nb_subtract */ wrap_sub, /* nb_subtract */
wrap_mul, /* nb_multiply */ wrap_mul, /* nb_multiply */
wrap_div, /* nb_divide */ #if PY_MAJOR_VERSION < 3
wrap_mod, /* nb_remainder */ wrap_div, /* nb_divide */
wrap_divmod, /* nb_divmod */ #endif
wrap_pow, /* nb_power */ wrap_mod, /* nb_remainder */
wrap_neg, /* nb_negative */ wrap_divmod, /* nb_divmod */
wrap_pos, /* nb_positive */ wrap_pow, /* nb_power */
wrap_abs, /* nb_absolute */ wrap_neg, /* nb_negative */
wrap_nonzero, /* nb_nonzero */ wrap_pos, /* nb_positive */
wrap_invert, /* nb_invert */ wrap_abs, /* nb_absolute */
wrap_lshift, /* nb_lshift */ wrap_nonzero, /* nb_nonzero */
wrap_rshift, /* nb_rshift */ wrap_invert, /* nb_invert */
wrap_and, /* nb_and */ wrap_lshift, /* nb_lshift */
wrap_xor, /* nb_xor */ wrap_rshift, /* nb_rshift */
wrap_or, /* nb_or */ wrap_and, /* nb_and */
wrap_coerce, /* nb_coerce */ wrap_xor, /* nb_xor */
wrap_int, /* nb_int */ wrap_or, /* nb_or */
wrap_long, /* nb_long */ #if PY_MAJOR_VERSION < 3
wrap_float, /* nb_float */ wrap_coerce, /* nb_coerce */
wrap_oct, /* nb_oct */ #endif
wrap_hex, /* nb_hex */ wrap_int, /* nb_int */
#if PY_MAJOR_VERSION < 3
wrap_long, /* nb_long */
#else
0, /* formerly known as nb_long */
#endif
wrap_float, /* nb_float */
#if PY_MAJOR_VERSION < 3
wrap_oct, /* nb_oct */
wrap_hex, /* nb_hex */
#endif
/* Added in release 2.0 */ /* Added in release 2.0 */
/* These require the Py_TPFLAGS_HAVE_INPLACEOPS flag */ /* These require the Py_TPFLAGS_HAVE_INPLACEOPS flag */
wrap_iadd, /* nb_inplace_add */ wrap_iadd, /* nb_inplace_add */
wrap_isub, /* nb_inplace_subtract */ wrap_isub, /* nb_inplace_subtract */
wrap_imul, /* nb_inplace_multiply */ wrap_imul, /* nb_inplace_multiply */
wrap_idiv, /* nb_inplace_divide */ #if PY_MAJOR_VERSION < 3
wrap_imod, /* nb_inplace_remainder */ wrap_idiv, /* nb_inplace_divide */
(ternaryfunc)wrap_ipow, /* nb_inplace_power */ #endif
wrap_ilshift, /* nb_inplace_lshift */ wrap_imod, /* nb_inplace_remainder */
wrap_irshift, /* nb_inplace_rshift */ (ternaryfunc)wrap_ipow, /* nb_inplace_power */
wrap_iand, /* nb_inplace_and */ wrap_ilshift, /* nb_inplace_lshift */
wrap_ixor, /* nb_inplace_xor */ wrap_irshift, /* nb_inplace_rshift */
wrap_ior, /* nb_inplace_or */ wrap_iand, /* nb_inplace_and */
wrap_ixor, /* nb_inplace_xor */
wrap_ior, /* nb_inplace_or */
/* Added in release 2.2 */ /* Added in release 2.2 */
/* These require the Py_TPFLAGS_HAVE_CLASS flag */ /* These require the Py_TPFLAGS_HAVE_CLASS flag */
wrap_floordiv, /* nb_floor_divide */ wrap_floordiv, /* nb_floor_divide */
wrap_truediv, /* nb_true_divide */ wrap_truediv, /* nb_true_divide */
wrap_ifloordiv, /* nb_inplace_floor_divide */ wrap_ifloordiv, /* nb_inplace_floor_divide */
wrap_itruediv, /* nb_inplace_true_divide */ wrap_itruediv, /* nb_inplace_true_divide */
wrap_index, /* nb_index */
}; };
static PySequenceMethods static PySequenceMethods
wrap_as_sequence = { wrap_as_sequence = {
wrap_length, /* sq_length */ wrap_length, /* sq_length */
0, /* sq_concat */ 0, /* sq_concat */
0, /* sq_repeat */ 0, /* sq_repeat */
0, /* sq_item */ 0, /* sq_item */
wrap_slice, /* sq_slice */ wrap_slice, /* sq_slice */
0, /* sq_ass_item */ 0, /* sq_ass_item */
wrap_ass_slice, /* sq_ass_slice */ wrap_ass_slice, /* sq_ass_slice */
wrap_contains, /* sq_contains */ wrap_contains, /* sq_contains */
}; };
static PyMappingMethods static PyMappingMethods
wrap_as_mapping = { wrap_as_mapping = {
wrap_length, /* mp_length */ wrap_length, /* mp_length */
wrap_getitem, /* mp_subscript */ wrap_getitem, /* mp_subscript */
wrap_setitem, /* mp_ass_subscript */ wrap_setitem, /* mp_ass_subscript */
}; };
static PyMethodDef static PyMethodDef
...@@ -770,49 +887,61 @@ wrap_methods[] = { ...@@ -770,49 +887,61 @@ wrap_methods[] = {
* be associated with the wrapper itself. * be associated with the wrapper itself.
*/ */
statichere PyTypeObject
static PyTypeObject
ProxyType = { ProxyType = {
PyObject_HEAD_INIT(NULL) /* PyObject_HEAD_INIT(&PyType_Type) */ PyVarObject_HEAD_INIT(NULL, 0)
0,
"zope.proxy.ProxyBase", "zope.proxy.ProxyBase",
sizeof(ProxyObject), sizeof(ProxyObject),
0, 0,
wrap_dealloc, /* tp_dealloc */ wrap_dealloc, /* tp_dealloc */
wrap_print, /* tp_print */ wrap_print, /* tp_print */
0, /* tp_getattr */ 0, /* tp_getattr */
0, /* tp_setattr */ 0, /* tp_setattr */
wrap_compare, /* tp_compare */ #if PY_MAJOR_VERSION < 3
wrap_repr, /* tp_repr */ wrap_compare, /* tp_compare */
&wrap_as_number, /* tp_as_number */ #else
&wrap_as_sequence, /* tp_as_sequence */ 0, /* tp_reserved */
&wrap_as_mapping, /* tp_as_mapping */ #endif
wrap_hash, /* tp_hash */ wrap_repr, /* tp_repr */
wrap_call, /* tp_call */ &wrap_as_number, /* tp_as_number */
wrap_str, /* tp_str */ &wrap_as_sequence, /* tp_as_sequence */
wrap_getattro, /* tp_getattro */ &wrap_as_mapping, /* tp_as_mapping */
wrap_setattro, /* tp_setattro */ wrap_hash, /* tp_hash */
0, /* tp_as_buffer */ wrap_call, /* tp_call */
Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC wrap_str, /* tp_str */
| Py_TPFLAGS_CHECKTYPES | Py_TPFLAGS_BASETYPE, /* tp_flags */ wrap_getattro, /* tp_getattro */
0, /* tp_doc */ wrap_setattro, /* tp_setattro */
wrap_traverse, /* tp_traverse */ 0, /* tp_as_buffer */
wrap_clear, /* tp_clear */ #if PY_MAJOR_VERSION < 3
wrap_richcompare, /* tp_richcompare */ Py_TPFLAGS_DEFAULT |
0, /* tp_weaklistoffset */ Py_TPFLAGS_HAVE_GC |
wrap_iter, /* tp_iter */ Py_TPFLAGS_CHECKTYPES |
wrap_iternext, /* tp_iternext */ Py_TPFLAGS_BASETYPE, /* tp_flags */
wrap_methods, /* tp_methods */ #else // Py_TPFLAGS_CHECKTYPES is always true in Python 3 and removed.
0, /* tp_members */ Py_TPFLAGS_DEFAULT |
0, /* tp_getset */ Py_TPFLAGS_HAVE_GC |
0, /* tp_base */ Py_TPFLAGS_BASETYPE, /* tp_flags */
0, /* tp_dict */ #endif
0, /* tp_descr_get */ 0, /* tp_doc */
0, /* tp_descr_set */ wrap_traverse, /* tp_traverse */
0, /* tp_dictoffset */ wrap_clear, /* tp_clear */
wrap_init, /* tp_init */ wrap_richcompare, /* tp_richcompare */
0, /* tp_alloc */ 0, /* tp_weaklistoffset */
wrap_new, /* tp_new */ wrap_iter, /* tp_iter */
0, /*_PyObject_GC_Del,*/ /* tp_free */ wrap_iternext, /* tp_iternext */
wrap_methods, /* 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 */
wrap_init, /* tp_init */
0, /* tp_alloc */
wrap_new, /* tp_new */
0, /*PyObject_GC_Del,*/ /* tp_free */
}; };
static PyObject * static PyObject *
...@@ -853,14 +982,14 @@ api_getobject(PyObject *proxy) ...@@ -853,14 +982,14 @@ api_getobject(PyObject *proxy)
{ {
if (proxy == NULL) { if (proxy == NULL) {
PyErr_SetString(PyExc_RuntimeError, PyErr_SetString(PyExc_RuntimeError,
"cannot pass NULL to ProxyAPI.getobject()"); "cannot pass NULL to ProxyAPI.getobject()");
return NULL; return NULL;
} }
if (Proxy_Check(proxy)) if (Proxy_Check(proxy))
return Proxy_GET_OBJECT(proxy); return Proxy_GET_OBJECT(proxy);
else { else {
PyErr_Format(PyExc_TypeError, "expected proxy object, got %s", PyErr_Format(PyExc_TypeError, "expected proxy object, got %s",
proxy->ob_type->tp_name); proxy->ob_type->tp_name);
return NULL; return NULL;
} }
} }
...@@ -886,9 +1015,9 @@ getobject__doc__[] = ...@@ -886,9 +1015,9 @@ getobject__doc__[] =
static PyObject * static PyObject *
wrapper_getobject(PyObject *unused, PyObject *obj) wrapper_getobject(PyObject *unused, PyObject *obj)
{ {
if (Proxy_Check(obj)) if (Proxy_Check(obj))
obj = Proxy_GET_OBJECT(obj); obj = Proxy_GET_OBJECT(obj);
if (obj == NULL) if (obj == NULL)
obj = Py_None; obj = Py_None;
...@@ -896,6 +1025,28 @@ wrapper_getobject(PyObject *unused, PyObject *obj) ...@@ -896,6 +1025,28 @@ wrapper_getobject(PyObject *unused, PyObject *obj)
return obj; return obj;
} }
static char
setobject__doc__[] =
"setProxiedObject(proxy, object) --> object\n"
"\n"
"Set the underlying object for proxy, returning the old proxied object.\n"
"Raises TypeError if proxy is not a proxy.\n";
static PyObject *
wrapper_setobject(PyObject *unused, PyObject *args)
{
PyObject *proxy;
PyObject *object;
PyObject *result = NULL;
if (PyArg_ParseTuple(args, "O!O:setProxiedObject",
&ProxyType, &proxy, &object)) {
result = Proxy_GET_OBJECT(proxy);
Py_INCREF(object);
((ProxyObject *) proxy)->proxy_object = object;
}
return result;
}
static char static char
isProxy__doc__[] = isProxy__doc__[] =
"Check whether the given object is a proxy\n" "Check whether the given object is a proxy\n"
...@@ -910,7 +1061,7 @@ wrapper_isProxy(PyObject *unused, PyObject *args) ...@@ -910,7 +1061,7 @@ wrapper_isProxy(PyObject *unused, PyObject *args)
PyObject *obj, *result; PyObject *obj, *result;
PyTypeObject *proxytype=&ProxyType; PyTypeObject *proxytype=&ProxyType;
if (! PyArg_ParseTuple(args, "O|O!:isProxy", if (! PyArg_ParseTuple(args, "O|O!:isProxy",
&obj, &PyType_Type, &proxytype) &obj, &PyType_Type, &proxytype)
) )
return NULL; return NULL;
...@@ -920,7 +1071,7 @@ wrapper_isProxy(PyObject *unused, PyObject *args) ...@@ -920,7 +1071,7 @@ wrapper_isProxy(PyObject *unused, PyObject *args)
if (PyObject_TypeCheck(obj, proxytype)) if (PyObject_TypeCheck(obj, proxytype))
{ {
result = Py_True; result = Py_True;
Py_INCREF(result); Py_INCREF(result);
return result; return result;
} }
obj = Proxy_GET_OBJECT(obj); obj = Proxy_GET_OBJECT(obj);
...@@ -944,9 +1095,9 @@ removeAllProxies__doc__[] = ...@@ -944,9 +1095,9 @@ removeAllProxies__doc__[] =
static PyObject * static PyObject *
wrapper_removeAllProxies(PyObject *unused, PyObject *obj) wrapper_removeAllProxies(PyObject *unused, PyObject *obj)
{ {
while (obj && Proxy_Check(obj)) while (obj && Proxy_Check(obj))
obj = Proxy_GET_OBJECT(obj); obj = Proxy_GET_OBJECT(obj);
if (obj == NULL) if (obj == NULL)
obj = Py_None; obj = Py_None;
...@@ -955,7 +1106,7 @@ wrapper_removeAllProxies(PyObject *unused, PyObject *obj) ...@@ -955,7 +1106,7 @@ wrapper_removeAllProxies(PyObject *unused, PyObject *obj)
} }
static char static char
sameProxiedObjects__doc__[] = sameProxiedObjects__doc__[] =
"Check whether two objects are the same or proxies of the same object"; "Check whether two objects are the same or proxies of the same object";
static PyObject * static PyObject *
...@@ -966,10 +1117,10 @@ wrapper_sameProxiedObjects(PyObject *unused, PyObject *args) ...@@ -966,10 +1117,10 @@ wrapper_sameProxiedObjects(PyObject *unused, PyObject *args)
if (! PyArg_ParseTuple(args, "OO:sameProxiedObjects", &ob1, &ob2)) if (! PyArg_ParseTuple(args, "OO:sameProxiedObjects", &ob1, &ob2))
return NULL; return NULL;
while (ob1 && Proxy_Check(ob1)) while (ob1 && Proxy_Check(ob1))
ob1 = Proxy_GET_OBJECT(ob1); ob1 = Proxy_GET_OBJECT(ob1);
while (ob2 && Proxy_Check(ob2)) while (ob2 && Proxy_Check(ob2))
ob2 = Proxy_GET_OBJECT(ob2); ob2 = Proxy_GET_OBJECT(ob2);
if (ob1 == ob2) if (ob1 == ob2)
...@@ -995,7 +1146,7 @@ wrapper_queryProxy(PyObject *unused, PyObject *args) ...@@ -995,7 +1146,7 @@ wrapper_queryProxy(PyObject *unused, PyObject *args)
PyObject *obj, *result=Py_None; PyObject *obj, *result=Py_None;
PyTypeObject *proxytype=&ProxyType; PyTypeObject *proxytype=&ProxyType;
if (! PyArg_ParseTuple(args, "O|O!O:queryProxy", if (! PyArg_ParseTuple(args, "O|O!O:queryProxy",
&obj, &PyType_Type, &proxytype, &result) &obj, &PyType_Type, &proxytype, &result)
) )
return NULL; return NULL;
...@@ -1029,7 +1180,7 @@ wrapper_queryInnerProxy(PyObject *unused, PyObject *args) ...@@ -1029,7 +1180,7 @@ wrapper_queryInnerProxy(PyObject *unused, PyObject *args)
PyObject *obj, *result=Py_None; PyObject *obj, *result=Py_None;
PyTypeObject *proxytype=&ProxyType; PyTypeObject *proxytype=&ProxyType;
if (! PyArg_ParseTuple(args, "O|O!O:queryInnerProxy", if (! PyArg_ParseTuple(args, "O|O!O:queryInnerProxy",
&obj, &PyType_Type, &proxytype, &result) &obj, &PyType_Type, &proxytype, &result)
) )
return NULL; return NULL;
...@@ -1045,6 +1196,8 @@ wrapper_queryInnerProxy(PyObject *unused, PyObject *args) ...@@ -1045,6 +1196,8 @@ wrapper_queryInnerProxy(PyObject *unused, PyObject *args)
return result; return result;
} }
/* Module initialization */
static char static char
module___doc__[] = module___doc__[] =
"Association between an object, a context object, and a dictionary.\n\ "Association between an object, a context object, and a dictionary.\n\
...@@ -1057,42 +1210,47 @@ act as proxies for the original object."; ...@@ -1057,42 +1210,47 @@ act as proxies for the original object.";
static PyMethodDef static PyMethodDef
module_functions[] = { module_functions[] = {
{"getProxiedObject", wrapper_getobject, METH_O, getobject__doc__}, {"getProxiedObject", wrapper_getobject, METH_O, getobject__doc__},
{"setProxiedObject", wrapper_setobject, METH_VARARGS, setobject__doc__},
{"isProxy", wrapper_isProxy, METH_VARARGS, isProxy__doc__}, {"isProxy", wrapper_isProxy, METH_VARARGS, isProxy__doc__},
{"sameProxiedObjects", wrapper_sameProxiedObjects, METH_VARARGS, {"sameProxiedObjects", wrapper_sameProxiedObjects, METH_VARARGS,
sameProxiedObjects__doc__}, sameProxiedObjects__doc__},
{"queryProxy", wrapper_queryProxy, METH_VARARGS, queryProxy__doc__}, {"queryProxy", wrapper_queryProxy, METH_VARARGS, queryProxy__doc__},
{"queryInnerProxy", wrapper_queryInnerProxy, METH_VARARGS, {"queryInnerProxy", wrapper_queryInnerProxy, METH_VARARGS,
queryInnerProxy__doc__}, queryInnerProxy__doc__},
{"removeAllProxies", wrapper_removeAllProxies, METH_O, {"removeAllProxies", wrapper_removeAllProxies, METH_O,
removeAllProxies__doc__}, removeAllProxies__doc__},
{NULL} {NULL}
}; };
void MOD_INIT(_zope_proxy_proxy)
init_zope_proxy_proxy(void)
{ {
PyObject *m = Py_InitModule3("_zope_proxy_proxy", PyObject *m;
module_functions, module___doc__);
MOD_DEF(m, "_zope_proxy_proxy", module___doc__, module_functions)
if (m == NULL) if (m == NULL)
return; return MOD_ERROR_VAL;
if (empty_tuple == NULL) if (empty_tuple == NULL)
empty_tuple = PyTuple_New(0); empty_tuple = PyTuple_New(0);
ProxyType.tp_free = _PyObject_GC_Del; ProxyType.tp_free = PyObject_GC_Del;
if (PyType_Ready(&ProxyType) < 0) if (PyType_Ready(&ProxyType) < 0)
return; return MOD_ERROR_VAL;
Py_INCREF(&ProxyType); Py_INCREF(&ProxyType);
PyModule_AddObject(m, "ProxyBase", (PyObject *)&ProxyType); PyModule_AddObject(m, "ProxyBase", (PyObject *)&ProxyType);
if (api_object == NULL) { if (api_object == NULL) {
api_object = PyCObject_FromVoidPtr(&wrapper_capi, NULL); api_object = PyCapsule_New(&wrapper_capi, NULL, NULL);
if (api_object == NULL) if (api_object == NULL)
return; return MOD_ERROR_VAL;
} }
Py_INCREF(api_object); Py_INCREF(api_object);
PyModule_AddObject(m, "_CAPI", api_object); PyModule_AddObject(m, "_CAPI", api_object);
return MOD_SUCCESS_VAL(m);
} }
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment