From ac6e37dd9ea81fe4f514dc2ca64ed867ca20b33b Mon Sep 17 00:00:00 2001 From: aneejit1 Date: Thu, 28 Apr 2022 21:10:55 +0000 Subject: [PATCH] Improve the "underlying C/C++ object has been deleted" message python-tqt is reporting "underlying C/C++ object has been deleted". This is rather unhelpful. A little code has been backported from the equivalent source files in sip 4.19.23 to make it a little clearer about what is going wrong (original author Riverbank Computing Limited , licensed under GPL version 2 or 3). Signed-off-by: aneejit1 (cherry picked from commit c9762bd162d2c0c33fec1dc1bce2c5a70357d6c8) --- siplib/sip.h | 2 ++ siplib/siplib.c | 16 +++++++++------- 2 files changed, 11 insertions(+), 7 deletions(-) diff --git a/siplib/sip.h b/siplib/sip.h index 48180a3..2f036bd 100644 --- a/siplib/sip.h +++ b/siplib/sip.h @@ -1432,6 +1432,7 @@ typedef struct _sipTQtAPI { #define SIP_SHARE_MAP 0x0040 /* If the map slot might be occupied. */ #define SIP_CPP_HAS_REF 0x0080 /* If C/C++ has a reference. */ #define SIP_POSSIBLE_PROXY 0x0100 /* If there might be a proxy slot. */ +#define SIP_CREATED 0x1000 /* If the C/C++ object has been created. */ #define sipIsPyOwned(w) ((w)->flags & SIP_PY_OWNED) #define sipSetPyOwned(w) ((w)->flags |= SIP_PY_OWNED) @@ -1446,6 +1447,7 @@ typedef struct _sipTQtAPI { #define sipResetCppHasRef(w) ((w)->flags &= ~SIP_CPP_HAS_REF) #define sipPossibleProxy(w) ((w)->flags & SIP_POSSIBLE_PROXY) #define sipSetPossibleProxy(w) ((w)->flags |= SIP_POSSIBLE_PROXY) +#define sipWasCreated(sw) ((sw)->flags & SIP_CREATED) #define SIP_TYPE_TYPE_MASK 0x0007 /* The type type mask. */ diff --git a/siplib/siplib.c b/siplib/siplib.c index ebbc194..2e0a5d5 100644 --- a/siplib/siplib.c +++ b/siplib/siplib.c @@ -551,7 +551,7 @@ static int getSelfFromArgs(sipTypeDef *td, PyObject *args, int argnr, sipSimpleWrapper **selfp); static PyObject *createEnumMember(sipTypeDef *td, sipEnumMemberDef *enm); static int compareTypedefName(const void *key, const void *el); -static int checkPointer(void *ptr); +static int checkPointer(void *ptr, sipSimpleWrapper *sw); static void *cast_cpp_ptr(void *ptr, PyTypeObject *src_type, const sipTypeDef *dst_type); static void finalise(void); @@ -1040,7 +1040,7 @@ static PyObject *callDtor(PyObject *self, PyObject *args) addr = getPtrTypeDef(sw, &ctd); - if (checkPointer(addr) < 0) + if (checkPointer(addr, sw) < 0) return NULL; if (PyObject_TypeCheck((PyObject *)sw, (PyTypeObject *)&sipWrapper_Type)) @@ -7418,7 +7418,7 @@ void *sip_api_get_cpp_ptr(sipSimpleWrapper *sw, const sipTypeDef *td) { void *ptr = sipGetAddress(sw); - if (checkPointer(ptr) < 0) + if (checkPointer(ptr, sw) < 0) return NULL; if (td != NULL) @@ -7454,12 +7454,14 @@ static void *cast_cpp_ptr(void *ptr, PyTypeObject *src_type, /* * Check that a pointer is non-NULL. */ -static int checkPointer(void *ptr) +static int checkPointer(void *ptr, sipSimpleWrapper *sw) { if (ptr == NULL) { - PyErr_SetString(PyExc_RuntimeError, - "underlying C/C++ object has been deleted"); + PyErr_Format(PyExc_RuntimeError, (sipWasCreated(sw) ? + "wrapped C/C++ object of type %s has been deleted" : + "super-class __init__() of type %s was never called"), + Py_TYPE(sw)->tp_name); return -1; } @@ -8701,7 +8703,7 @@ static int sipSimpleWrapper_init(sipSimpleWrapper *self, PyObject *args, } self->u.cppPtr = sipNew; - self->flags = sipFlags; + self->flags = sipFlags | SIP_CREATED; if (!sipNotInMap(self)) sipOMAddObject(&cppPyMap, self);