Proxy through query/update of annotations in C version of wrapper.

This commit is contained in:
Graham Dumpleton
2013-08-11 22:38:51 +08:00
parent 039aecad50
commit 4fa911fef5
2 changed files with 77 additions and 0 deletions

View File

@@ -301,6 +301,32 @@ static int WraptWrapperBase_set_doc(WraptWrapperBaseObject *self,
/* ------------------------------------------------------------------------- */
static PyObject *WraptWrapperBase_get_annotations(
WraptWrapperBaseObject *self)
{
if (!self->wrapped) {
PyErr_SetString(PyExc_ValueError, "wrapper has not been initialised");
return NULL;
}
return PyObject_GetAttrString(self->wrapped, "__annotations__");
}
/* ------------------------------------------------------------------------- */
static int WraptWrapperBase_set_annotations(WraptWrapperBaseObject *self,
PyObject *value)
{
if (!self->wrapped) {
PyErr_SetString(PyExc_ValueError, "wrapper has not been initialised");
return -1;
}
return PyObject_SetAttrString(self->wrapped, "__annotations__", value);
}
/* ------------------------------------------------------------------------- */
static PyObject *WraptWrapperBase_getattro(
WraptWrapperBaseObject *self, PyObject *name)
{
@@ -398,6 +424,8 @@ static PyGetSetDef WraptWrapperBase_getset[] = {
(setter)WraptWrapperBase_set_module, 0 },
{ "__doc__", (getter)WraptWrapperBase_get_doc,
(setter)WraptWrapperBase_set_doc, 0 },
{ "__annotations__", (getter)WraptWrapperBase_get_annotations,
(setter)WraptWrapperBase_set_annotations, 0 },
{ NULL },
};
@@ -640,6 +668,8 @@ static PyGetSetDef WraptFunctionWrapper_getset[] = {
(setter)WraptWrapperBase_set_module, 0 },
{ "__doc__", (getter)WraptWrapperBase_get_doc,
(setter)WraptWrapperBase_set_doc, 0 },
{ "__annotations__", (getter)WraptWrapperBase_get_annotations,
(setter)WraptWrapperBase_set_annotations, 0 },
{ NULL },
};
@@ -850,6 +880,8 @@ static PyGetSetDef WraptBoundFunctionWrapper_getset[] = {
(setter)WraptWrapperBase_set_module, 0 },
{ "__doc__", (getter)WraptWrapperBase_get_doc,
(setter)WraptWrapperBase_set_doc, 0 },
{ "__annotations__", (getter)WraptWrapperBase_get_annotations,
(setter)WraptWrapperBase_set_annotations, 0 },
{ NULL },
};
@@ -1112,6 +1144,8 @@ static PyGetSetDef WraptBoundMethodWrapper_getset[] = {
(setter)WraptWrapperBase_set_module, 0 },
{ "__doc__", (getter)WraptWrapperBase_get_doc,
(setter)WraptWrapperBase_set_doc, 0 },
{ "__annotations__", (getter)WraptWrapperBase_get_annotations,
(setter)WraptWrapperBase_set_annotations, 0 },
{ NULL },
};

View File

@@ -129,5 +129,48 @@ class TestUpdateAttributes(unittest.TestCase):
self.assertEqual(function.__doc__, 'override_doc')
self.assertEqual(instance.__doc__, 'override_doc')
def test_update_annotations(self):
@passthru_decorator
def function():
pass
if six.PY3:
self.assertEqual(function.__annotations__, {})
else:
def run(*args):
function.__annotations__
self.assertRaises(AttributeError, run, ())
override_annotations = { 'override_annotations': '' }
function.__annotations__ = override_annotations
self.assertEqual(function.__annotations__, override_annotations)
def test_update_annotations_modified_on_original(self):
def function():
pass
def wrapper(wrapped, instance, args, kwargs):
return wrapped(*args, **kwargs)
instance = wrapt.FunctionWrapper(function, wrapper)
if six.PY3:
self.assertEqual(instance.__annotations__, {})
else:
def run(*args):
instance.__annotations__
self.assertRaises(AttributeError, run, ())
override_annotations = { 'override_annotations': '' }
instance.__annotations__ = override_annotations
self.assertEqual(function.__annotations__, override_annotations)
self.assertEqual(instance.__annotations__, override_annotations)
if __name__ == '__main__':
unittest.main()