Skip to content

Commit

Permalink
It was not possible to update __class__ attribute via the ObjectProxy…
Browse files Browse the repository at this point in the history
… when using C implementation.
  • Loading branch information
GrahamDumpleton committed Jun 23, 2023
1 parent f562a67 commit fe909c2
Show file tree
Hide file tree
Showing 2 changed files with 32 additions and 1 deletion.
15 changes: 14 additions & 1 deletion src/wrapt/_wrappers.c
Original file line number Diff line number Diff line change
Expand Up @@ -1464,6 +1464,19 @@ static PyObject *WraptObjectProxy_get_class(

/* ------------------------------------------------------------------------- */

static int WraptObjectProxy_set_class(WraptObjectProxyObject *self,
PyObject *value)
{
if (!self->wrapped) {
PyErr_SetString(PyExc_ValueError, "wrapper has not been initialized");
return -1;
}

return PyObject_SetAttrString(self->wrapped, "__class__", value);
}

/* ------------------------------------------------------------------------- */

static PyObject *WraptObjectProxy_get_annotations(
WraptObjectProxyObject *self)
{
Expand Down Expand Up @@ -1779,7 +1792,7 @@ static PyGetSetDef WraptObjectProxy_getset[] = {
{ "__doc__", (getter)WraptObjectProxy_get_doc,
(setter)WraptObjectProxy_set_doc, 0 },
{ "__class__", (getter)WraptObjectProxy_get_class,
NULL, 0 },
(setter)WraptObjectProxy_set_class, 0 },
{ "__annotations__", (getter)WraptObjectProxy_get_annotations,
(setter)WraptObjectProxy_set_annotations, 0 },
{ "__wrapped__", (getter)WraptObjectProxy_get_wrapped,
Expand Down
18 changes: 18 additions & 0 deletions tests/test_object_proxy.py
Original file line number Diff line number Diff line change
Expand Up @@ -2417,5 +2417,23 @@ def function(_self, self, *args, **kwargs):

self.assertEqual(result, ('self', (), dict(arg1='arg1')))

class TestOverridingSpecialAttributes(unittest.TestCase):

def test_overriding_class_attribute(self):
class Object1: pass
class Object2(Object1): pass

o1 = Object1()

self.assertEqual(o1.__class__, type(o1))

o2 = Object2()

self.assertEqual(o2.__class__, type(o2))

o2.__class__ = type(o1)

self.assertEqual(o2.__class__, type(o1))

if __name__ == '__main__':
unittest.main()

0 comments on commit fe909c2

Please sign in to comment.