From 5577cb87b7142d1140e93c871e7bc5932a9c771b Mon Sep 17 00:00:00 2001 From: Robin Dunn Date: Wed, 6 Jun 2012 01:15:27 +0000 Subject: [PATCH] Update to a newer build of SIP to get some bug fixes git-svn-id: https://svn.wxwidgets.org/svn/wx/wxPython/Phoenix/trunk@71661 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775 --- bin/build-sip-posix | 3 +- build.py | 8 ++--- sip/siplib/qtlib.c | 14 +++----- sip/siplib/sip.h | 17 +++++++-- sip/siplib/siplib.c | 87 +++++++++++++++++++++++++++++---------------- 5 files changed, 81 insertions(+), 48 deletions(-) diff --git a/bin/build-sip-posix b/bin/build-sip-posix index e78e848f..68f2f47b 100755 --- a/bin/build-sip-posix +++ b/bin/build-sip-posix @@ -37,7 +37,8 @@ if [ "$PLATFORM" = "darwin" ]; then --sip-module wx.siplib \ $* - make -C sipgen CC=gcc-4.0 CXX=g++-4.0 LINK=g++-4.0 clean all + #make -C sipgen CC=gcc-4.0 CXX=g++-4.0 LINK=g++-4.0 clean all + make -C sipgen clean all else $PYTHON configure.py \ --sip-module wx.siplib \ diff --git a/build.py b/build.py index 1db142d6..e2cefc70 100755 --- a/build.py +++ b/build.py @@ -49,11 +49,11 @@ unstable_series = (version.VER_MINOR % 2) == 1 # is the minor version odd or ev isWindows = sys.platform.startswith('win') isDarwin = sys.platform == "darwin" -sipCurrentVersion = '4.13.2' +sipCurrentVersion = '4.13.3-snapshot-377e9e4763f5' sipCurrentVersionMD5 = { - 'darwin' : 'b9262c3ea3d2a0010f4c59c27c60e8c1', - 'win32' : 'b5885b420b7fe16e9dc5e32ef381a847', - 'linux2' : '5956f74dc9a1e0673633e7a494705dca', + 'darwin' : 'c43e77a4a63dd663be2f9d90853276ad', + 'win32' : '801c477ebe9e02e314e7e153e6ea7356', + 'linux2' : '07a1676641918106132bb64aa6517734', } wafCurrentVersion = '1.6.11' diff --git a/sip/siplib/qtlib.c b/sip/siplib/qtlib.c index b7c03d3e..4259d731 100644 --- a/sip/siplib/qtlib.c +++ b/sip/siplib/qtlib.c @@ -139,17 +139,11 @@ PyObject *sip_api_invoke_slot(const sipSlot *slot, PyObject *sigargs) PyObject *self = (sref != NULL ? sref : slot->meth.mself); /* - * If the receiver wraps a C++ object then ignore the call if it no - * longer exists. + * We used to check that any wrapped C++ object still existed and just + * returning None if it didn't. This caused inconsistent behaviour + * when the slot was a method connected to its object's destroyed() + * signal. */ - if (PyObject_TypeCheck(self, (PyTypeObject *)&sipSimpleWrapper_Type) && - sip_api_get_address((sipSimpleWrapper *)self) == NULL) - { - Py_XDECREF(sref); - - Py_INCREF(Py_None); - return Py_None; - } #if PY_MAJOR_VERSION >= 3 sfunc = PyMethod_New(slot->meth.mfunc, self); diff --git a/sip/siplib/sip.h b/sip/siplib/sip.h index 6b540e06..fadc0478 100644 --- a/sip/siplib/sip.h +++ b/sip/siplib/sip.h @@ -1,7 +1,7 @@ /* * The SIP module interface. * - * Copyright (c) 2011 Riverbank Computing Limited + * Copyright (c) 2012 Riverbank Computing Limited * * This file is part of SIP. * @@ -54,8 +54,8 @@ extern "C" { /* * Define the SIP version number. */ -#define SIP_VERSION 0x040d02 -#define SIP_VERSION_STR "4.13.2" +#define SIP_VERSION 0x040d03 +#define SIP_VERSION_STR "4.13.3-snapshot-377e9e4763f5" /* @@ -686,6 +686,7 @@ typedef struct _sipVariableDef { } sipVariableDef; +#if SIP_API_MAJOR_NR == 8 /* * The information describing a variable. This is deprecated from v8.1 of the * API and should be removed in v9.0. @@ -703,6 +704,14 @@ typedef struct _sipVariableDef_8 { /* This is set if the variable is static. */ int vd_is_static; } sipVariableDef_8; +#else +/* + * In addition, change the getter signature so that it is also passed the self + * Python object so that the getter doesn't need to reverse map it from the + * C++ pointer. + */ +#error "Remove v8 support for sipVariableDef" +#endif /* @@ -1514,6 +1523,7 @@ typedef struct _sipQtAPI { #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_ALIAS 0x0200 /* If it is an alias. */ +#define SIP_CREATED 0x0400 /* If the C/C++ object has been created. */ #define sipIsPyOwned(w) ((w)->flags & SIP_PY_OWNED) #define sipSetPyOwned(w) ((w)->flags |= SIP_PY_OWNED) @@ -1529,6 +1539,7 @@ typedef struct _sipQtAPI { #define sipPossibleProxy(w) ((w)->flags & SIP_POSSIBLE_PROXY) #define sipSetPossibleProxy(w) ((w)->flags |= SIP_POSSIBLE_PROXY) #define sipIsAlias(w) ((w)->flags & SIP_ALIAS) +#define sipWasCreated(w) ((w)->flags & SIP_CREATED) #define SIP_TYPE_TYPE_MASK 0x0007 /* The type type mask. */ diff --git a/sip/siplib/siplib.c b/sip/siplib/siplib.c index 3f3aa338..b7926b2c 100644 --- a/sip/siplib/siplib.c +++ b/sip/siplib/siplib.c @@ -1,7 +1,7 @@ /* * SIP library code. * - * Copyright (c) 2011 Riverbank Computing Limited + * Copyright (c) 2012 Riverbank Computing Limited * * This file is part of SIP. * @@ -555,7 +555,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); @@ -1058,7 +1058,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)) @@ -3373,7 +3373,7 @@ static int parsePass1(PyObject **parseErrp, sipSimpleWrapper **selfp, break; } } - else if (a < nr_pos_args) + else if (a < nr_pos_args - *selfargp) { /* * The argument has been given positionally and as @@ -3403,7 +3403,7 @@ static int parsePass1(PyObject **parseErrp, sipSimpleWrapper **selfp, } else if (sipKwdArgs != NULL && kwdlist != NULL) { - const char *name = kwdlist[argnr]; + const char *name = kwdlist[argnr - *selfargp]; if (name != NULL) { @@ -4655,7 +4655,7 @@ static int parsePass2(sipSimpleWrapper *self, int selfarg, PyObject *sipArgs, } else if (sipKwdArgs != NULL) { - const char *name = kwdlist[a]; + const char *name = kwdlist[a - selfarg]; if (name != NULL) arg = PyDict_GetItemString(sipKwdArgs, name); @@ -7549,6 +7549,10 @@ static PyObject *sip_api_is_py_method(sip_gilstate_t *gil, char *pymc, if (sipInterpreter == NULL) return NULL; +#ifdef WITH_THREAD + *gil = PyGILState_Ensure(); +#endif + /* * It's possible that the Python object has been deleted but the underlying * C++ instance is still working and trying to handle virtual functions. @@ -7557,7 +7561,7 @@ static PyObject *sip_api_is_py_method(sip_gilstate_t *gil, char *pymc, * reimplementation. */ if (sipSelf == NULL) - return NULL; + goto release_gil; /* * It's possible that the object's type's tp_mro is NULL. A possible @@ -7569,14 +7573,10 @@ static PyObject *sip_api_is_py_method(sip_gilstate_t *gil, char *pymc, mro = ((PyTypeObject *)cls)->tp_mro; if (mro == NULL) - return NULL; + goto release_gil; /* Get any reimplementation. */ -#ifdef WITH_THREAD - *gil = PyGILState_Ensure(); -#endif - #if PY_MAJOR_VERSION >= 3 mname_obj = PyUnicode_FromString(mname); #else @@ -7584,12 +7584,7 @@ static PyObject *sip_api_is_py_method(sip_gilstate_t *gil, char *pymc, #endif if (mname_obj == NULL) - { -#ifdef WITH_THREAD - PyGILState_Release(*gil); -#endif - return NULL; - } + goto release_gil; /* * We don't use PyObject_GetAttr() because that might find the generated @@ -7600,11 +7595,7 @@ static PyObject *sip_api_is_py_method(sip_gilstate_t *gil, char *pymc, if (add_all_lazy_attrs(((sipWrapperType *)Py_TYPE(sipSelf))->type) < 0) { Py_DECREF(mname_obj); - -#ifdef WITH_THREAD - PyGILState_Release(*gil); -#endif - return NULL; + goto release_gil; } if (sipSelf->dict != NULL) @@ -7684,6 +7675,12 @@ static PyObject *sip_api_is_py_method(sip_gilstate_t *gil, char *pymc, reimp = PyMethod_New(reimp, (PyObject *)sipSelf, cls); #endif } + else if (Py_TYPE(reimp)->tp_descr_get) + { + /* It is a descriptor, so assume it will do the right thing. */ + reimp = Py_TYPE(reimp)->tp_descr_get(reimp, (PyObject *)sipSelf, + cls); + } else { /* @@ -7713,6 +7710,12 @@ static PyObject *sip_api_is_py_method(sip_gilstate_t *gil, char *pymc, } return reimp; + +release_gil: +#ifdef WITH_THREAD + PyGILState_Release(*gil); +#endif + return NULL; } @@ -7811,7 +7814,7 @@ void *sip_api_get_cpp_ptr(sipSimpleWrapper *sw, const sipTypeDef *td) { void *ptr = sip_api_get_address(sw); - if (checkPointer(ptr) < 0) + if (checkPointer(ptr, sw) < 0) return NULL; if (td != NULL) @@ -7847,12 +7850,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 %S has been deleted" : + "super-class __init__() of %S was never called"), + (PyObject *)sw); return -1; } @@ -9070,8 +9075,6 @@ static int sipSimpleWrapper_init(sipSimpleWrapper *self, PyObject *args, { sipInitExtenderDef *ie = wt->iextend; - assert(parseErr != NULL); - /* * If we have not found an appropriate overload then try any * extenders. @@ -9135,7 +9138,7 @@ static int sipSimpleWrapper_init(sipSimpleWrapper *self, PyObject *args, } self->data = sipNew; - self->flags = sipFlags; + self->flags = sipFlags | SIP_CREATED; /* Set the access function. */ if (sipIsAccessFunc(self)) @@ -10326,7 +10329,11 @@ static char sip_api_string_as_ascii_char(PyObject *obj) if (parseString_AsASCIIChar(obj, &ch) < 0) { /* Use the exception set if it was an encoding error. */ +#if PY_VERSION_HEX >= 0x03030000 + if (!PyUnicode_Check(obj) || PyUnicode_GET_LENGTH(obj) != 1) +#else if (!PyUnicode_Check(obj) || PyUnicode_GET_SIZE(obj) != 1) +#endif PyErr_Format(PyExc_TypeError, #if PY_MAJOR_VERSION >= 3 "bytes or ASCII string of length 1 expected not '%s'", @@ -10362,7 +10369,11 @@ static char sip_api_string_as_latin1_char(PyObject *obj) if (parseString_AsLatin1Char(obj, &ch) < 0) { /* Use the exception set if it was an encoding error. */ +#if PY_VERSION_HEX >= 0x03030000 + if (!PyUnicode_Check(obj) || PyUnicode_GET_LENGTH(obj) != 1) +#else if (!PyUnicode_Check(obj) || PyUnicode_GET_SIZE(obj) != 1) +#endif PyErr_Format(PyExc_TypeError, #if PY_MAJOR_VERSION >= 3 "bytes or Latin-1 string of length 1 expected not '%s'", @@ -10398,7 +10409,11 @@ static char sip_api_string_as_utf8_char(PyObject *obj) if (parseString_AsUTF8Char(obj, &ch) < 0) { /* Use the exception set if it was an encoding error. */ +#if PY_VERSION_HEX >= 0x03030000 + if (!PyUnicode_Check(obj) || PyUnicode_GET_LENGTH(obj) != 1) +#else if (!PyUnicode_Check(obj) || PyUnicode_GET_SIZE(obj) != 1) +#endif PyErr_Format(PyExc_TypeError, #if PY_MAJOR_VERSION >= 3 "bytes or UTF-8 string of length 1 expected not '%s'", @@ -10752,7 +10767,11 @@ static int convertToWCharArray(PyObject *obj, wchar_t **ap, SIP_SSIZE_T *aszp) SIP_SSIZE_T ulen; wchar_t *wc; +#if PY_VERSION_HEX >= 0x03030000 + ulen = PyUnicode_GET_LENGTH(obj); +#else ulen = PyUnicode_GET_SIZE(obj); +#endif if ((wc = sip_api_malloc(ulen * sizeof (wchar_t))) == NULL) return -1; @@ -10809,7 +10828,11 @@ static int parseWChar(PyObject *obj, wchar_t *ap) */ static int convertToWChar(PyObject *obj, wchar_t *ap) { +#if PY_VERSION_HEX >= 0x03030000 + if (PyUnicode_GET_LENGTH(obj) != 1) +#else if (PyUnicode_GET_SIZE(obj) != 1) +#endif return -1; #if PY_VERSION_HEX >= 0x03020000 @@ -10867,7 +10890,11 @@ static int convertToWCharString(PyObject *obj, wchar_t **ap) SIP_SSIZE_T ulen; wchar_t *wc; +#if PY_VERSION_HEX >= 0x03030000 + ulen = PyUnicode_GET_LENGTH(obj); +#else ulen = PyUnicode_GET_SIZE(obj); +#endif if ((wc = sip_api_malloc((ulen + 1) * sizeof (wchar_t))) == NULL) return -1;