Merge branch 'feature/refactor-adapter-mechanism' into develop

This commit is contained in:
Graham Dumpleton
2013-10-07 13:12:41 +11:00
5 changed files with 183 additions and 222 deletions

View File

@@ -36,6 +36,9 @@ Version 1.2.0
ObjectProxy was being used. The derived class __getattr__() could also
get ignored.
* Using inspect.getargspec() now works correctly on bound methods when an
adapter function can be provided to @decorator.
Version 1.1.3
-------------

View File

@@ -24,7 +24,6 @@ typedef struct {
PyObject *instance;
PyObject *wrapper;
PyObject *adapter;
PyObject *enabled;
PyObject *binding;
PyObject *parent;
@@ -57,10 +56,55 @@ static PyObject *WraptObjectProxy_new(PyTypeObject *type,
static int WraptObjectProxy_raw_init(WraptObjectProxyObject *self,
PyObject *wrapped)
{
static PyObject *module_str = NULL;
static PyObject *doc_str = NULL;
PyObject *object = NULL;
Py_INCREF(wrapped);
Py_XDECREF(self->wrapped);
self->wrapped = wrapped;
if (!module_str) {
#if PY_MAJOR_VERSION >= 3
module_str = PyUnicode_InternFromString("__module__");
#else
module_str = PyString_InternFromString("__module__");
#endif
}
if (!doc_str) {
#if PY_MAJOR_VERSION >= 3
doc_str = PyUnicode_InternFromString("__doc__");
#else
doc_str = PyString_InternFromString("__doc__");
#endif
}
object = PyObject_GetAttr(wrapped, module_str);
if (object) {
if (PyDict_SetItem(self->dict, module_str, object) == -1) {
Py_DECREF(object);
return -1;
}
Py_DECREF(object);
}
else
PyErr_Clear();
object = PyObject_GetAttr(wrapped, doc_str);
if (object) {
if (PyDict_SetItem(self->dict, doc_str, object) == -1) {
Py_DECREF(object);
return -1;
}
Py_DECREF(object);
}
else
PyErr_Clear();
return 0;
}
@@ -116,7 +160,7 @@ static void WraptObjectProxy_dealloc(WraptObjectProxyObject *self)
static PyObject *WraptObjectProxy_repr(WraptObjectProxyObject *self)
{
if (!self->wrapped) {
PyErr_SetString(PyExc_ValueError, "wrapper has not been initialised");
PyErr_SetString(PyExc_ValueError, "wrapper has not been initialized");
return NULL;
}
@@ -136,7 +180,7 @@ static PyObject *WraptObjectProxy_repr(WraptObjectProxyObject *self)
static long WraptObjectProxy_hash(WraptObjectProxyObject *self)
{
if (!self->wrapped) {
PyErr_SetString(PyExc_ValueError, "wrapper has not been initialised");
PyErr_SetString(PyExc_ValueError, "wrapper has not been initialized");
return -1;
}
@@ -149,7 +193,7 @@ static PyObject *WraptObjectProxy_call(
WraptObjectProxyObject *self, PyObject *args, PyObject *kwds)
{
if (!self->wrapped) {
PyErr_SetString(PyExc_ValueError, "wrapper has not been initialised");
PyErr_SetString(PyExc_ValueError, "wrapper has not been initialized");
return NULL;
}
@@ -161,7 +205,7 @@ static PyObject *WraptObjectProxy_call(
static PyObject *WraptObjectProxy_str(WraptObjectProxyObject *self)
{
if (!self->wrapped) {
PyErr_SetString(PyExc_ValueError, "wrapper has not been initialised");
PyErr_SetString(PyExc_ValueError, "wrapper has not been initialized");
return NULL;
}
@@ -268,7 +312,7 @@ static PyObject *WraptObjectProxy_power(PyObject *o1, PyObject *o2,
static PyObject *WraptObjectProxy_negative(WraptObjectProxyObject *self)
{
if (!self->wrapped) {
PyErr_SetString(PyExc_ValueError, "wrapper has not been initialised");
PyErr_SetString(PyExc_ValueError, "wrapper has not been initialized");
return NULL;
}
@@ -280,7 +324,7 @@ static PyObject *WraptObjectProxy_negative(WraptObjectProxyObject *self)
static PyObject *WraptObjectProxy_positive(WraptObjectProxyObject *self)
{
if (!self->wrapped) {
PyErr_SetString(PyExc_ValueError, "wrapper has not been initialised");
PyErr_SetString(PyExc_ValueError, "wrapper has not been initialized");
return NULL;
}
@@ -292,7 +336,7 @@ static PyObject *WraptObjectProxy_positive(WraptObjectProxyObject *self)
static PyObject *WraptObjectProxy_absolute(WraptObjectProxyObject *self)
{
if (!self->wrapped) {
PyErr_SetString(PyExc_ValueError, "wrapper has not been initialised");
PyErr_SetString(PyExc_ValueError, "wrapper has not been initialized");
return NULL;
}
@@ -304,7 +348,7 @@ static PyObject *WraptObjectProxy_absolute(WraptObjectProxyObject *self)
static int WraptObjectProxy_bool(WraptObjectProxyObject *self)
{
if (!self->wrapped) {
PyErr_SetString(PyExc_ValueError, "wrapper has not been initialised");
PyErr_SetString(PyExc_ValueError, "wrapper has not been initialized");
return -1;
}
@@ -316,7 +360,7 @@ static int WraptObjectProxy_bool(WraptObjectProxyObject *self)
static PyObject *WraptObjectProxy_invert(WraptObjectProxyObject *self)
{
if (!self->wrapped) {
PyErr_SetString(PyExc_ValueError, "wrapper has not been initialised");
PyErr_SetString(PyExc_ValueError, "wrapper has not been initialized");
return NULL;
}
@@ -394,7 +438,7 @@ static PyObject *WraptObjectProxy_or(PyObject *o1, PyObject *o2)
static PyObject *WraptObjectProxy_int(WraptObjectProxyObject *self)
{
if (!self->wrapped) {
PyErr_SetString(PyExc_ValueError, "wrapper has not been initialised");
PyErr_SetString(PyExc_ValueError, "wrapper has not been initialized");
return NULL;
}
@@ -407,7 +451,7 @@ static PyObject *WraptObjectProxy_int(WraptObjectProxyObject *self)
static PyObject *WraptObjectProxy_long(WraptObjectProxyObject *self)
{
if (!self->wrapped) {
PyErr_SetString(PyExc_ValueError, "wrapper has not been initialised");
PyErr_SetString(PyExc_ValueError, "wrapper has not been initialized");
return NULL;
}
@@ -419,7 +463,7 @@ static PyObject *WraptObjectProxy_long(WraptObjectProxyObject *self)
static PyObject *WraptObjectProxy_float(WraptObjectProxyObject *self)
{
if (!self->wrapped) {
PyErr_SetString(PyExc_ValueError, "wrapper has not been initialised");
PyErr_SetString(PyExc_ValueError, "wrapper has not been initialized");
return NULL;
}
@@ -434,7 +478,7 @@ static PyObject *WraptObjectProxy_oct(WraptObjectProxyObject *self)
PyNumberMethods *nb;
if (!self->wrapped) {
PyErr_SetString(PyExc_ValueError, "wrapper has not been initialised");
PyErr_SetString(PyExc_ValueError, "wrapper has not been initialized");
return NULL;
}
@@ -457,7 +501,7 @@ static PyObject *WraptObjectProxy_hex(WraptObjectProxyObject *self)
PyNumberMethods *nb;
if (!self->wrapped) {
PyErr_SetString(PyExc_ValueError, "wrapper has not been initialised");
PyErr_SetString(PyExc_ValueError, "wrapper has not been initialized");
return NULL;
}
@@ -480,7 +524,7 @@ static PyObject *WraptObjectProxy_inplace_add(WraptObjectProxyObject *self,
PyObject *object = NULL;
if (!self->wrapped) {
PyErr_SetString(PyExc_ValueError, "wrapper has not been initialised");
PyErr_SetString(PyExc_ValueError, "wrapper has not been initialized");
return NULL;
}
@@ -507,7 +551,7 @@ static PyObject *WraptObjectProxy_inplace_subtract(
PyObject *object = NULL;
if (!self->wrapped) {
PyErr_SetString(PyExc_ValueError, "wrapper has not been initialised");
PyErr_SetString(PyExc_ValueError, "wrapper has not been initialized");
return NULL;
}
@@ -534,7 +578,7 @@ static PyObject *WraptObjectProxy_inplace_multiply(
PyObject *object = NULL;
if (!self->wrapped) {
PyErr_SetString(PyExc_ValueError, "wrapper has not been initialised");
PyErr_SetString(PyExc_ValueError, "wrapper has not been initialized");
return NULL;
}
@@ -562,7 +606,7 @@ static PyObject *WraptObjectProxy_inplace_divide(
PyObject *object = NULL;
if (!self->wrapped) {
PyErr_SetString(PyExc_ValueError, "wrapper has not been initialised");
PyErr_SetString(PyExc_ValueError, "wrapper has not been initialized");
return NULL;
}
@@ -590,7 +634,7 @@ static PyObject *WraptObjectProxy_inplace_remainder(
PyObject *object = NULL;
if (!self->wrapped) {
PyErr_SetString(PyExc_ValueError, "wrapper has not been initialised");
PyErr_SetString(PyExc_ValueError, "wrapper has not been initialized");
return NULL;
}
@@ -617,7 +661,7 @@ static PyObject *WraptObjectProxy_inplace_power(WraptObjectProxyObject *self,
PyObject *object = NULL;
if (!self->wrapped) {
PyErr_SetString(PyExc_ValueError, "wrapper has not been initialised");
PyErr_SetString(PyExc_ValueError, "wrapper has not been initialized");
return NULL;
}
@@ -644,7 +688,7 @@ static PyObject *WraptObjectProxy_inplace_lshift(WraptObjectProxyObject *self,
PyObject *object = NULL;
if (!self->wrapped) {
PyErr_SetString(PyExc_ValueError, "wrapper has not been initialised");
PyErr_SetString(PyExc_ValueError, "wrapper has not been initialized");
return NULL;
}
@@ -671,7 +715,7 @@ static PyObject *WraptObjectProxy_inplace_rshift(WraptObjectProxyObject *self,
PyObject *object = NULL;
if (!self->wrapped) {
PyErr_SetString(PyExc_ValueError, "wrapper has not been initialised");
PyErr_SetString(PyExc_ValueError, "wrapper has not been initialized");
return NULL;
}
@@ -698,7 +742,7 @@ static PyObject *WraptObjectProxy_inplace_and(WraptObjectProxyObject *self,
PyObject *object = NULL;
if (!self->wrapped) {
PyErr_SetString(PyExc_ValueError, "wrapper has not been initialised");
PyErr_SetString(PyExc_ValueError, "wrapper has not been initialized");
return NULL;
}
@@ -725,7 +769,7 @@ static PyObject *WraptObjectProxy_inplace_xor(WraptObjectProxyObject *self,
PyObject *object = NULL;
if (!self->wrapped) {
PyErr_SetString(PyExc_ValueError, "wrapper has not been initialised");
PyErr_SetString(PyExc_ValueError, "wrapper has not been initialized");
return NULL;
}
@@ -752,7 +796,7 @@ static PyObject *WraptObjectProxy_inplace_or(WraptObjectProxyObject *self,
PyObject *object = NULL;
if (!self->wrapped) {
PyErr_SetString(PyExc_ValueError, "wrapper has not been initialised");
PyErr_SetString(PyExc_ValueError, "wrapper has not been initialized");
return NULL;
}
@@ -802,7 +846,7 @@ static PyObject *WraptObjectProxy_inplace_floor_divide(
PyObject *object = NULL;
if (!self->wrapped) {
PyErr_SetString(PyExc_ValueError, "wrapper has not been initialised");
PyErr_SetString(PyExc_ValueError, "wrapper has not been initialized");
return NULL;
}
@@ -829,7 +873,7 @@ static PyObject *WraptObjectProxy_inplace_true_divide(
PyObject *object = NULL;
if (!self->wrapped) {
PyErr_SetString(PyExc_ValueError, "wrapper has not been initialised");
PyErr_SetString(PyExc_ValueError, "wrapper has not been initialized");
return NULL;
}
@@ -853,7 +897,7 @@ static PyObject *WraptObjectProxy_inplace_true_divide(
static PyObject *WraptObjectProxy_index(WraptObjectProxyObject *self)
{
if (!self->wrapped) {
PyErr_SetString(PyExc_ValueError, "wrapper has not been initialised");
PyErr_SetString(PyExc_ValueError, "wrapper has not been initialized");
return NULL;
}
@@ -865,7 +909,7 @@ static PyObject *WraptObjectProxy_index(WraptObjectProxyObject *self)
static Py_ssize_t WraptObjectProxy_length(WraptObjectProxyObject *self)
{
if (!self->wrapped) {
PyErr_SetString(PyExc_ValueError, "wrapper has not been initialised");
PyErr_SetString(PyExc_ValueError, "wrapper has not been initialized");
return -1;
}
@@ -878,7 +922,7 @@ static int WraptObjectProxy_contains(WraptObjectProxyObject *self,
PyObject *value)
{
if (!self->wrapped) {
PyErr_SetString(PyExc_ValueError, "wrapper has not been initialised");
PyErr_SetString(PyExc_ValueError, "wrapper has not been initialized");
return -1;
}
@@ -891,7 +935,7 @@ static PyObject *WraptObjectProxy_getitem(WraptObjectProxyObject *self,
PyObject *key)
{
if (!self->wrapped) {
PyErr_SetString(PyExc_ValueError, "wrapper has not been initialised");
PyErr_SetString(PyExc_ValueError, "wrapper has not been initialized");
return NULL;
}
@@ -904,7 +948,7 @@ static int WraptObjectProxy_setitem(WraptObjectProxyObject *self,
PyObject *key, PyObject* value)
{
if (!self->wrapped) {
PyErr_SetString(PyExc_ValueError, "wrapper has not been initialised");
PyErr_SetString(PyExc_ValueError, "wrapper has not been initialized");
return -1;
}
@@ -920,7 +964,7 @@ static PyObject *WraptObjectProxy_dir(
WraptObjectProxyObject *self, PyObject *args)
{
if (!self->wrapped) {
PyErr_SetString(PyExc_ValueError, "wrapper has not been initialised");
PyErr_SetString(PyExc_ValueError, "wrapper has not been initialized");
return NULL;
}
@@ -936,7 +980,7 @@ static PyObject *WraptObjectProxy_enter(
PyObject *result = NULL;
if (!self->wrapped) {
PyErr_SetString(PyExc_ValueError, "wrapper has not been initialised");
PyErr_SetString(PyExc_ValueError, "wrapper has not been initialized");
return NULL;
}
@@ -961,7 +1005,7 @@ static PyObject *WraptObjectProxy_exit(
PyObject *result = NULL;
if (!self->wrapped) {
PyErr_SetString(PyExc_ValueError, "wrapper has not been initialised");
PyErr_SetString(PyExc_ValueError, "wrapper has not been initialized");
return NULL;
}
@@ -983,7 +1027,7 @@ static PyObject *WraptObjectProxy_get_name(
WraptObjectProxyObject *self)
{
if (!self->wrapped) {
PyErr_SetString(PyExc_ValueError, "wrapper has not been initialised");
PyErr_SetString(PyExc_ValueError, "wrapper has not been initialized");
return NULL;
}
@@ -996,7 +1040,7 @@ static int WraptObjectProxy_set_name(WraptObjectProxyObject *self,
PyObject *value)
{
if (!self->wrapped) {
PyErr_SetString(PyExc_ValueError, "wrapper has not been initialised");
PyErr_SetString(PyExc_ValueError, "wrapper has not been initialized");
return -1;
}
@@ -1009,7 +1053,7 @@ static PyObject *WraptObjectProxy_get_qualname(
WraptObjectProxyObject *self)
{
if (!self->wrapped) {
PyErr_SetString(PyExc_ValueError, "wrapper has not been initialised");
PyErr_SetString(PyExc_ValueError, "wrapper has not been initialized");
return NULL;
}
@@ -1022,7 +1066,7 @@ static int WraptObjectProxy_set_qualname(WraptObjectProxyObject *self,
PyObject *value)
{
if (!self->wrapped) {
PyErr_SetString(PyExc_ValueError, "wrapper has not been initialised");
PyErr_SetString(PyExc_ValueError, "wrapper has not been initialized");
return -1;
}
@@ -1035,7 +1079,7 @@ static PyObject *WraptObjectProxy_get_module(
WraptObjectProxyObject *self)
{
if (!self->wrapped) {
PyErr_SetString(PyExc_ValueError, "wrapper has not been initialised");
PyErr_SetString(PyExc_ValueError, "wrapper has not been initialized");
return NULL;
}
@@ -1048,11 +1092,14 @@ static int WraptObjectProxy_set_module(WraptObjectProxyObject *self,
PyObject *value)
{
if (!self->wrapped) {
PyErr_SetString(PyExc_ValueError, "wrapper has not been initialised");
PyErr_SetString(PyExc_ValueError, "wrapper has not been initialized");
return -1;
}
return PyObject_SetAttrString(self->wrapped, "__module__", value);
if (PyObject_SetAttrString(self->wrapped, "__module__", value) == -1)
return -1;
return PyDict_SetItemString(self->dict, "__module__", value);
}
/* ------------------------------------------------------------------------- */
@@ -1061,7 +1108,7 @@ static PyObject *WraptObjectProxy_get_doc(
WraptObjectProxyObject *self)
{
if (!self->wrapped) {
PyErr_SetString(PyExc_ValueError, "wrapper has not been initialised");
PyErr_SetString(PyExc_ValueError, "wrapper has not been initialized");
return NULL;
}
@@ -1074,11 +1121,14 @@ static int WraptObjectProxy_set_doc(WraptObjectProxyObject *self,
PyObject *value)
{
if (!self->wrapped) {
PyErr_SetString(PyExc_ValueError, "wrapper has not been initialised");
PyErr_SetString(PyExc_ValueError, "wrapper has not been initialized");
return -1;
}
return PyObject_SetAttrString(self->wrapped, "__doc__", value);
if (PyObject_SetAttrString(self->wrapped, "__doc__", value) == -1)
return -1;
return PyDict_SetItemString(self->dict, "__doc__", value);
}
/* ------------------------------------------------------------------------- */
@@ -1087,7 +1137,7 @@ static PyObject *WraptObjectProxy_get_class(
WraptObjectProxyObject *self)
{
if (!self->wrapped) {
PyErr_SetString(PyExc_ValueError, "wrapper has not been initialised");
PyErr_SetString(PyExc_ValueError, "wrapper has not been initialized");
return NULL;
}
@@ -1100,7 +1150,7 @@ static PyObject *WraptObjectProxy_get_wrapped(
WraptObjectProxyObject *self)
{
if (!self->wrapped) {
PyErr_SetString(PyExc_ValueError, "wrapper has not been initialised");
PyErr_SetString(PyExc_ValueError, "wrapper has not been initialized");
return NULL;
}
@@ -1114,7 +1164,7 @@ static int WraptObjectProxy_set_wrapped(WraptObjectProxyObject *self,
PyObject *value)
{
if (!self->wrapped) {
PyErr_SetString(PyExc_ValueError, "wrapper has not been initialised");
PyErr_SetString(PyExc_ValueError, "wrapper has not been initialized");
return -1;
}
@@ -1137,7 +1187,7 @@ static PyObject *WraptObjectProxy_get_annotations(
WraptObjectProxyObject *self)
{
if (!self->wrapped) {
PyErr_SetString(PyExc_ValueError, "wrapper has not been initialised");
PyErr_SetString(PyExc_ValueError, "wrapper has not been initialized");
return NULL;
}
@@ -1150,7 +1200,7 @@ static int WraptObjectProxy_set_annotations(WraptObjectProxyObject *self,
PyObject *value)
{
if (!self->wrapped) {
PyErr_SetString(PyExc_ValueError, "wrapper has not been initialised");
PyErr_SetString(PyExc_ValueError, "wrapper has not been initialized");
return -1;
}
@@ -1210,7 +1260,7 @@ static PyObject *WraptObjectProxy_getattr(
#endif
if (!self->wrapped) {
PyErr_SetString(PyExc_ValueError, "wrapper has not been initialised");
PyErr_SetString(PyExc_ValueError, "wrapper has not been initialized");
return NULL;
}
@@ -1273,7 +1323,7 @@ static int WraptObjectProxy_setattro(
}
if (!self->wrapped) {
PyErr_SetString(PyExc_ValueError, "wrapper has not been initialised");
PyErr_SetString(PyExc_ValueError, "wrapper has not been initialized");
return -1;
}
@@ -1286,7 +1336,7 @@ static PyObject *WraptObjectProxy_richcompare(WraptObjectProxyObject *self,
PyObject *other, int opcode)
{
if (!self->wrapped) {
PyErr_SetString(PyExc_ValueError, "wrapper has not been initialised");
PyErr_SetString(PyExc_ValueError, "wrapper has not been initialized");
return NULL;
}
@@ -1298,7 +1348,7 @@ static PyObject *WraptObjectProxy_richcompare(WraptObjectProxyObject *self,
static PyObject *WraptObjectProxy_iter(WraptObjectProxyObject *self)
{
if (!self->wrapped) {
PyErr_SetString(PyExc_ValueError, "wrapper has not been initialised");
PyErr_SetString(PyExc_ValueError, "wrapper has not been initialized");
return NULL;
}
@@ -1473,7 +1523,6 @@ static PyObject *WraptFunctionWrapperBase_new(PyTypeObject *type,
self->instance = NULL;
self->wrapper = NULL;
self->adapter = NULL;
self->enabled = NULL;
self->binding = NULL;
self->parent = NULL;
@@ -1485,8 +1534,7 @@ static PyObject *WraptFunctionWrapperBase_new(PyTypeObject *type,
static int WraptFunctionWrapperBase_raw_init(WraptFunctionWrapperObject *self,
PyObject *wrapped, PyObject *instance, PyObject *wrapper,
PyObject *adapter, PyObject *enabled, PyObject *binding,
PyObject *parent)
PyObject *enabled, PyObject *binding, PyObject *parent)
{
int result = 0;
@@ -1502,10 +1550,6 @@ static int WraptFunctionWrapperBase_raw_init(WraptFunctionWrapperObject *self,
Py_XDECREF(self->wrapper);
self->wrapper = wrapper;
Py_INCREF(adapter);
Py_XDECREF(self->adapter);
self->adapter = adapter;
Py_INCREF(enabled);
Py_XDECREF(self->enabled);
self->enabled = enabled;
@@ -1530,22 +1574,21 @@ static int WraptFunctionWrapperBase_init(WraptFunctionWrapperObject *self,
PyObject *wrapped = NULL;
PyObject *instance = NULL;
PyObject *wrapper = NULL;
PyObject *adapter = Py_None;
PyObject *enabled = Py_None;
PyObject *binding = Py_None;
PyObject *parent = Py_None;
static char *kwlist[] = { "wrapped", "instance", "wrapper",
"adapter", "enabled", "binding", "parent", NULL };
"enabled", "binding", "parent", NULL };
if (!PyArg_ParseTupleAndKeywords(args, kwds,
"OOO|OOOO:FunctionWrapperBase", kwlist, &wrapped, &instance,
&wrapper, &adapter, &enabled, &binding, &parent)) {
"OOO|OOO:FunctionWrapperBase", kwlist, &wrapped, &instance,
&wrapper, &enabled, &binding, &parent)) {
return -1;
}
return WraptFunctionWrapperBase_raw_init(self, wrapped, instance, wrapper,
adapter, enabled, binding, parent);
enabled, binding, parent);
}
/* ------------------------------------------------------------------------- */
@@ -1557,7 +1600,6 @@ static int WraptFunctionWrapperBase_traverse(WraptFunctionWrapperObject *self,
Py_VISIT(self->instance);
Py_VISIT(self->wrapper);
Py_VISIT(self->adapter);
Py_VISIT(self->enabled);
Py_VISIT(self->binding);
Py_VISIT(self->parent);
@@ -1573,7 +1615,6 @@ static int WraptFunctionWrapperBase_clear(WraptFunctionWrapperObject *self)
Py_CLEAR(self->instance);
Py_CLEAR(self->wrapper);
Py_CLEAR(self->adapter);
Py_CLEAR(self->enabled);
Py_CLEAR(self->binding);
Py_CLEAR(self->parent);
@@ -1708,7 +1749,7 @@ static PyObject *WraptFunctionWrapperBase_descr_get(
if (descriptor) {
result = PyObject_CallFunctionObjArgs(bound_type ? bound_type :
(PyObject *)&WraptBoundFunctionWrapper_Type, descriptor,
obj, self->wrapper, self->adapter, Py_None, self->binding,
obj, self->wrapper, Py_None, self->binding,
self, NULL);
}
@@ -1720,70 +1761,6 @@ static PyObject *WraptFunctionWrapperBase_descr_get(
/* ------------------------------------------------------------------------- */
static PyObject *WraptFunctionWrapperBase_get_code(
WraptFunctionWrapperObject *self)
{
if (!self->object_proxy.wrapped) {
PyErr_SetString(PyExc_ValueError, "wrapper has not been initialised");
return NULL;
}
if (self->adapter != Py_None)
return PyObject_GetAttrString(self->adapter, "__code__");
return PyObject_GetAttrString(self->object_proxy.wrapped, "__code__");
}
/* ------------------------------------------------------------------------- */
static PyObject *WraptFunctionWrapperBase_get_defaults(
WraptFunctionWrapperObject *self)
{
if (!self->object_proxy.wrapped) {
PyErr_SetString(PyExc_ValueError, "wrapper has not been initialised");
return NULL;
}
if (self->adapter != Py_None)
return PyObject_GetAttrString(self->adapter, "__defaults__");
return PyObject_GetAttrString(self->object_proxy.wrapped, "__defaults__");
}
/* ------------------------------------------------------------------------- */
static PyObject *WraptFunctionWrapperBase_get_kwdefaults(
WraptFunctionWrapperObject *self)
{
if (!self->object_proxy.wrapped) {
PyErr_SetString(PyExc_ValueError, "wrapper has not been initialised");
return NULL;
}
if (self->adapter != Py_None)
return PyObject_GetAttrString(self->adapter, "__kwdefaults__");
return PyObject_GetAttrString(self->object_proxy.wrapped, "__kwdefaults__");
}
/* ------------------------------------------------------------------------- */
static PyObject *WraptFunctionWrapperBase_get_signature(
WraptFunctionWrapperObject *self)
{
if (!self->object_proxy.wrapped) {
PyErr_SetString(PyExc_ValueError, "wrapper has not been initialised");
return NULL;
}
if (self->adapter != Py_None)
return PyObject_GetAttrString(self->adapter, "__signature__");
return PyObject_GetAttrString(self->object_proxy.wrapped, "__signature__");
}
/* ------------------------------------------------------------------------- */
static PyObject *WraptFunctionWrapperBase_get_self_instance(
WraptFunctionWrapperObject *self, void *closure)
{
@@ -1812,20 +1789,6 @@ static PyObject *WraptFunctionWrapperBase_get_self_wrapper(
/* ------------------------------------------------------------------------- */
static PyObject *WraptFunctionWrapperBase_get_self_adapter(
WraptFunctionWrapperObject *self, void *closure)
{
if (!self->adapter) {
Py_INCREF(Py_None);
return Py_None;
}
Py_INCREF(self->adapter);
return self->adapter;
}
/* ------------------------------------------------------------------------- */
static PyObject *WraptFunctionWrapperBase_get_self_enabled(
WraptFunctionWrapperObject *self, void *closure)
{
@@ -1873,26 +1836,10 @@ static PyGetSetDef WraptFunctionWrapperBase_getset[] = {
(setter)WraptObjectProxy_set_module, 0 },
{ "__doc__", (getter)WraptObjectProxy_get_doc,
(setter)WraptObjectProxy_set_doc, 0 },
{ "__code__", (getter)WraptFunctionWrapperBase_get_code,
NULL, 0 },
{ "__defaults__", (getter)WraptFunctionWrapperBase_get_defaults,
NULL, 0 },
{ "__kwdefaults__", (getter)WraptFunctionWrapperBase_get_kwdefaults,
NULL, 0 },
{ "__signature__", (getter)WraptFunctionWrapperBase_get_signature,
NULL, 0 },
#if PY_MAJOR_VERSION < 3
{ "func_code", (getter)WraptFunctionWrapperBase_get_code,
NULL, 0 },
{ "func_defaults", (getter)WraptFunctionWrapperBase_get_defaults,
NULL, 0 },
#endif
{ "_self_instance", (getter)WraptFunctionWrapperBase_get_self_instance,
NULL, 0 },
{ "_self_wrapper", (getter)WraptFunctionWrapperBase_get_self_wrapper,
NULL, 0 },
{ "_self_adapter", (getter)WraptFunctionWrapperBase_get_self_adapter,
NULL, 0 },
{ "_self_enabled", (getter)WraptFunctionWrapperBase_get_self_enabled,
NULL, 0 },
{ "_self_binding", (getter)WraptFunctionWrapperBase_get_self_binding,
@@ -2157,7 +2104,6 @@ static int WraptFunctionWrapper_init(WraptFunctionWrapperObject *self,
{
PyObject *wrapped = NULL;
PyObject *wrapper = NULL;
PyObject *adapter = Py_None;
PyObject *enabled = Py_None;
PyObject *binding = NULL;
@@ -2167,10 +2113,10 @@ static int WraptFunctionWrapper_init(WraptFunctionWrapperObject *self,
int result = 0;
static char *kwlist[] = { "wrapped", "wrapper", "adapter", "enabled", NULL };
static char *kwlist[] = { "wrapped", "wrapper", "enabled", NULL };
if (!PyArg_ParseTupleAndKeywords(args, kwds, "OO|OO:FunctionWrapper",
kwlist, &wrapped, &wrapper, &adapter, &enabled)) {
if (!PyArg_ParseTupleAndKeywords(args, kwds, "OO|O:FunctionWrapper",
kwlist, &wrapped, &wrapper, &enabled)) {
return -1;
}
@@ -2206,7 +2152,7 @@ static int WraptFunctionWrapper_init(WraptFunctionWrapperObject *self,
binding = instancemethod_str;
result = WraptFunctionWrapperBase_raw_init(self, wrapped, Py_None,
wrapper, adapter, enabled, binding, Py_None);
wrapper, enabled, binding, Py_None);
return result;
}

View File

@@ -13,9 +13,9 @@ from threading import Lock, RLock
if not six.PY2:
from inspect import signature
from .wrappers import FunctionWrapper, ObjectProxy
from .wrappers import FunctionWrapper, BoundFunctionWrapper, ObjectProxy
# Object proxy for the wrapped function which will overlay certain
# Adapter wrapper for the wrapped function which will overlay certain
# properties from the adapter function onto the wrapped function so that
# functions such as inspect.getargspec(), inspect.getfullargspec(),
# inspect.signature() and inspect.getsource() return the correct results
@@ -47,10 +47,10 @@ class _AdapterFunctionCode(ObjectProxy):
def co_varnames(self):
return self._self_adapter_code.co_varnames
class _AdapterFunction(ObjectProxy):
class _AdapterFunctionSurrogate(ObjectProxy):
def __init__(self, wrapped, adapter):
super(_AdapterFunction, self).__init__(wrapped)
super(_AdapterFunctionSurrogate, self).__init__(wrapped)
self._self_adapter = adapter
@property
@@ -82,6 +82,47 @@ class _AdapterFunction(ObjectProxy):
func_code = __code__
func_defaults = __defaults__
class _BoundAdapterWrapper(BoundFunctionWrapper):
@property
def __func__(self):
return _AdapterFunctionSurrogate(self.__wrapped__.__func__,
self._self_parent._self_adapter)
if six.PY2:
im_func = __func__
class AdapterWrapper(FunctionWrapper):
__bound_function_wrapper__ = _BoundAdapterWrapper
def __init__(self, *args, **kwargs):
adapter = kwargs.pop('adapter')
super(AdapterWrapper, self).__init__(*args, **kwargs)
self._self_surrogate = _AdapterFunctionSurrogate(
self.__wrapped__, adapter)
self._self_adapter = adapter
@property
def __code__(self):
return self._self_surrogate.__code__
@property
def __defaults__(self):
return self._self_surrogate.__defaults__
@property
def __kwdefaults__(self):
return self._self_surrogate.__kwdefaults__
if six.PY2:
func_code = __code__
func_defaults = __defaults__
@property
def __signature__(self):
return self._self_surrogate.__signature__
# Decorator for creating other decorators. This decorator and the
# wrappers which they use are designed to properly preserve any name
# attributes, function signatures etc, in addition to the wrappers
@@ -122,9 +163,12 @@ def decorator(wrapper=None, adapter=None, enabled=None):
return func
_enabled = None
_adapter = adapter and _AdapterFunction(func, adapter)
result = FunctionWrapper(wrapped=func, wrapper=wrapper,
adapter=_adapter, enabled=_enabled)
if adapter:
result = AdapterWrapper(wrapped=func, wrapper=wrapper,
enabled=_enabled, adapter=adapter)
else:
result = FunctionWrapper(wrapped=func, wrapper=wrapper,
enabled=_enabled)
return result

View File

@@ -380,17 +380,16 @@ class ObjectProxy(six.with_metaclass(_ObjectProxyMetaType)):
class _FunctionWrapperBase(ObjectProxy):
__slots__ = ('_self_instance', '_self_wrapper', '_self_adapter',
'_self_enabled', '_self_binding', '_self_parent')
__slots__ = ('_self_instance', '_self_wrapper', '_self_enabled',
'_self_binding', '_self_parent')
def __init__(self, wrapped, instance, wrapper, adapter=None,
enabled=None, binding=None, parent=None):
def __init__(self, wrapped, instance, wrapper, enabled=None,
binding=None, parent=None):
super(_FunctionWrapperBase, self).__init__(wrapped)
object.__setattr__(self, '_self_instance', instance)
object.__setattr__(self, '_self_wrapper', wrapper)
object.__setattr__(self, '_self_adapter', adapter)
object.__setattr__(self, '_self_enabled', enabled)
object.__setattr__(self, '_self_binding', binding)
object.__setattr__(self, '_self_parent', parent)
@@ -420,8 +419,7 @@ class _FunctionWrapperBase(ObjectProxy):
return descriptor
return self.__bound_function_wrapper__(descriptor, instance,
self._self_wrapper, self._self_adapter, None,
self._self_binding, self)
self._self_wrapper, None, self._self_binding, self)
def __call__(self, *args, **kwargs):
# If enabled has been specified, then evaluate it at this point
@@ -446,43 +444,6 @@ class _FunctionWrapperBase(ObjectProxy):
return self._self_wrapper(self.__wrapped__, self._self_instance,
args, kwargs)
# If an adapter function was provided we want to return certain
# attributes of the function from the adapter rather than the
# wrapped function so things like inspect.getargspec() will reflect
# the prototype of the adapter and not the wrapped function.
@property
def __code__(self):
if self._self_adapter:
return self._self_adapter.__code__
return self.__wrapped__.__code__
@property
def __defaults__(self):
if self._self_adapter:
return self._self_adapter.__defaults__
return self.__wrapped__.__defaults__
@property
def __kwdefaults__(self):
if self._self_adapter:
return self._self_adapter.__kwdefaults__
return self.__wrapped__.__kwdefaults__
if six.PY2:
func_code = __code__
func_defaults = __defaults__
# If an adapter function was provided, we also want to override the
# __signature__ attribute introduced in Python 3 so that we get the
# correct result when using inspect.signature().
@property
def __signature__(self):
if self._self_adapter:
return self._self_adapter.__signature__
return self.__wrapped__.__signature__
class BoundFunctionWrapper(_FunctionWrapperBase):
def __call__(self, *args, **kwargs):
@@ -529,7 +490,7 @@ class FunctionWrapper(_FunctionWrapperBase):
__bound_function_wrapper__ = BoundFunctionWrapper
def __init__(self, wrapped, wrapper, adapter=None, enabled=None):
def __init__(self, wrapped, wrapper, enabled=None):
# We need to do special fixups on the args in the case of an
# instancemethod where called via the class and the instance is
# passed explicitly as the first argument. So work out when we
@@ -563,7 +524,7 @@ class FunctionWrapper(_FunctionWrapperBase):
binding = 'instancemethod'
super(FunctionWrapper, self).__init__(wrapped, None, wrapper,
adapter, enabled, binding)
enabled, binding)
try:
from ._wrappers import (ObjectProxy, FunctionWrapper,

View File

@@ -76,6 +76,13 @@ class TestArgumentSpecification(unittest.TestCase):
function1d_argspec = inspect.getargspec(function1d)
self.assertEqual(function1a_argspec, function1d_argspec)
# Now bind the function to an instance. The argspec should
# still match.
bound_function1d = function1d.__get__(object(), object)
bound_function1d_argspec = inspect.getargspec(bound_function1d)
self.assertEqual(function1a_argspec, bound_function1d_argspec)
def test_signature(self):
# Test preservation of function argument specification. It
# actually needs to match that of the adapter function the