Add back underlying support in wrappers for both args and kwargs for wrapper function.
This commit is contained in:
294
src/_wrappers.c
294
src/_wrappers.c
@@ -21,7 +21,8 @@ PyTypeObject WraptObjectProxy_Type;
|
||||
typedef struct {
|
||||
WraptObjectProxyObject object_proxy;
|
||||
PyObject *wrapper;
|
||||
PyObject *params;
|
||||
PyObject *wrapper_args;
|
||||
PyObject *wrapper_kwargs;
|
||||
PyObject *bound_type;
|
||||
} WraptFunctionWrapperObject;
|
||||
|
||||
@@ -31,7 +32,8 @@ typedef struct {
|
||||
WraptObjectProxyObject object_proxy;
|
||||
PyObject *instance;
|
||||
PyObject *wrapper;
|
||||
PyObject *params;
|
||||
PyObject *wrapper_args;
|
||||
PyObject *wrapper_kwargs;
|
||||
} WraptBoundFunctionWrapperObject;
|
||||
|
||||
PyTypeObject WraptBoundFunctionWrapper_Type;
|
||||
@@ -40,7 +42,8 @@ typedef struct {
|
||||
WraptObjectProxyObject object_proxy;
|
||||
PyObject *instance;
|
||||
PyObject *wrapper;
|
||||
PyObject *params;
|
||||
PyObject *wrapper_args;
|
||||
PyObject *wrapper_kwargs;
|
||||
} WraptBoundMethodWrapperObject;
|
||||
|
||||
PyTypeObject WraptBoundMethodWrapper_Type;
|
||||
@@ -1160,8 +1163,7 @@ PyTypeObject WraptObjectProxy_Type = {
|
||||
(setattrofunc)WraptObjectProxy_setattro, /*tp_setattro*/
|
||||
0, /*tp_as_buffer*/
|
||||
#if PY_MAJOR_VERSION < 3
|
||||
Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE |
|
||||
Py_TPFLAGS_CHECKTYPES, /*tp_flags*/
|
||||
Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_CHECKTYPES, /*tp_flags*/
|
||||
#else
|
||||
Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /*tp_flags*/
|
||||
#endif
|
||||
@@ -1201,7 +1203,8 @@ static PyObject *WraptFunctionWrapper_new(PyTypeObject *type,
|
||||
return NULL;
|
||||
|
||||
self->wrapper = NULL;
|
||||
self->params = NULL;
|
||||
self->wrapper_args = NULL;
|
||||
self->wrapper_kwargs = NULL;
|
||||
self->bound_type = NULL;
|
||||
|
||||
return (PyObject *)self;
|
||||
@@ -1214,26 +1217,29 @@ static int WraptFunctionWrapper_init(WraptFunctionWrapperObject *self,
|
||||
{
|
||||
PyObject *wrapped = NULL;
|
||||
PyObject *wrapper = NULL;
|
||||
PyObject *params = NULL;
|
||||
PyObject *wrapper_args = NULL;
|
||||
PyObject *wrapper_kwargs = NULL;
|
||||
|
||||
PyObject *base_args = NULL;
|
||||
PyObject *base_kwds = NULL;
|
||||
|
||||
int result = 0;
|
||||
|
||||
static char *kwlist[] = { "wrapped", "wrapper", "params", NULL };
|
||||
static char *kwlist[] = { "wrapped", "wrapper", "args", "kwargs", NULL };
|
||||
|
||||
if (!PyArg_ParseTupleAndKeywords(args, kwds, "OO|O:FunctionWrapper",
|
||||
kwlist, &wrapped, &wrapper, ¶ms)) {
|
||||
if (!PyArg_ParseTupleAndKeywords(args, kwds, "OO|OO:FunctionWrapper",
|
||||
kwlist, &wrapped, &wrapper, &wrapper_args, &wrapper_kwargs)) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
Py_XDECREF(self->wrapper);
|
||||
Py_XDECREF(self->params);
|
||||
Py_XDECREF(self->wrapper_args);
|
||||
Py_XDECREF(self->wrapper_kwargs);
|
||||
Py_XDECREF(self->bound_type);
|
||||
|
||||
self->wrapper = NULL;
|
||||
self->params = NULL;
|
||||
self->wrapper_args = NULL;
|
||||
self->wrapper_kwargs = NULL;
|
||||
self->bound_type = NULL;
|
||||
|
||||
base_args = PyTuple_Pack(1, wrapped);
|
||||
@@ -1246,12 +1252,19 @@ static int WraptFunctionWrapper_init(WraptFunctionWrapperObject *self,
|
||||
Py_INCREF(wrapper);
|
||||
self->wrapper = wrapper;
|
||||
|
||||
if (params) {
|
||||
Py_INCREF(params);
|
||||
self->params = params;
|
||||
if (wrapper_args) {
|
||||
Py_INCREF(wrapper_args);
|
||||
self->wrapper_args = wrapper_args;
|
||||
}
|
||||
else
|
||||
self->params = PyDict_New();
|
||||
self->wrapper_args = PyTuple_New(0);
|
||||
|
||||
if (wrapper_kwargs) {
|
||||
Py_INCREF(wrapper_kwargs);
|
||||
self->wrapper_kwargs = wrapper_kwargs;
|
||||
}
|
||||
else
|
||||
self->wrapper_kwargs = PyDict_New();
|
||||
|
||||
if (PyObject_IsInstance(wrapped,
|
||||
(PyObject *)&PyClassMethod_Type) || PyObject_IsInstance(
|
||||
@@ -1276,7 +1289,8 @@ static int WraptFunctionWrapper_init(WraptFunctionWrapperObject *self,
|
||||
static void WraptFunctionWrapper_dealloc(WraptFunctionWrapperObject *self)
|
||||
{
|
||||
Py_XDECREF(self->wrapper);
|
||||
Py_XDECREF(self->params);
|
||||
Py_XDECREF(self->wrapper_args);
|
||||
Py_XDECREF(self->wrapper_kwargs);
|
||||
Py_XDECREF(self->bound_type);
|
||||
|
||||
WraptObjectProxy_dealloc((WraptObjectProxyObject *)self);
|
||||
@@ -1292,16 +1306,35 @@ static PyObject *WraptFunctionWrapper_call(
|
||||
|
||||
PyObject *result = NULL;
|
||||
|
||||
int len = 0;
|
||||
int i = 0;
|
||||
|
||||
if (!kwds) {
|
||||
param_kwds = PyDict_New();
|
||||
kwds = param_kwds;
|
||||
}
|
||||
|
||||
call_args = PyTuple_Pack(4, self->object_proxy.wrapped, Py_None,
|
||||
args, kwds);
|
||||
len = PySequence_Size(self->wrapper_args);
|
||||
call_args = PyTuple_New(len+4);
|
||||
|
||||
Py_INCREF(self->object_proxy.wrapped);
|
||||
Py_INCREF(Py_None);
|
||||
Py_INCREF(args);
|
||||
Py_INCREF(kwds);
|
||||
|
||||
PyTuple_SET_ITEM(call_args, 0, self->object_proxy.wrapped);
|
||||
PyTuple_SET_ITEM(call_args, 1, Py_None);
|
||||
PyTuple_SET_ITEM(call_args, 2, args);
|
||||
PyTuple_SET_ITEM(call_args, 3, kwds);
|
||||
|
||||
for (i=0; i<len; i++) {
|
||||
PyObject *item = PyTuple_GetItem(self->wrapper_args, i);
|
||||
Py_INCREF(item);
|
||||
PyTuple_SET_ITEM(call_args, i+4, item);
|
||||
}
|
||||
|
||||
result = PyEval_CallObjectWithKeywords(self->wrapper, call_args,
|
||||
self->params);
|
||||
self->wrapper_kwargs);
|
||||
|
||||
Py_DECREF(call_args);
|
||||
Py_XDECREF(param_kwds);
|
||||
@@ -1326,8 +1359,9 @@ static PyObject *WraptFunctionWrapper_descr_get(
|
||||
type = Py_None;
|
||||
|
||||
if (descriptor) {
|
||||
result = PyObject_CallFunction(self->bound_type, "(OOOO)",
|
||||
descriptor, obj, self->wrapper, self->params);
|
||||
result = PyObject_CallFunction(self->bound_type, "(OOOOO)",
|
||||
descriptor, obj, self->wrapper, self->wrapper_args,
|
||||
self->wrapper_kwargs);
|
||||
}
|
||||
|
||||
Py_XDECREF(descriptor);
|
||||
@@ -1351,16 +1385,30 @@ static PyObject *WraptFunctionWrapper_get_self_wrapper(
|
||||
|
||||
/* ------------------------------------------------------------------------- */
|
||||
|
||||
static PyObject *WraptFunctionWrapper_get_self_params(
|
||||
static PyObject *WraptFunctionWrapper_get_self_wrapper_args(
|
||||
WraptFunctionWrapperObject *self, void *closure)
|
||||
{
|
||||
if (!self->params) {
|
||||
if (!self->wrapper_args) {
|
||||
Py_INCREF(Py_None);
|
||||
return Py_None;
|
||||
}
|
||||
|
||||
Py_INCREF(self->params);
|
||||
return self->params;
|
||||
Py_INCREF(self->wrapper_args);
|
||||
return self->wrapper_args;
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------------------- */
|
||||
|
||||
static PyObject *WraptFunctionWrapper_get_self_wrapper_kwargs(
|
||||
WraptFunctionWrapperObject *self, void *closure)
|
||||
{
|
||||
if (!self->wrapper_kwargs) {
|
||||
Py_INCREF(Py_None);
|
||||
return Py_None;
|
||||
}
|
||||
|
||||
Py_INCREF(self->wrapper_kwargs);
|
||||
return self->wrapper_kwargs;
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------------------- */
|
||||
@@ -1386,7 +1434,9 @@ static PyGetSetDef WraptFunctionWrapper_getset[] = {
|
||||
(setter)WraptObjectProxy_set_doc, 0 },
|
||||
{ "_self_wrapper", (getter)WraptFunctionWrapper_get_self_wrapper,
|
||||
NULL, 0 },
|
||||
{ "_self_params", (getter)WraptFunctionWrapper_get_self_params,
|
||||
{ "_self_wrapper_args", (getter)WraptFunctionWrapper_get_self_wrapper_args,
|
||||
NULL, 0 },
|
||||
{ "_self_wrapper_kwargs", (getter)WraptFunctionWrapper_get_self_wrapper_kwargs,
|
||||
NULL, 0 },
|
||||
{ "_self_bound_type", (getter)WraptFunctionWrapper_get_self_bound_type,
|
||||
NULL, 0 },
|
||||
@@ -1415,8 +1465,7 @@ PyTypeObject WraptFunctionWrapper_Type = {
|
||||
0, /*tp_setattro*/
|
||||
0, /*tp_as_buffer*/
|
||||
#if PY_MAJOR_VERSION < 3
|
||||
Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE |
|
||||
Py_TPFLAGS_CHECKTYPES, /*tp_flags*/
|
||||
Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_CHECKTYPES, /*tp_flags*/
|
||||
#else
|
||||
Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /*tp_flags*/
|
||||
#endif
|
||||
@@ -1457,7 +1506,8 @@ static PyObject *WraptBoundFunctionWrapper_new(PyTypeObject *type,
|
||||
|
||||
self->instance = NULL;
|
||||
self->wrapper = NULL;
|
||||
self->params = NULL;
|
||||
self->wrapper_args = NULL;
|
||||
self->wrapper_kwargs = NULL;
|
||||
|
||||
return (PyObject *)self;
|
||||
}
|
||||
@@ -1470,7 +1520,8 @@ static int WraptBoundFunctionWrapper_init(
|
||||
PyObject *wrapped = NULL;
|
||||
PyObject *instance = NULL;
|
||||
PyObject *wrapper = NULL;
|
||||
PyObject *params = NULL;
|
||||
PyObject *wrapper_args = NULL;
|
||||
PyObject *wrapper_kwargs = NULL;
|
||||
|
||||
PyObject *base_args = NULL;
|
||||
PyObject *base_kwds = NULL;
|
||||
@@ -1478,21 +1529,23 @@ static int WraptBoundFunctionWrapper_init(
|
||||
int result = 0;
|
||||
|
||||
static char *kwlist[] = { "wrapped", "instance", "wrapper",
|
||||
"params", NULL };
|
||||
"args", "kwargs", NULL };
|
||||
|
||||
if (!PyArg_ParseTupleAndKeywords(args, kwds,
|
||||
"OOO|O:BoundFunctionWrapper", kwlist, &wrapped, &instance,
|
||||
&wrapper, ¶ms)) {
|
||||
"OOO|OO:BoundFunctionWrapper", kwlist, &wrapped, &instance,
|
||||
&wrapper, &wrapper_args, &wrapper_kwargs)) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
Py_XDECREF(self->instance);
|
||||
Py_XDECREF(self->wrapper);
|
||||
Py_XDECREF(self->params);
|
||||
Py_XDECREF(self->wrapper_args);
|
||||
Py_XDECREF(self->wrapper_kwargs);
|
||||
|
||||
self->instance = NULL;
|
||||
self->wrapper = NULL;
|
||||
self->params = NULL;
|
||||
self->wrapper_args = NULL;
|
||||
self->wrapper_kwargs = NULL;
|
||||
|
||||
base_args = PyTuple_Pack(1, wrapped);
|
||||
base_kwds = PyDict_New();
|
||||
@@ -1507,12 +1560,19 @@ static int WraptBoundFunctionWrapper_init(
|
||||
Py_INCREF(wrapper);
|
||||
self->wrapper = wrapper;
|
||||
|
||||
if (params) {
|
||||
Py_INCREF(params);
|
||||
self->params = params;
|
||||
if (wrapper_args) {
|
||||
Py_INCREF(wrapper_args);
|
||||
self->wrapper_args = wrapper_args;
|
||||
}
|
||||
else
|
||||
self->params = PyDict_New();
|
||||
self->wrapper_args = PyTuple_New(0);
|
||||
|
||||
if (wrapper_kwargs) {
|
||||
Py_INCREF(wrapper_kwargs);
|
||||
self->wrapper_kwargs = wrapper_kwargs;
|
||||
}
|
||||
else
|
||||
self->wrapper_kwargs = PyDict_New();
|
||||
}
|
||||
|
||||
Py_DECREF(base_args);
|
||||
@@ -1528,7 +1588,8 @@ static void WraptBoundFunctionWrapper_dealloc(
|
||||
{
|
||||
Py_XDECREF(self->instance);
|
||||
Py_XDECREF(self->wrapper);
|
||||
Py_XDECREF(self->params);
|
||||
Py_XDECREF(self->wrapper_args);
|
||||
Py_XDECREF(self->wrapper_kwargs);
|
||||
|
||||
WraptObjectProxy_dealloc((WraptObjectProxyObject *)self);
|
||||
}
|
||||
@@ -1543,16 +1604,35 @@ static PyObject *WraptBoundFunctionWrapper_call(
|
||||
|
||||
PyObject *result = NULL;
|
||||
|
||||
int len = 0;
|
||||
int i = 0;
|
||||
|
||||
if (!kwds) {
|
||||
param_kwds = PyDict_New();
|
||||
kwds = param_kwds;
|
||||
}
|
||||
|
||||
call_args = PyTuple_Pack(4, self->object_proxy.wrapped, self->instance,
|
||||
args, kwds);
|
||||
len = PySequence_Size(self->wrapper_args);
|
||||
call_args = PyTuple_New(len+4);
|
||||
|
||||
Py_INCREF(self->object_proxy.wrapped);
|
||||
Py_INCREF(self->instance);
|
||||
Py_INCREF(args);
|
||||
Py_INCREF(kwds);
|
||||
|
||||
PyTuple_SET_ITEM(call_args, 0, self->object_proxy.wrapped);
|
||||
PyTuple_SET_ITEM(call_args, 1, self->instance);
|
||||
PyTuple_SET_ITEM(call_args, 2, args);
|
||||
PyTuple_SET_ITEM(call_args, 3, kwds);
|
||||
|
||||
for (i=0; i<len; i++) {
|
||||
PyObject *item = PyTuple_GetItem(self->wrapper_args, i);
|
||||
Py_INCREF(item);
|
||||
PyTuple_SET_ITEM(call_args, i+4, item);
|
||||
}
|
||||
|
||||
result = PyEval_CallObjectWithKeywords(self->wrapper, call_args,
|
||||
self->params);
|
||||
self->wrapper_kwargs);
|
||||
|
||||
Py_DECREF(call_args);
|
||||
Py_XDECREF(param_kwds);
|
||||
@@ -1590,16 +1670,30 @@ static PyObject *WraptBoundFunctionWrapper_get_self_wrapper(
|
||||
|
||||
/* ------------------------------------------------------------------------- */
|
||||
|
||||
static PyObject *WraptBoundFunctionWrapper_get_self_params(
|
||||
static PyObject *WraptBoundFunctionWrapper_get_self_wrapper_args(
|
||||
WraptBoundFunctionWrapperObject *self, void *closure)
|
||||
{
|
||||
if (!self->params) {
|
||||
if (!self->wrapper_args) {
|
||||
Py_INCREF(Py_None);
|
||||
return Py_None;
|
||||
}
|
||||
|
||||
Py_INCREF(self->params);
|
||||
return self->params;
|
||||
Py_INCREF(self->wrapper_args);
|
||||
return self->wrapper_args;
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------------------- */
|
||||
|
||||
static PyObject *WraptBoundFunctionWrapper_get_self_wrapper_kwargs(
|
||||
WraptBoundFunctionWrapperObject *self, void *closure)
|
||||
{
|
||||
if (!self->wrapper_kwargs) {
|
||||
Py_INCREF(Py_None);
|
||||
return Py_None;
|
||||
}
|
||||
|
||||
Py_INCREF(self->wrapper_kwargs);
|
||||
return self->wrapper_kwargs;
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------------------- */;
|
||||
@@ -1613,7 +1707,9 @@ static PyGetSetDef WraptBoundFunctionWrapper_getset[] = {
|
||||
NULL, 0 },
|
||||
{ "_self_wrapper", (getter)WraptBoundFunctionWrapper_get_self_wrapper,
|
||||
NULL, 0 },
|
||||
{ "_self_params", (getter)WraptBoundFunctionWrapper_get_self_params,
|
||||
{ "_self_wrapper_args", (getter)WraptBoundFunctionWrapper_get_self_wrapper_args,
|
||||
NULL, 0 },
|
||||
{ "_self_wrapper_kwargs", (getter)WraptBoundFunctionWrapper_get_self_wrapper_kwargs,
|
||||
NULL, 0 },
|
||||
{ NULL },
|
||||
};
|
||||
@@ -1640,8 +1736,7 @@ PyTypeObject WraptBoundFunctionWrapper_Type = {
|
||||
0, /*tp_setattro*/
|
||||
0, /*tp_as_buffer*/
|
||||
#if PY_MAJOR_VERSION < 3
|
||||
Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE |
|
||||
Py_TPFLAGS_CHECKTYPES, /*tp_flags*/
|
||||
Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_CHECKTYPES, /*tp_flags*/
|
||||
#else
|
||||
Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /*tp_flags*/
|
||||
#endif
|
||||
@@ -1682,7 +1777,8 @@ static PyObject *WraptBoundMethodWrapper_new(PyTypeObject *type,
|
||||
|
||||
self->instance = NULL;
|
||||
self->wrapper = NULL;
|
||||
self->params = NULL;
|
||||
self->wrapper_args = NULL;
|
||||
self->wrapper_kwargs = NULL;
|
||||
|
||||
return (PyObject *)self;
|
||||
}
|
||||
@@ -1695,7 +1791,8 @@ static int WraptBoundMethodWrapper_init(
|
||||
PyObject *wrapped = NULL;
|
||||
PyObject *instance = NULL;
|
||||
PyObject *wrapper = NULL;
|
||||
PyObject *params = NULL;
|
||||
PyObject *wrapper_args = NULL;
|
||||
PyObject *wrapper_kwargs = NULL;
|
||||
|
||||
PyObject *base_args = NULL;
|
||||
PyObject *base_kwds = NULL;
|
||||
@@ -1703,21 +1800,23 @@ static int WraptBoundMethodWrapper_init(
|
||||
int result = 0;
|
||||
|
||||
static char *kwlist[] = { "wrapped", "instance", "wrapper",
|
||||
"params", NULL };
|
||||
"args", "kwargs", NULL };
|
||||
|
||||
if (!PyArg_ParseTupleAndKeywords(args, kwds,
|
||||
"OOO|O:BoundMethodWrapper", kwlist, &wrapped, &instance,
|
||||
&wrapper, ¶ms)) {
|
||||
"OOO|OO:BoundMethodWrapper", kwlist, &wrapped, &instance,
|
||||
&wrapper, &wrapper_args, &wrapper_kwargs)) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
Py_XDECREF(self->instance);
|
||||
Py_XDECREF(self->wrapper);
|
||||
Py_XDECREF(self->params);
|
||||
Py_XDECREF(self->wrapper_args);
|
||||
Py_XDECREF(self->wrapper_kwargs);
|
||||
|
||||
self->instance = NULL;
|
||||
self->wrapper = NULL;
|
||||
self->params = NULL;
|
||||
self->wrapper_args = NULL;
|
||||
self->wrapper_kwargs = NULL;
|
||||
|
||||
base_args = PyTuple_Pack(1, wrapped);
|
||||
base_kwds = PyDict_New();
|
||||
@@ -1732,12 +1831,19 @@ static int WraptBoundMethodWrapper_init(
|
||||
Py_INCREF(wrapper);
|
||||
self->wrapper = wrapper;
|
||||
|
||||
if (params) {
|
||||
Py_INCREF(params);
|
||||
self->params = params;
|
||||
if (wrapper_args) {
|
||||
Py_INCREF(wrapper_args);
|
||||
self->wrapper_args = wrapper_args;
|
||||
}
|
||||
else
|
||||
self->params = PyDict_New();
|
||||
self->wrapper_args = PyTuple_New(0);
|
||||
|
||||
if (wrapper_kwargs) {
|
||||
Py_INCREF(wrapper_kwargs);
|
||||
self->wrapper_kwargs = wrapper_kwargs;
|
||||
}
|
||||
else
|
||||
self->wrapper_kwargs = PyDict_New();
|
||||
}
|
||||
|
||||
Py_DECREF(base_args);
|
||||
@@ -1753,7 +1859,8 @@ static void WraptBoundMethodWrapper_dealloc(
|
||||
{
|
||||
Py_XDECREF(self->instance);
|
||||
Py_XDECREF(self->wrapper);
|
||||
Py_XDECREF(self->params);
|
||||
Py_XDECREF(self->wrapper_args);
|
||||
Py_XDECREF(self->wrapper_kwargs);
|
||||
|
||||
WraptObjectProxy_dealloc((WraptObjectProxyObject *)self);
|
||||
}
|
||||
@@ -1772,6 +1879,9 @@ static PyObject *WraptBoundMethodWrapper_call(
|
||||
|
||||
PyObject *result = NULL;
|
||||
|
||||
int len = 0;
|
||||
int i = 0;
|
||||
|
||||
if (self->instance == Py_None) {
|
||||
PyObject *module = NULL;
|
||||
PyObject *partial = NULL;
|
||||
@@ -1819,15 +1929,34 @@ static PyObject *WraptBoundMethodWrapper_call(
|
||||
kwds = param_kwds;
|
||||
}
|
||||
|
||||
len = PySequence_Size(self->wrapper_args);
|
||||
call_args = PyTuple_New(len+4);
|
||||
|
||||
if (!wrapped) {
|
||||
call_args = PyTuple_Pack(4, self->object_proxy.wrapped, instance,
|
||||
args, kwds);
|
||||
Py_INCREF(self->object_proxy.wrapped);
|
||||
PyTuple_SET_ITEM(call_args, 0, self->object_proxy.wrapped);
|
||||
}
|
||||
else {
|
||||
Py_INCREF(wrapped);
|
||||
PyTuple_SET_ITEM(call_args, 0, wrapped);
|
||||
}
|
||||
|
||||
Py_INCREF(instance);
|
||||
Py_INCREF(args);
|
||||
Py_INCREF(kwds);
|
||||
|
||||
PyTuple_SET_ITEM(call_args, 1, instance);
|
||||
PyTuple_SET_ITEM(call_args, 2, args);
|
||||
PyTuple_SET_ITEM(call_args, 3, kwds);
|
||||
|
||||
for (i=0; i<len; i++) {
|
||||
PyObject *item = PyTuple_GetItem(self->wrapper_args, i);
|
||||
Py_INCREF(item);
|
||||
PyTuple_SET_ITEM(call_args, i+4, item);
|
||||
}
|
||||
else
|
||||
call_args = PyTuple_Pack(4, wrapped, instance, args, kwds);
|
||||
|
||||
result = PyEval_CallObjectWithKeywords(self->wrapper, call_args,
|
||||
self->params);
|
||||
self->wrapper_kwargs);
|
||||
|
||||
Py_DECREF(call_args);
|
||||
Py_XDECREF(param_args);
|
||||
@@ -1867,16 +1996,30 @@ static PyObject *WraptBoundMethodWrapper_get_self_wrapper(
|
||||
|
||||
/* ------------------------------------------------------------------------- */
|
||||
|
||||
static PyObject *WraptBoundMethodWrapper_get_self_params(
|
||||
static PyObject *WraptBoundMethodWrapper_get_self_wrapper_args(
|
||||
WraptBoundMethodWrapperObject *self, void *closure)
|
||||
{
|
||||
if (!self->params) {
|
||||
if (!self->wrapper_args) {
|
||||
Py_INCREF(Py_None);
|
||||
return Py_None;
|
||||
}
|
||||
|
||||
Py_INCREF(self->params);
|
||||
return self->params;
|
||||
Py_INCREF(self->wrapper_args);
|
||||
return self->wrapper_args;
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------------------- */
|
||||
|
||||
static PyObject *WraptBoundMethodWrapper_get_self_wrapper_kwargs(
|
||||
WraptBoundMethodWrapperObject *self, void *closure)
|
||||
{
|
||||
if (!self->wrapper_kwargs) {
|
||||
Py_INCREF(Py_None);
|
||||
return Py_None;
|
||||
}
|
||||
|
||||
Py_INCREF(self->wrapper_kwargs);
|
||||
return self->wrapper_kwargs;
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------------------- */;
|
||||
@@ -1890,7 +2033,9 @@ static PyGetSetDef WraptBoundMethodWrapper_getset[] = {
|
||||
NULL, 0 },
|
||||
{ "_self_wrapper", (getter)WraptBoundMethodWrapper_get_self_wrapper,
|
||||
NULL, 0 },
|
||||
{ "_self_params", (getter)WraptBoundMethodWrapper_get_self_params,
|
||||
{ "_self_wrapper_args", (getter)WraptBoundMethodWrapper_get_self_wrapper_args,
|
||||
NULL, 0 },
|
||||
{ "_self_wrapper_kwargs", (getter)WraptBoundMethodWrapper_get_self_wrapper_kwargs,
|
||||
NULL, 0 },
|
||||
{ NULL },
|
||||
};
|
||||
@@ -1917,8 +2062,7 @@ PyTypeObject WraptBoundMethodWrapper_Type = {
|
||||
0, /*tp_setattro*/
|
||||
0, /*tp_as_buffer*/
|
||||
#if PY_MAJOR_VERSION < 3
|
||||
Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE |
|
||||
Py_TPFLAGS_CHECKTYPES, /*tp_flags*/
|
||||
Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_CHECKTYPES, /*tp_flags*/
|
||||
#else
|
||||
Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /*tp_flags*/
|
||||
#endif
|
||||
|
||||
@@ -116,7 +116,7 @@ def decorator(wrapper=None, target=None):
|
||||
|
||||
def _wrapper(func):
|
||||
result = FunctionWrapper(wrapped=func,
|
||||
wrapper=wrapper, params=decorator_kwargs)
|
||||
wrapper=wrapper, kwargs=decorator_kwargs)
|
||||
if target:
|
||||
_update_adapter(result, target)
|
||||
return result
|
||||
|
||||
@@ -322,23 +322,26 @@ class ObjectProxy(six.with_metaclass(_ObjectProxyMetaType)):
|
||||
|
||||
class _BoundFunctionWrapper(ObjectProxy):
|
||||
|
||||
def __init__(self, wrapped, instance, wrapper, params={}):
|
||||
def __init__(self, wrapped, instance, wrapper, args=(), kwargs={}):
|
||||
super(_BoundFunctionWrapper, self).__init__(wrapped)
|
||||
self._self_instance = instance
|
||||
self._self_wrapper = wrapper
|
||||
self._self_params = params
|
||||
self._self_wrapper_args = args
|
||||
self._self_wrapper_kwargs = kwargs
|
||||
|
||||
def __call__(self, *args, **kwargs):
|
||||
return self._self_wrapper(self._self_wrapped, self._self_instance,
|
||||
args, kwargs, **self._self_params)
|
||||
args, kwargs, *self._self_wrapper_args,
|
||||
**self._self_wrapper_kwargs)
|
||||
|
||||
class _BoundMethodWrapper(ObjectProxy):
|
||||
|
||||
def __init__(self, wrapped, instance, wrapper, params={}):
|
||||
def __init__(self, wrapped, instance, wrapper, args=(), kwargs={}):
|
||||
super(_BoundMethodWrapper, self).__init__(wrapped)
|
||||
self._self_instance = instance
|
||||
self._self_wrapper = wrapper
|
||||
self._self_params = params
|
||||
self._self_wrapper_args = args
|
||||
self._self_wrapper_kwargs = kwargs
|
||||
|
||||
def __call__(self, *args, **kwargs):
|
||||
if self._self_instance is None:
|
||||
@@ -352,17 +355,19 @@ class _BoundMethodWrapper(ObjectProxy):
|
||||
instance, args = args[0], args[1:]
|
||||
wrapped = functools.partial(self._self_wrapped, instance)
|
||||
return self._self_wrapper(wrapped, instance, args, kwargs,
|
||||
**self._self_params)
|
||||
*self._self_wrapper_args, **self._self_wrapper_kwargs)
|
||||
|
||||
return self._self_wrapper(self._self_wrapped, self._self_instance,
|
||||
args, kwargs, **self._self_params)
|
||||
args, kwargs, *self._self_wrapper_args,
|
||||
**self._self_wrapper_kwargs)
|
||||
|
||||
class FunctionWrapper(ObjectProxy):
|
||||
|
||||
def __init__(self, wrapped, wrapper, params={}):
|
||||
def __init__(self, wrapped, wrapper, args=(), kwargs={}):
|
||||
super(FunctionWrapper, self).__init__(wrapped)
|
||||
self._self_wrapper = wrapper
|
||||
self._self_params = params
|
||||
self._self_wrapper_args = args
|
||||
self._self_wrapper_kwargs = kwargs
|
||||
|
||||
# We need to do special fixups on the args in the case of an
|
||||
# instancemethod where called via the class and the instance is
|
||||
@@ -405,7 +410,7 @@ class FunctionWrapper(ObjectProxy):
|
||||
descriptor = self._self_wrapped.__get__(instance, owner)
|
||||
|
||||
return self._self_bound_type(descriptor, instance, self._self_wrapper,
|
||||
self._self_params)
|
||||
self._self_wrapper_args, self._self_wrapper_kwargs)
|
||||
|
||||
def __call__(self, *args, **kwargs):
|
||||
# This is invoked when the wrapped function is being called as a
|
||||
@@ -415,7 +420,7 @@ class FunctionWrapper(ObjectProxy):
|
||||
# using the staticmethod decorator.
|
||||
|
||||
return self._self_wrapper(self._self_wrapped, None, args,
|
||||
kwargs, **self._self_params)
|
||||
kwargs, *self._self_wrapper_args, **self._self_wrapper_kwargs)
|
||||
|
||||
try:
|
||||
from ._wrappers import ObjectProxy as C_ObjectProxy
|
||||
|
||||
@@ -89,7 +89,8 @@ class TestAttributeAccess(unittest.TestCase):
|
||||
|
||||
self.assertEqual(function2._self_wrapped, function1)
|
||||
self.assertEqual(function2._self_wrapper, decorator1)
|
||||
self.assertEqual(function2._self_params, {})
|
||||
self.assertEqual(function2._self_wrapper_args, ())
|
||||
self.assertEqual(function2._self_wrapper_kwargs, {})
|
||||
self.assertNotEqual(function2._self_bound_type, None)
|
||||
|
||||
def test_instancemethod_attributes(self):
|
||||
@@ -104,7 +105,8 @@ class TestAttributeAccess(unittest.TestCase):
|
||||
|
||||
self.assertEqual(function2._self_wrapped, function1)
|
||||
self.assertEqual(function2._self_wrapper, decorator1)
|
||||
self.assertEqual(function2._self_params, {})
|
||||
self.assertEqual(function2._self_wrapper_args, ())
|
||||
self.assertEqual(function2._self_wrapper_kwargs, {})
|
||||
self.assertNotEqual(function2._self_bound_type, None)
|
||||
|
||||
instance = Class()
|
||||
@@ -112,7 +114,8 @@ class TestAttributeAccess(unittest.TestCase):
|
||||
self.assertEqual(instance.function2._self_wrapped, instance.function1)
|
||||
self.assertEqual(instance.function2._self_instance, instance)
|
||||
self.assertEqual(instance.function2._self_wrapper, decorator1)
|
||||
self.assertEqual(instance.function2._self_params, {})
|
||||
self.assertEqual(instance.function2._self_wrapper_args, ())
|
||||
self.assertEqual(instance.function2._self_wrapper_kwargs, {})
|
||||
|
||||
def test_classmethod_attributes(self):
|
||||
def decorator1(wrapped, instance, args, kwargs):
|
||||
@@ -127,7 +130,8 @@ class TestAttributeAccess(unittest.TestCase):
|
||||
|
||||
self.assertEqual(function2._self_wrapped, function1)
|
||||
self.assertEqual(function2._self_wrapper, decorator1)
|
||||
self.assertEqual(function2._self_params, {})
|
||||
self.assertEqual(function2._self_wrapper_args, ())
|
||||
self.assertEqual(function2._self_wrapper_kwargs, {})
|
||||
self.assertNotEqual(function2._self_bound_type, None)
|
||||
|
||||
instance = Class()
|
||||
@@ -135,7 +139,8 @@ class TestAttributeAccess(unittest.TestCase):
|
||||
self.assertEqual(instance.function2._self_wrapped, instance.function1)
|
||||
self.assertEqual(instance.function2._self_instance, instance)
|
||||
self.assertEqual(instance.function2._self_wrapper, decorator1)
|
||||
self.assertEqual(instance.function2._self_params, {})
|
||||
self.assertEqual(instance.function2._self_wrapper_args, ())
|
||||
self.assertEqual(instance.function2._self_wrapper_kwargs, {})
|
||||
|
||||
def test_staticmethod_attributes(self):
|
||||
def decorator1(wrapped, instance, args, kwargs):
|
||||
@@ -150,7 +155,8 @@ class TestAttributeAccess(unittest.TestCase):
|
||||
|
||||
self.assertEqual(function2._self_wrapped, function1)
|
||||
self.assertEqual(function2._self_wrapper, decorator1)
|
||||
self.assertEqual(function2._self_params, {})
|
||||
self.assertEqual(function2._self_wrapper_args, ())
|
||||
self.assertEqual(function2._self_wrapper_kwargs, {})
|
||||
self.assertNotEqual(function2._self_bound_type, None)
|
||||
|
||||
instance = Class()
|
||||
@@ -158,7 +164,8 @@ class TestAttributeAccess(unittest.TestCase):
|
||||
self.assertEqual(instance.function2._self_wrapped, instance.function1)
|
||||
self.assertEqual(instance.function2._self_instance, instance)
|
||||
self.assertEqual(instance.function2._self_wrapper, decorator1)
|
||||
self.assertEqual(instance.function2._self_params, {})
|
||||
self.assertEqual(instance.function2._self_wrapper_args, ())
|
||||
self.assertEqual(instance.function2._self_wrapper_kwargs, {})
|
||||
|
||||
if __name__ == '__main__':
|
||||
unittest.main()
|
||||
|
||||
Reference in New Issue
Block a user