diff --git a/src/wrapt/_wrappers.c b/src/wrapt/_wrappers.c index 0cd0b81f..239866d0 100644 --- a/src/wrapt/_wrappers.c +++ b/src/wrapt/_wrappers.c @@ -3056,6 +3056,16 @@ static int WraptObjectProxy_set_module(WraptObjectProxyObject *self, Py_DECREF(wrapped); + if (!value) + { + if (PyDict_DelItemString(self->dict, "__module__") == -1 && + !PyErr_ExceptionMatches(PyExc_KeyError)) + return -1; + + PyErr_Clear(); + return 0; + } + return PyDict_SetItemString(self->dict, "__module__", value); } @@ -3107,6 +3117,16 @@ static int WraptObjectProxy_set_doc(WraptObjectProxyObject *self, Py_DECREF(wrapped); + if (!value) + { + if (PyDict_DelItemString(self->dict, "__doc__") == -1 && + !PyErr_ExceptionMatches(PyExc_KeyError)) + return -1; + + PyErr_Clear(); + return 0; + } + return PyDict_SetItemString(self->dict, "__doc__", value); } @@ -4329,7 +4349,7 @@ static PyObject *WraptFunctionWrapperBase_call(WraptFunctionWrapperObject *self, enabled = wrapt_acquire_field((PyObject *)self, &self->enabled); binding = wrapt_acquire_field((PyObject *)self, &self->binding); - if (enabled != Py_None) + if (enabled && enabled != Py_None) { if (PyCallable_Check(enabled)) { @@ -4843,7 +4863,7 @@ WraptBoundFunctionWrapper_call(WraptFunctionWrapperObject *self, PyObject *args, binding = wrapt_acquire_field((PyObject *)self, &self->binding); owner = wrapt_acquire_field((PyObject *)self, &self->owner); - if (enabled != Py_None) + if (enabled && enabled != Py_None) { if (PyCallable_Check(enabled)) { diff --git a/src/wrapt/wrappers.py b/src/wrapt/wrappers.py index e489a22b..832daa35 100644 --- a/src/wrapt/wrappers.py +++ b/src/wrapt/wrappers.py @@ -419,6 +419,9 @@ def __delattr__(self, name): pass delattr(self.__wrapped__, name) + elif name in ("__module__", "__doc__"): + delattr(self.__wrapped__, name) + elif hasattr(type(self), name): object.__delattr__(self, name) diff --git a/tests/core/test_type_module_attribute.py b/tests/core/test_type_module_attribute.py index fde9ee6a..0d17e571 100644 --- a/tests/core/test_type_module_attribute.py +++ b/tests/core/test_type_module_attribute.py @@ -255,6 +255,24 @@ def test_set_doc_on_object_proxy(self): wrapper.__doc__ = "override doc" self.assertEqual(target.__doc__, "override doc") + def test_delete_module_on_object_proxy(self): + target = objects.target + wrapper = wrapt.ObjectProxy(target) + wrapper.__module__ = "override_module" + + del wrapper.__module__ + + self.assertIsNone(target.__module__) + + def test_delete_doc_on_object_proxy(self): + target = objects.target + wrapper = wrapt.ObjectProxy(target) + wrapper.__doc__ = "override doc" + + del wrapper.__doc__ + + self.assertIsNone(target.__doc__) + def test_set_module_on_function_wrapper(self): def my_wrapper(wrapped, instance, args, kwargs): return wrapped(*args, **kwargs)