Drop wrapper args/kwargs concept from function wrappers as now relying on closures. #1
This commit is contained in:
176
src/_wrappers.c
176
src/_wrappers.c
@@ -24,8 +24,6 @@ typedef struct {
|
||||
|
||||
PyObject *instance;
|
||||
PyObject *wrapper;
|
||||
PyObject *wrapper_args;
|
||||
PyObject *wrapper_kwargs;
|
||||
PyObject *adapter;
|
||||
PyObject *bound_type;
|
||||
} WraptFunctionWrapperObject;
|
||||
@@ -1299,8 +1297,6 @@ static PyObject *WraptFunctionWrapperBase_new(PyTypeObject *type,
|
||||
|
||||
self->instance = NULL;
|
||||
self->wrapper = NULL;
|
||||
self->wrapper_args = NULL;
|
||||
self->wrapper_kwargs = NULL;
|
||||
self->adapter = NULL;
|
||||
self->bound_type = NULL;
|
||||
|
||||
@@ -1311,8 +1307,7 @@ static PyObject *WraptFunctionWrapperBase_new(PyTypeObject *type,
|
||||
|
||||
static int WraptFunctionWrapperBase_raw_init(WraptFunctionWrapperObject *self,
|
||||
PyObject *wrapped, PyObject *instance, PyObject *wrapper,
|
||||
PyObject *wrapper_args, PyObject *wrapper_kwargs, PyObject *adapter,
|
||||
PyObject *bound_type)
|
||||
PyObject *adapter, PyObject *bound_type)
|
||||
{
|
||||
int result = 0;
|
||||
|
||||
@@ -1328,26 +1323,6 @@ static int WraptFunctionWrapperBase_raw_init(WraptFunctionWrapperObject *self,
|
||||
Py_XDECREF(self->wrapper);
|
||||
self->wrapper = wrapper;
|
||||
|
||||
if (wrapper_args) {
|
||||
Py_INCREF(wrapper_args);
|
||||
Py_XDECREF(self->wrapper_args);
|
||||
self->wrapper_args = wrapper_args;
|
||||
}
|
||||
else {
|
||||
Py_XDECREF(self->wrapper_args);
|
||||
self->wrapper_args = PyTuple_New(0);
|
||||
}
|
||||
|
||||
if (wrapper_kwargs) {
|
||||
Py_INCREF(wrapper_kwargs);
|
||||
Py_XDECREF(self->wrapper_kwargs);
|
||||
self->wrapper_kwargs = wrapper_kwargs;
|
||||
}
|
||||
else {
|
||||
Py_XDECREF(self->wrapper_kwargs);
|
||||
self->wrapper_kwargs = PyDict_New();
|
||||
}
|
||||
|
||||
Py_INCREF(adapter);
|
||||
Py_XDECREF(self->adapter);
|
||||
self->adapter = adapter;
|
||||
@@ -1368,22 +1343,19 @@ static int WraptFunctionWrapperBase_init(WraptFunctionWrapperObject *self,
|
||||
PyObject *wrapped = NULL;
|
||||
PyObject *instance = NULL;
|
||||
PyObject *wrapper = NULL;
|
||||
PyObject *wrapper_args = NULL;
|
||||
PyObject *wrapper_kwargs = NULL;
|
||||
PyObject *adapter = Py_None;
|
||||
PyObject *bound_type = Py_None;
|
||||
|
||||
static char *kwlist[] = { "wrapped", "instance", "wrapper",
|
||||
"wrapper_args", "wrapper_kwargs", "adapter", "bound_type", NULL };
|
||||
"adapter", "bound_type", NULL };
|
||||
|
||||
if (!PyArg_ParseTupleAndKeywords(args, kwds, "OOO|OOOO:FunctionWrapperBase",
|
||||
kwlist, &wrapped, &instance, &wrapper, &wrapper_args,
|
||||
&wrapper_kwargs, &adapter, &bound_type)) {
|
||||
if (!PyArg_ParseTupleAndKeywords(args, kwds, "OOO|OO:FunctionWrapperBase",
|
||||
kwlist, &wrapped, &instance, &wrapper, &adapter, &bound_type)) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
return WraptFunctionWrapperBase_raw_init(self, wrapped, instance, wrapper,
|
||||
wrapper_args, wrapper_kwargs, adapter, bound_type);
|
||||
adapter, bound_type);
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------------------- */
|
||||
@@ -1395,8 +1367,6 @@ static int WraptFunctionWrapperBase_traverse(WraptFunctionWrapperObject *self,
|
||||
|
||||
Py_VISIT(self->instance);
|
||||
Py_VISIT(self->wrapper);
|
||||
Py_VISIT(self->wrapper_args);
|
||||
Py_VISIT(self->wrapper_kwargs);
|
||||
Py_VISIT(self->adapter);
|
||||
Py_VISIT(self->bound_type);
|
||||
|
||||
@@ -1411,8 +1381,6 @@ static int WraptFunctionWrapperBase_clear(WraptFunctionWrapperObject *self)
|
||||
|
||||
Py_CLEAR(self->instance);
|
||||
Py_CLEAR(self->wrapper);
|
||||
Py_CLEAR(self->wrapper_args);
|
||||
Py_CLEAR(self->wrapper_kwargs);
|
||||
Py_CLEAR(self->adapter);
|
||||
Py_CLEAR(self->bound_type);
|
||||
|
||||
@@ -1446,27 +1414,10 @@ static PyObject *WraptFunctionWrapperBase_call(
|
||||
kwds = param_kwds;
|
||||
}
|
||||
|
||||
len = PySequence_Size(self->wrapper_args);
|
||||
call_args = PyTuple_New(len+4);
|
||||
call_args = PyTuple_Pack(4, self->object_proxy.wrapped, Py_None,
|
||||
args, kwds);
|
||||
|
||||
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->wrapper_kwargs);
|
||||
result = PyEval_CallObject(self->wrapper, call_args);
|
||||
|
||||
Py_DECREF(call_args);
|
||||
Py_XDECREF(param_kwds);
|
||||
@@ -1496,9 +1447,8 @@ static PyObject *WraptFunctionWrapperBase_descr_get(
|
||||
type = Py_None;
|
||||
|
||||
if (descriptor) {
|
||||
result = PyObject_CallFunction(self->bound_type, "(OOOOO)",
|
||||
descriptor, obj, self->wrapper, self->wrapper_args,
|
||||
self->wrapper_kwargs);
|
||||
result = PyObject_CallFunction(self->bound_type, "(OOO)",
|
||||
descriptor, obj, self->wrapper);
|
||||
}
|
||||
|
||||
Py_XDECREF(descriptor);
|
||||
@@ -1600,34 +1550,6 @@ static PyObject *WraptFunctionWrapperBase_get_self_wrapper(
|
||||
|
||||
/* ------------------------------------------------------------------------- */
|
||||
|
||||
static PyObject *WraptFunctionWrapperBase_get_self_wrapper_args(
|
||||
WraptFunctionWrapperObject *self, void *closure)
|
||||
{
|
||||
if (!self->wrapper_args) {
|
||||
Py_INCREF(Py_None);
|
||||
return Py_None;
|
||||
}
|
||||
|
||||
Py_INCREF(self->wrapper_args);
|
||||
return self->wrapper_args;
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------------------- */
|
||||
|
||||
static PyObject *WraptFunctionWrapperBase_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;
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------------------- */
|
||||
|
||||
static PyObject *WraptFunctionWrapperBase_get_self_adapter(
|
||||
WraptFunctionWrapperObject *self, void *closure)
|
||||
{
|
||||
@@ -1679,10 +1601,6 @@ static PyGetSetDef WraptFunctionWrapperBase_getset[] = {
|
||||
NULL, 0 },
|
||||
{ "_self_wrapper", (getter)WraptFunctionWrapperBase_get_self_wrapper,
|
||||
NULL, 0 },
|
||||
{ "_self_wrapper_args", (getter)WraptFunctionWrapperBase_get_self_wrapper_args,
|
||||
NULL, 0 },
|
||||
{ "_self_wrapper_kwargs", (getter)WraptFunctionWrapperBase_get_self_wrapper_kwargs,
|
||||
NULL, 0 },
|
||||
{ "_self_adapter", (getter)WraptFunctionWrapperBase_get_self_adapter,
|
||||
NULL, 0 },
|
||||
{ "_self_bound_type", (getter)WraptFunctionWrapperBase_get_self_bound_type,
|
||||
@@ -1775,27 +1693,10 @@ static PyObject *WraptBoundFunctionWrapper_call(
|
||||
instance = Py_None;
|
||||
}
|
||||
|
||||
len = PySequence_Size(self->wrapper_args);
|
||||
call_args = PyTuple_New(len+4);
|
||||
call_args = PyTuple_Pack(4, self->object_proxy.wrapped, instance,
|
||||
args, kwds);
|
||||
|
||||
Py_INCREF(self->object_proxy.wrapped);
|
||||
Py_INCREF(instance);
|
||||
Py_INCREF(args);
|
||||
Py_INCREF(kwds);
|
||||
|
||||
PyTuple_SET_ITEM(call_args, 0, self->object_proxy.wrapped);
|
||||
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);
|
||||
}
|
||||
|
||||
result = PyEval_CallObjectWithKeywords(self->wrapper, call_args,
|
||||
self->wrapper_kwargs);
|
||||
result = PyEval_CallObject(self->wrapper, call_args);
|
||||
|
||||
Py_DECREF(call_args);
|
||||
Py_XDECREF(param_kwds);
|
||||
@@ -1927,34 +1828,14 @@ static PyObject *WraptBoundMethodWrapper_call(
|
||||
kwds = param_kwds;
|
||||
}
|
||||
|
||||
len = PySequence_Size(self->wrapper_args);
|
||||
call_args = PyTuple_New(len+4);
|
||||
|
||||
if (!wrapped) {
|
||||
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);
|
||||
wrapped = self->object_proxy.wrapped;
|
||||
}
|
||||
|
||||
Py_INCREF(instance);
|
||||
Py_INCREF(args);
|
||||
Py_INCREF(kwds);
|
||||
call_args = PyTuple_Pack(4, wrapped, instance, args, 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);
|
||||
}
|
||||
|
||||
result = PyEval_CallObjectWithKeywords(self->wrapper, call_args,
|
||||
self->wrapper_kwargs);
|
||||
result = PyEval_CallObject(self->wrapper, call_args);
|
||||
|
||||
Py_DECREF(call_args);
|
||||
Py_XDECREF(param_args);
|
||||
@@ -2029,19 +1910,15 @@ static int WraptFunctionWrapper_init(WraptFunctionWrapperObject *self,
|
||||
{
|
||||
PyObject *wrapped = NULL;
|
||||
PyObject *wrapper = NULL;
|
||||
PyObject *wrapper_args = NULL;
|
||||
PyObject *wrapper_kwargs = NULL;
|
||||
PyObject *adapter = Py_None;
|
||||
PyObject *bound_type = NULL;
|
||||
|
||||
int result = 0;
|
||||
|
||||
static char *kwlist[] = { "wrapped", "wrapper", "wrapper_args",
|
||||
"wrapper_kwargs", "adapter", NULL };
|
||||
static char *kwlist[] = { "wrapped", "wrapper", "adapter", NULL };
|
||||
|
||||
if (!PyArg_ParseTupleAndKeywords(args, kwds, "OO|OOO:FunctionWrapper",
|
||||
kwlist, &wrapped, &wrapper, &wrapper_args, &wrapper_kwargs,
|
||||
&adapter)) {
|
||||
if (!PyArg_ParseTupleAndKeywords(args, kwds, "OO|O:FunctionWrapper",
|
||||
kwlist, &wrapped, &wrapper, &adapter)) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
@@ -2056,21 +1933,8 @@ static int WraptFunctionWrapper_init(WraptFunctionWrapperObject *self,
|
||||
bound_type = (PyObject *)&WraptBoundMethodWrapper_Type;
|
||||
}
|
||||
|
||||
if (!wrapper_args)
|
||||
wrapper_args = PyTuple_New(0);
|
||||
else
|
||||
Py_INCREF(wrapper_args);
|
||||
|
||||
if (!wrapper_kwargs)
|
||||
wrapper_kwargs = PyDict_New();
|
||||
else
|
||||
Py_INCREF(wrapper_kwargs);
|
||||
|
||||
result = WraptFunctionWrapperBase_raw_init(self, wrapped, Py_None,
|
||||
wrapper, wrapper_args, wrapper_kwargs, adapter, bound_type);
|
||||
|
||||
Py_DECREF(wrapper_args);
|
||||
Py_DECREF(wrapper_kwargs);
|
||||
wrapper, adapter, bound_type);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
@@ -362,15 +362,13 @@ class ObjectProxy(six.with_metaclass(_ObjectProxyMetaType)):
|
||||
|
||||
class _FunctionWrapperBase(ObjectProxy):
|
||||
|
||||
def __init__(self, wrapped, instance, wrapper, wrapper_args=(),
|
||||
wrapper_kwargs={}, adapter=None, bound_type=None):
|
||||
def __init__(self, wrapped, instance, wrapper, adapter=None,
|
||||
bound_type=None):
|
||||
|
||||
super(_FunctionWrapperBase, self).__init__(wrapped)
|
||||
|
||||
object.__setattr__(self, '_self_instance', instance)
|
||||
object.__setattr__(self, '_self_wrapper', wrapper)
|
||||
object.__setattr__(self, '_self_wrapper_args', wrapper_args)
|
||||
object.__setattr__(self, '_self_wrapper_kwargs', wrapper_kwargs)
|
||||
object.__setattr__(self, '_self_adapter', adapter)
|
||||
object.__setattr__(self, '_self_bound_type', bound_type)
|
||||
|
||||
@@ -385,7 +383,6 @@ class _FunctionWrapperBase(ObjectProxy):
|
||||
descriptor = self._self_wrapped.__get__(instance, owner)
|
||||
|
||||
return self._self_bound_type(descriptor, instance, self._self_wrapper,
|
||||
self._self_wrapper_args, self._self_wrapper_kwargs,
|
||||
self._self_adapter)
|
||||
|
||||
def __call__(self, *args, **kwargs):
|
||||
@@ -396,8 +393,7 @@ class _FunctionWrapperBase(ObjectProxy):
|
||||
# wrapped using the staticmethod decorator.
|
||||
|
||||
return self._self_wrapper(self._self_wrapped, self._self_instance,
|
||||
args, kwargs, *self._self_wrapper_args,
|
||||
**self._self_wrapper_kwargs)
|
||||
args, kwargs)
|
||||
|
||||
# If an adapter function was provided we want to return certain
|
||||
# attributes of the function from the adapter rather than the
|
||||
@@ -454,9 +450,7 @@ class _BoundFunctionWrapper(_FunctionWrapperBase):
|
||||
|
||||
instance = getattr(self._self_wrapped, '__self__', None)
|
||||
|
||||
return self._self_wrapper(self._self_wrapped, instance,
|
||||
args, kwargs, *self._self_wrapper_args,
|
||||
**self._self_wrapper_kwargs)
|
||||
return self._self_wrapper(self._self_wrapped, instance, args, kwargs)
|
||||
|
||||
class _BoundMethodWrapper(_FunctionWrapperBase):
|
||||
|
||||
@@ -471,17 +465,14 @@ class _BoundMethodWrapper(_FunctionWrapperBase):
|
||||
|
||||
instance, args = args[0], args[1:]
|
||||
wrapped = functools.partial(self._self_wrapped, instance)
|
||||
return self._self_wrapper(wrapped, instance, args, kwargs,
|
||||
*self._self_wrapper_args, **self._self_wrapper_kwargs)
|
||||
return self._self_wrapper(wrapped, instance, args, kwargs)
|
||||
|
||||
return self._self_wrapper(self._self_wrapped, self._self_instance,
|
||||
args, kwargs, *self._self_wrapper_args,
|
||||
**self._self_wrapper_kwargs)
|
||||
args, kwargs)
|
||||
|
||||
class FunctionWrapper(_FunctionWrapperBase):
|
||||
|
||||
def __init__(self, wrapped, wrapper, wrapper_args=(), wrapper_kwargs={},
|
||||
adapter=None):
|
||||
def __init__(self, wrapped, wrapper, adapter=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
|
||||
@@ -515,7 +506,7 @@ class FunctionWrapper(_FunctionWrapperBase):
|
||||
bound_type = _BoundMethodWrapper
|
||||
|
||||
super(FunctionWrapper, self).__init__(wrapped, None, wrapper,
|
||||
wrapper_args, wrapper_kwargs, adapter, bound_type)
|
||||
adapter, bound_type)
|
||||
|
||||
try:
|
||||
from ._wrappers import ObjectProxy, FunctionWrapper
|
||||
|
||||
@@ -89,8 +89,6 @@ class TestAttributeAccess(unittest.TestCase):
|
||||
|
||||
self.assertEqual(function2._self_wrapped, function1)
|
||||
self.assertEqual(function2._self_wrapper, decorator1)
|
||||
self.assertEqual(function2._self_wrapper_args, ())
|
||||
self.assertEqual(function2._self_wrapper_kwargs, {})
|
||||
self.assertNotEqual(function2._self_bound_type, None)
|
||||
|
||||
def test_instancemethod_attributes(self):
|
||||
@@ -105,8 +103,6 @@ class TestAttributeAccess(unittest.TestCase):
|
||||
|
||||
self.assertEqual(function2._self_wrapped, function1)
|
||||
self.assertEqual(function2._self_wrapper, decorator1)
|
||||
self.assertEqual(function2._self_wrapper_args, ())
|
||||
self.assertEqual(function2._self_wrapper_kwargs, {})
|
||||
self.assertNotEqual(function2._self_bound_type, None)
|
||||
|
||||
instance = Class()
|
||||
@@ -114,8 +110,6 @@ 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_wrapper_args, ())
|
||||
self.assertEqual(instance.function2._self_wrapper_kwargs, {})
|
||||
|
||||
def test_classmethod_attributes(self):
|
||||
def decorator1(wrapped, instance, args, kwargs):
|
||||
@@ -130,8 +124,6 @@ class TestAttributeAccess(unittest.TestCase):
|
||||
|
||||
self.assertEqual(function2._self_wrapped, function1)
|
||||
self.assertEqual(function2._self_wrapper, decorator1)
|
||||
self.assertEqual(function2._self_wrapper_args, ())
|
||||
self.assertEqual(function2._self_wrapper_kwargs, {})
|
||||
self.assertNotEqual(function2._self_bound_type, None)
|
||||
|
||||
instance = Class()
|
||||
@@ -139,8 +131,6 @@ 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_wrapper_args, ())
|
||||
self.assertEqual(instance.function2._self_wrapper_kwargs, {})
|
||||
|
||||
def test_staticmethod_attributes(self):
|
||||
def decorator1(wrapped, instance, args, kwargs):
|
||||
@@ -155,8 +145,6 @@ class TestAttributeAccess(unittest.TestCase):
|
||||
|
||||
self.assertEqual(function2._self_wrapped, function1)
|
||||
self.assertEqual(function2._self_wrapper, decorator1)
|
||||
self.assertEqual(function2._self_wrapper_args, ())
|
||||
self.assertEqual(function2._self_wrapper_kwargs, {})
|
||||
self.assertNotEqual(function2._self_bound_type, None)
|
||||
|
||||
instance = Class()
|
||||
@@ -164,8 +152,6 @@ 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_wrapper_args, ())
|
||||
self.assertEqual(instance.function2._self_wrapper_kwargs, {})
|
||||
|
||||
if __name__ == '__main__':
|
||||
unittest.main()
|
||||
|
||||
Reference in New Issue
Block a user