Implement BoundFunctionWrapper and BoundMethodWrapper as part of C extension to improve performance.
This commit is contained in:
521
src/_wrappers.c
521
src/_wrappers.c
@@ -28,6 +28,22 @@ typedef struct {
|
||||
|
||||
PyTypeObject WraptFunctionWrapper_Type;
|
||||
|
||||
typedef struct {
|
||||
WraptWrapperBaseObject wrapper_base;
|
||||
PyObject *instance;
|
||||
PyObject *params;
|
||||
} WraptBoundFunctionWrapperObject;
|
||||
|
||||
PyTypeObject WraptBoundFunctionWrapper_Type;
|
||||
|
||||
typedef struct {
|
||||
WraptWrapperBaseObject wrapper_base;
|
||||
PyObject *instance;
|
||||
PyObject *params;
|
||||
} WraptBoundMethodWrapperObject;
|
||||
|
||||
PyTypeObject WraptBoundMethodWrapper_Type;
|
||||
|
||||
/* ------------------------------------------------------------------------- */
|
||||
|
||||
static PyObject *WraptWrapperBase_new(PyTypeObject *type,
|
||||
@@ -447,10 +463,6 @@ static int WraptFunctionWrapper_init(WraptFunctionWrapperObject *self,
|
||||
base_args, base_kwds);
|
||||
|
||||
if (result == 0) {
|
||||
PyObject *module = NULL;
|
||||
PyObject *dict = NULL;
|
||||
PyObject *object = NULL;
|
||||
|
||||
if (params) {
|
||||
Py_INCREF(params);
|
||||
self->params = params;
|
||||
@@ -458,30 +470,16 @@ static int WraptFunctionWrapper_init(WraptFunctionWrapperObject *self,
|
||||
else
|
||||
self->params = PyDict_New();
|
||||
|
||||
module = PyImport_ImportModule("wrapt.wrappers");
|
||||
|
||||
if (module)
|
||||
dict = PyModule_GetDict(module);
|
||||
|
||||
if (dict) {
|
||||
if (PyObject_IsInstance(wrapped,
|
||||
(PyObject *)&PyClassMethod_Type) || PyObject_IsInstance(
|
||||
wrapped, (PyObject *)&PyStaticMethod_Type)) {
|
||||
object = PyDict_GetItemString(dict, "BoundFunctionWrapper");
|
||||
}
|
||||
else {
|
||||
object = PyDict_GetItemString(dict, "BoundMethodWrapper");
|
||||
}
|
||||
if (PyObject_IsInstance(wrapped,
|
||||
(PyObject *)&PyClassMethod_Type) || PyObject_IsInstance(
|
||||
wrapped, (PyObject *)&PyStaticMethod_Type)) {
|
||||
Py_INCREF((PyObject *)&WraptBoundFunctionWrapper_Type);
|
||||
self->wrapper_type = (PyObject *)&WraptBoundFunctionWrapper_Type;
|
||||
}
|
||||
|
||||
if (object) {
|
||||
Py_INCREF(object);
|
||||
self->wrapper_type = object;
|
||||
else {
|
||||
Py_INCREF((PyObject *)&WraptBoundMethodWrapper_Type);
|
||||
self->wrapper_type = (PyObject *)&WraptBoundMethodWrapper_Type;
|
||||
}
|
||||
else
|
||||
result = -1;
|
||||
|
||||
Py_XDECREF(module);
|
||||
}
|
||||
|
||||
Py_DECREF(base_args);
|
||||
@@ -645,6 +643,470 @@ PyTypeObject WraptFunctionWrapper_Type = {
|
||||
0, /*tp_is_gc*/
|
||||
};
|
||||
|
||||
/* ------------------------------------------------------------------------- */
|
||||
|
||||
static PyObject *WraptBoundFunctionWrapper_new(PyTypeObject *type,
|
||||
PyObject *args, PyObject *kwds)
|
||||
{
|
||||
WraptBoundFunctionWrapperObject *self;
|
||||
|
||||
self = (WraptBoundFunctionWrapperObject *)WraptWrapperBase_new(type,
|
||||
args, kwds);
|
||||
|
||||
if (!self)
|
||||
return NULL;
|
||||
|
||||
self->instance = NULL;
|
||||
self->params = NULL;
|
||||
|
||||
return (PyObject *)self;
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------------------- */
|
||||
|
||||
static int WraptBoundFunctionWrapper_init(
|
||||
WraptBoundFunctionWrapperObject *self, PyObject *args, PyObject *kwds)
|
||||
{
|
||||
PyObject *wrapped = NULL;
|
||||
PyObject *instance = NULL;
|
||||
PyObject *wrapper = NULL;
|
||||
PyObject *target = NULL;
|
||||
PyObject *params = NULL;
|
||||
|
||||
PyObject *base_args = NULL;
|
||||
PyObject *base_kwds = NULL;
|
||||
|
||||
int result = 0;
|
||||
|
||||
static char *kwlist[] = { "wrapped", "instance", "wrapper",
|
||||
"target", "params", NULL };
|
||||
|
||||
if (!PyArg_ParseTupleAndKeywords(args, kwds,
|
||||
"OOO|OO:BoundFunctionWrapper", kwlist, &wrapped, &instance,
|
||||
&wrapper, &target, ¶ms)) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
Py_XDECREF(self->instance);
|
||||
Py_XDECREF(self->params);
|
||||
|
||||
self->instance = NULL;
|
||||
self->params = NULL;
|
||||
|
||||
if (!target)
|
||||
target = Py_None;
|
||||
|
||||
base_args = PyTuple_Pack(3, wrapped, wrapper, target);
|
||||
base_kwds = PyDict_New();
|
||||
|
||||
result = WraptWrapperBase_init((WraptWrapperBaseObject *)self,
|
||||
base_args, base_kwds);
|
||||
|
||||
if (result == 0) {
|
||||
Py_INCREF(instance);
|
||||
self->instance = instance;
|
||||
|
||||
if (params) {
|
||||
Py_INCREF(params);
|
||||
self->params = params;
|
||||
}
|
||||
else
|
||||
self->params = PyDict_New();
|
||||
}
|
||||
|
||||
Py_DECREF(base_args);
|
||||
Py_DECREF(base_kwds);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------------------- */
|
||||
|
||||
static void WraptBoundFunctionWrapper_dealloc(
|
||||
WraptBoundFunctionWrapperObject *self)
|
||||
{
|
||||
Py_XDECREF(self->instance);
|
||||
Py_XDECREF(self->params);
|
||||
|
||||
WraptWrapperBase_dealloc((WraptWrapperBaseObject *)self);
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------------------- */
|
||||
|
||||
static PyObject *WraptBoundFunctionWrapper_call(
|
||||
WraptBoundFunctionWrapperObject *self, PyObject *args, PyObject *kwds)
|
||||
{
|
||||
PyObject *call_args = NULL;
|
||||
PyObject *param_kwds = NULL;
|
||||
|
||||
PyObject *result = NULL;
|
||||
|
||||
if (!kwds) {
|
||||
param_kwds = PyDict_New();
|
||||
kwds = param_kwds;
|
||||
}
|
||||
|
||||
call_args = PyTuple_Pack(4, self->wrapper_base.wrapped, self->instance,
|
||||
args, kwds);
|
||||
|
||||
result = PyEval_CallObjectWithKeywords(self->wrapper_base.wrapper,
|
||||
call_args, self->params);
|
||||
|
||||
Py_DECREF(call_args);
|
||||
Py_XDECREF(param_kwds);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------------------- */
|
||||
|
||||
static PyObject *WraptBoundFunctionWrapper_get_instance(
|
||||
WraptBoundFunctionWrapperObject *self, void *closure)
|
||||
{
|
||||
if (!self->instance) {
|
||||
Py_INCREF(Py_None);
|
||||
return Py_None;
|
||||
}
|
||||
|
||||
Py_INCREF(self->instance);
|
||||
return self->instance;
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------------------- */
|
||||
|
||||
static PyObject *WraptBoundFunctionWrapper_get_params(
|
||||
WraptBoundFunctionWrapperObject *self, void *closure)
|
||||
{
|
||||
if (!self->params) {
|
||||
Py_INCREF(Py_None);
|
||||
return Py_None;
|
||||
}
|
||||
|
||||
Py_INCREF(self->params);
|
||||
return self->params;
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------------------- */;
|
||||
|
||||
static PyGetSetDef WraptBoundFunctionWrapper_getset[] = {
|
||||
{ "_self_wrapped", (getter)WraptWrapperBase_get_wrapped,
|
||||
NULL, 0 },
|
||||
{ "_self_instance", (getter)WraptBoundFunctionWrapper_get_instance,
|
||||
NULL, 0 },
|
||||
{ "_self_wrapper", (getter)WraptWrapperBase_get_wrapper,
|
||||
NULL, 0 },
|
||||
{ "_self_target", (getter)WraptWrapperBase_get_target,
|
||||
NULL, 0 },
|
||||
{ "_self_params", (getter)WraptBoundFunctionWrapper_get_params,
|
||||
NULL, 0 },
|
||||
{ "__class__", (getter)WraptWrapperBase_get_class,
|
||||
NULL, 0 },
|
||||
{ NULL },
|
||||
};
|
||||
|
||||
PyTypeObject WraptBoundFunctionWrapper_Type = {
|
||||
PyVarObject_HEAD_INIT(NULL, 0)
|
||||
"_wrappers.BoundFunctionWrapper", /*tp_name*/
|
||||
sizeof(WraptBoundFunctionWrapperObject), /*tp_basicsize*/
|
||||
0, /*tp_itemsize*/
|
||||
/* methods */
|
||||
(destructor)WraptBoundFunctionWrapper_dealloc, /*tp_dealloc*/
|
||||
0, /*tp_print*/
|
||||
0, /*tp_getattr*/
|
||||
0, /*tp_setattr*/
|
||||
0, /*tp_compare*/
|
||||
0, /*tp_repr*/
|
||||
0, /*tp_as_number*/
|
||||
0, /*tp_as_sequence*/
|
||||
0, /*tp_as_mapping*/
|
||||
0, /*tp_hash*/
|
||||
(ternaryfunc)WraptBoundFunctionWrapper_call, /*tp_call*/
|
||||
0, /*tp_str*/
|
||||
(getattrofunc)WraptWrapperBase_getattro, /*tp_getattro*/
|
||||
(setattrofunc)WraptWrapperBase_setattro, /*tp_setattro*/
|
||||
0, /*tp_as_buffer*/
|
||||
Py_TPFLAGS_DEFAULT |
|
||||
Py_TPFLAGS_BASETYPE, /*tp_flags*/
|
||||
0, /*tp_doc*/
|
||||
0, /*tp_traverse*/
|
||||
0, /*tp_clear*/
|
||||
0, /*tp_richcompare*/
|
||||
0, /*tp_weaklistoffset*/
|
||||
(getiterfunc)WraptWrapperBase_iter, /*tp_iter*/
|
||||
0, /*tp_iternext*/
|
||||
0, /*tp_methods*/
|
||||
0, /*tp_members*/
|
||||
WraptBoundFunctionWrapper_getset, /*tp_getset*/
|
||||
0, /*tp_base*/
|
||||
0, /*tp_dict*/
|
||||
0, /*tp_descr_get*/
|
||||
0, /*tp_descr_set*/
|
||||
offsetof(WraptWrapperBaseObject, dict), /*tp_dictoffset*/
|
||||
(initproc)WraptBoundFunctionWrapper_init, /*tp_init*/
|
||||
0, /*tp_alloc*/
|
||||
WraptBoundFunctionWrapper_new, /*tp_new*/
|
||||
0, /*tp_free*/
|
||||
0, /*tp_is_gc*/
|
||||
};
|
||||
|
||||
/* ------------------------------------------------------------------------- */
|
||||
|
||||
static PyObject *WraptBoundMethodWrapper_new(PyTypeObject *type,
|
||||
PyObject *args, PyObject *kwds)
|
||||
{
|
||||
WraptBoundMethodWrapperObject *self;
|
||||
|
||||
self = (WraptBoundMethodWrapperObject *)WraptWrapperBase_new(type,
|
||||
args, kwds);
|
||||
|
||||
if (!self)
|
||||
return NULL;
|
||||
|
||||
self->instance = NULL;
|
||||
self->params = NULL;
|
||||
|
||||
return (PyObject *)self;
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------------------- */
|
||||
|
||||
static int WraptBoundMethodWrapper_init(
|
||||
WraptBoundMethodWrapperObject *self, PyObject *args, PyObject *kwds)
|
||||
{
|
||||
PyObject *wrapped = NULL;
|
||||
PyObject *instance = NULL;
|
||||
PyObject *wrapper = NULL;
|
||||
PyObject *target = NULL;
|
||||
PyObject *params = NULL;
|
||||
|
||||
PyObject *base_args = NULL;
|
||||
PyObject *base_kwds = NULL;
|
||||
|
||||
int result = 0;
|
||||
|
||||
static char *kwlist[] = { "wrapped", "instance", "wrapper",
|
||||
"target", "params", NULL };
|
||||
|
||||
if (!PyArg_ParseTupleAndKeywords(args, kwds,
|
||||
"OOO|OO:BoundMethodWrapper", kwlist, &wrapped, &instance,
|
||||
&wrapper, &target, ¶ms)) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
Py_XDECREF(self->instance);
|
||||
Py_XDECREF(self->params);
|
||||
|
||||
self->instance = NULL;
|
||||
self->params = NULL;
|
||||
|
||||
if (!target)
|
||||
target = Py_None;
|
||||
|
||||
base_args = PyTuple_Pack(3, wrapped, wrapper, target);
|
||||
base_kwds = PyDict_New();
|
||||
|
||||
result = WraptWrapperBase_init((WraptWrapperBaseObject *)self,
|
||||
base_args, base_kwds);
|
||||
|
||||
if (result == 0) {
|
||||
Py_INCREF(instance);
|
||||
self->instance = instance;
|
||||
|
||||
if (params) {
|
||||
Py_INCREF(params);
|
||||
self->params = params;
|
||||
}
|
||||
else
|
||||
self->params = PyDict_New();
|
||||
}
|
||||
|
||||
Py_DECREF(base_args);
|
||||
Py_DECREF(base_kwds);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------------------- */
|
||||
|
||||
static void WraptBoundMethodWrapper_dealloc(
|
||||
WraptBoundMethodWrapperObject *self)
|
||||
{
|
||||
Py_XDECREF(self->instance);
|
||||
Py_XDECREF(self->params);
|
||||
|
||||
WraptWrapperBase_dealloc((WraptWrapperBaseObject *)self);
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------------------- */
|
||||
|
||||
static PyObject *WraptBoundMethodWrapper_call(
|
||||
WraptBoundMethodWrapperObject *self, PyObject *args, PyObject *kwds)
|
||||
{
|
||||
PyObject *call_args = NULL;
|
||||
PyObject *param_args = NULL;
|
||||
PyObject *param_kwds = NULL;
|
||||
|
||||
PyObject *wrapped = NULL;
|
||||
PyObject *instance = NULL;
|
||||
|
||||
PyObject *result = NULL;
|
||||
|
||||
if (self->instance == Py_None) {
|
||||
PyObject *module = NULL;
|
||||
PyObject *partial = NULL;
|
||||
PyObject *object = NULL;
|
||||
|
||||
module = PyImport_ImportModule("functools");
|
||||
|
||||
if (module) {
|
||||
PyObject *dict = NULL;
|
||||
|
||||
dict = PyModule_GetDict(module);
|
||||
partial = PyDict_GetItemString(dict, "partial");
|
||||
|
||||
Py_DECREF(module);
|
||||
}
|
||||
|
||||
if (!partial)
|
||||
return NULL;
|
||||
|
||||
instance = PyTuple_GetItem(args, 0);
|
||||
|
||||
if (!instance)
|
||||
return NULL;
|
||||
|
||||
object = PyObject_CallFunction(partial, "(OO)",
|
||||
self->wrapper_base.wrapped, instance);
|
||||
|
||||
if (object) {
|
||||
Py_INCREF(object);
|
||||
wrapped = object;
|
||||
}
|
||||
else
|
||||
return NULL;
|
||||
|
||||
param_args = PyTuple_GetSlice(args, 1, PyTuple_Size(args));
|
||||
if (!param_args)
|
||||
return NULL;
|
||||
args = param_args;
|
||||
}
|
||||
else
|
||||
instance = self->instance;
|
||||
|
||||
if (!kwds) {
|
||||
param_kwds = PyDict_New();
|
||||
kwds = param_kwds;
|
||||
}
|
||||
|
||||
if (!wrapped) {
|
||||
call_args = PyTuple_Pack(4, self->wrapper_base.wrapped, instance,
|
||||
args, kwds);
|
||||
}
|
||||
else
|
||||
call_args = PyTuple_Pack(4, wrapped, instance, args, kwds);
|
||||
|
||||
result = PyEval_CallObjectWithKeywords(self->wrapper_base.wrapper,
|
||||
call_args, self->params);
|
||||
|
||||
Py_DECREF(call_args);
|
||||
Py_XDECREF(param_args);
|
||||
Py_XDECREF(param_kwds);
|
||||
Py_XDECREF(wrapped);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------------------- */
|
||||
|
||||
static PyObject *WraptBoundMethodWrapper_get_instance(
|
||||
WraptBoundMethodWrapperObject *self, void *closure)
|
||||
{
|
||||
if (!self->instance) {
|
||||
Py_INCREF(Py_None);
|
||||
return Py_None;
|
||||
}
|
||||
|
||||
Py_INCREF(self->instance);
|
||||
return self->instance;
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------------------- */
|
||||
|
||||
static PyObject *WraptBoundMethodWrapper_get_params(
|
||||
WraptBoundMethodWrapperObject *self, void *closure)
|
||||
{
|
||||
if (!self->params) {
|
||||
Py_INCREF(Py_None);
|
||||
return Py_None;
|
||||
}
|
||||
|
||||
Py_INCREF(self->params);
|
||||
return self->params;
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------------------- */;
|
||||
|
||||
static PyGetSetDef WraptBoundMethodWrapper_getset[] = {
|
||||
{ "_self_wrapped", (getter)WraptWrapperBase_get_wrapped,
|
||||
NULL, 0 },
|
||||
{ "_self_instance", (getter)WraptBoundMethodWrapper_get_instance,
|
||||
NULL, 0 },
|
||||
{ "_self_wrapper", (getter)WraptWrapperBase_get_wrapper,
|
||||
NULL, 0 },
|
||||
{ "_self_target", (getter)WraptWrapperBase_get_target,
|
||||
NULL, 0 },
|
||||
{ "_self_params", (getter)WraptBoundMethodWrapper_get_params,
|
||||
NULL, 0 },
|
||||
{ "__class__", (getter)WraptWrapperBase_get_class,
|
||||
NULL, 0 },
|
||||
{ NULL },
|
||||
};
|
||||
|
||||
PyTypeObject WraptBoundMethodWrapper_Type = {
|
||||
PyVarObject_HEAD_INIT(NULL, 0)
|
||||
"_wrappers.BoundMethodWrapper", /*tp_name*/
|
||||
sizeof(WraptBoundMethodWrapperObject), /*tp_basicsize*/
|
||||
0, /*tp_itemsize*/
|
||||
/* methods */
|
||||
(destructor)WraptBoundMethodWrapper_dealloc, /*tp_dealloc*/
|
||||
0, /*tp_print*/
|
||||
0, /*tp_getattr*/
|
||||
0, /*tp_setattr*/
|
||||
0, /*tp_compare*/
|
||||
0, /*tp_repr*/
|
||||
0, /*tp_as_number*/
|
||||
0, /*tp_as_sequence*/
|
||||
0, /*tp_as_mapping*/
|
||||
0, /*tp_hash*/
|
||||
(ternaryfunc)WraptBoundMethodWrapper_call, /*tp_call*/
|
||||
0, /*tp_str*/
|
||||
(getattrofunc)WraptWrapperBase_getattro, /*tp_getattro*/
|
||||
(setattrofunc)WraptWrapperBase_setattro, /*tp_setattro*/
|
||||
0, /*tp_as_buffer*/
|
||||
Py_TPFLAGS_DEFAULT |
|
||||
Py_TPFLAGS_BASETYPE, /*tp_flags*/
|
||||
0, /*tp_doc*/
|
||||
0, /*tp_traverse*/
|
||||
0, /*tp_clear*/
|
||||
0, /*tp_richcompare*/
|
||||
0, /*tp_weaklistoffset*/
|
||||
(getiterfunc)WraptWrapperBase_iter, /*tp_iter*/
|
||||
0, /*tp_iternext*/
|
||||
0, /*tp_methods*/
|
||||
0, /*tp_members*/
|
||||
WraptBoundMethodWrapper_getset, /*tp_getset*/
|
||||
0, /*tp_base*/
|
||||
0, /*tp_dict*/
|
||||
0, /*tp_descr_get*/
|
||||
0, /*tp_descr_set*/
|
||||
offsetof(WraptWrapperBaseObject, dict), /*tp_dictoffset*/
|
||||
(initproc)WraptBoundMethodWrapper_init, /*tp_init*/
|
||||
0, /*tp_alloc*/
|
||||
WraptBoundMethodWrapper_new, /*tp_new*/
|
||||
0, /*tp_free*/
|
||||
0, /*tp_is_gc*/
|
||||
};
|
||||
|
||||
/* ------------------------------------------------------------------------- */;
|
||||
|
||||
#if PY_MAJOR_VERSION >= 3
|
||||
@@ -679,10 +1141,11 @@ moduleinit(void)
|
||||
return NULL;
|
||||
if (PyType_Ready(&WraptFunctionWrapper_Type) < 0)
|
||||
return NULL;
|
||||
if (PyType_Ready(&WraptBoundFunctionWrapper_Type) < 0)
|
||||
return NULL;
|
||||
if (PyType_Ready(&WraptBoundMethodWrapper_Type) < 0)
|
||||
return NULL;
|
||||
|
||||
Py_INCREF(&WraptWrapperBase_Type);
|
||||
PyModule_AddObject(module, "WrapperBase",
|
||||
(PyObject *)&WraptWrapperBase_Type);
|
||||
Py_INCREF(&WraptFunctionWrapper_Type);
|
||||
PyModule_AddObject(module, "FunctionWrapper",
|
||||
(PyObject *)&WraptFunctionWrapper_Type);
|
||||
|
||||
@@ -2,14 +2,7 @@ import functools
|
||||
|
||||
from . import six
|
||||
|
||||
try:
|
||||
from ._wrappers import WrapperBase as C_WrapperBase
|
||||
from ._wrappers import FunctionWrapper as C_FunctionWrapper
|
||||
except ImportError:
|
||||
C_WrapperBase = None
|
||||
C_FunctionWrapper = None
|
||||
|
||||
class WrapperOverrideMethods(object):
|
||||
class _WrapperOverrideMethods(object):
|
||||
|
||||
@property
|
||||
def __module__(self):
|
||||
@@ -27,10 +20,10 @@ class WrapperOverrideMethods(object):
|
||||
def __doc__(self, value):
|
||||
self._self_wrapped.__doc__ = value
|
||||
|
||||
class WrapperBaseMetaType(type):
|
||||
class _WrapperBaseMetaType(type):
|
||||
def __new__(cls, name, bases, dictionary):
|
||||
# We use properties to override the values of __module__ and
|
||||
# __doc__. If we add these in WrapperBase, the derived class
|
||||
# __doc__. If we add these in _WrapperBase, the derived class
|
||||
# __dict__ will still be setup to have string variants of these
|
||||
# attributes and the rules of descriptors means that they
|
||||
# appear to take precedence over the properties in the base
|
||||
@@ -38,10 +31,10 @@ class WrapperBaseMetaType(type):
|
||||
# class type itself via a meta class. In that way the
|
||||
# properties will always take precedence.
|
||||
|
||||
dictionary.update(vars(WrapperOverrideMethods))
|
||||
dictionary.update(vars(_WrapperOverrideMethods))
|
||||
return type.__new__(cls, name, bases, dictionary)
|
||||
|
||||
class PY_WrapperBase(six.with_metaclass(WrapperBaseMetaType)):
|
||||
class _WrapperBase(six.with_metaclass(_WrapperBaseMetaType)):
|
||||
|
||||
def __init__(self, wrapped, wrapper, target=None):
|
||||
self._self_wrapped = wrapped
|
||||
@@ -147,12 +140,10 @@ class PY_WrapperBase(six.with_metaclass(WrapperBaseMetaType)):
|
||||
def __iter__(self):
|
||||
return iter(self._self_wrapped)
|
||||
|
||||
WrapperBase = C_WrapperBase or PY_WrapperBase
|
||||
|
||||
class BoundFunctionWrapper(WrapperBase):
|
||||
class _BoundFunctionWrapper(_WrapperBase):
|
||||
|
||||
def __init__(self, wrapped, instance, wrapper, target=None, params={}):
|
||||
super(BoundFunctionWrapper, self).__init__(wrapped, wrapper, target)
|
||||
super(_BoundFunctionWrapper, self).__init__(wrapped, wrapper, target)
|
||||
self._self_instance = instance
|
||||
self._self_params = params
|
||||
|
||||
@@ -160,10 +151,10 @@ class BoundFunctionWrapper(WrapperBase):
|
||||
return self._self_wrapper(self._self_wrapped, self._self_instance,
|
||||
args, kwargs, **self._self_params)
|
||||
|
||||
class BoundMethodWrapper(WrapperBase):
|
||||
class _BoundMethodWrapper(_WrapperBase):
|
||||
|
||||
def __init__(self, wrapped, instance, wrapper, target=None, params={}):
|
||||
super(BoundMethodWrapper, self).__init__(wrapped, wrapper, target)
|
||||
super(_BoundMethodWrapper, self).__init__(wrapped, wrapper, target)
|
||||
self._self_instance = instance
|
||||
self._self_params = params
|
||||
|
||||
@@ -184,7 +175,7 @@ class BoundMethodWrapper(WrapperBase):
|
||||
return self._self_wrapper(self._self_wrapped, self._self_instance,
|
||||
args, kwargs, **self._self_params)
|
||||
|
||||
class Py_FunctionWrapper(WrapperBase):
|
||||
class FunctionWrapper(_WrapperBase):
|
||||
|
||||
def __init__(self, wrapped, wrapper, target=None, params={}):
|
||||
super(FunctionWrapper, self).__init__(wrapped, wrapper, target)
|
||||
@@ -193,7 +184,7 @@ class Py_FunctionWrapper(WrapperBase):
|
||||
# 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. Defer to the
|
||||
# BoundMethodWrapper for these specific fixups when we believe
|
||||
# _BoundMethodWrapper for these specific fixups when we believe
|
||||
# it is likely an instancemethod. That is, anytime it isn't
|
||||
# classmethod or staticmethod.
|
||||
#
|
||||
@@ -223,9 +214,9 @@ class Py_FunctionWrapper(WrapperBase):
|
||||
# later.
|
||||
|
||||
if isinstance(self._self_wrapped, (classmethod, staticmethod)):
|
||||
self._self_wrapper_type = BoundFunctionWrapper
|
||||
self._self_wrapper_type = _BoundFunctionWrapper
|
||||
else:
|
||||
self._self_wrapper_type = BoundMethodWrapper
|
||||
self._self_wrapper_type = _BoundMethodWrapper
|
||||
|
||||
def __get__(self, instance, owner):
|
||||
descriptor = self._self_wrapped.__get__(instance, owner)
|
||||
@@ -243,4 +234,9 @@ class Py_FunctionWrapper(WrapperBase):
|
||||
return self._self_wrapper(self._self_wrapped, None, args,
|
||||
kwargs, **self._self_params)
|
||||
|
||||
FunctionWrapper = C_FunctionWrapper or PY_FunctionWrapper
|
||||
try:
|
||||
from ._wrappers import FunctionWrapper as C_FunctionWrapper
|
||||
PY_FunctionWrapper = FunctionWrapper
|
||||
FunctionWrapper = C_FunctionWrapper
|
||||
except ImportError:
|
||||
pass
|
||||
|
||||
Reference in New Issue
Block a user