diff --git a/bin/build-sip-msw b/bin/build-sip-msw index 9fd8f475..99db1484 100644 --- a/bin/build-sip-msw +++ b/bin/build-sip-msw @@ -36,7 +36,7 @@ echo "The MD5:" $PYTHON mymd5.py sip-$SIPVER-win32.exe echo "" echo "If ready to upload then do these commands now:" -echo " bzip2 $MYBINDIR/sip-$SIPVER-win32.exe" +echo " bzip2 -9 $MYBINDIR/sip-$SIPVER-win32.exe" echo " scp $MYBINDIR/sip-$SIPVER-win32.exe.bz2 robind@riobu.com:/home/robind/domains/wxpython.org/htdocs/Phoenix/tools" diff --git a/bin/build-sip-posix b/bin/build-sip-posix index f9309f80..5100b1f5 100755 --- a/bin/build-sip-posix +++ b/bin/build-sip-posix @@ -52,7 +52,7 @@ echo "The MD5:" $PYTHON mymd5.py sip-$SIPVER-$PLATFORM echo "" echo "If ready to upload then do these commands now:" -echo " bzip2 $MYBINDIR/sip-$SIPVER-$PLATFORM" +echo " bzip2 -9 $MYBINDIR/sip-$SIPVER-$PLATFORM" echo " scp $MYBINDIR/sip-$SIPVER-$PLATFORM.bz2 robind@riobu.com:/home/robind/domains/wxpython.org/htdocs/Phoenix/tools" diff --git a/build.py b/build.py index e5c0e768..f14310d7 100755 --- a/build.py +++ b/build.py @@ -58,10 +58,10 @@ wxICON = 'docs/sphinx/_static/images/sphinxdocs/mondrian.png' # Some tools will be downloaded for the builds. These are the versions and # MD5s of the tool binaries currently in use. -sipCurrentVersion = '4.14.4' +sipCurrentVersion = '4.14.7' sipMD5 = { - 'darwin' : 'dd8d1128fc43586072206038bfa35a66', - 'win32' : '3edfb918fbddc19ac7a26b931addfeed', + 'darwin' : '836e78f3c2bf9f8233b32c1a3599efec', + 'win32' : '208e8472342c07c2679868602d96a42b', 'linux' : 'b9fa64b1f6f5a6407777a0dda0de5778', } @@ -72,7 +72,7 @@ doxygenCurrentVersion = '1.8.8' doxygenMD5 = { 'darwin' : '71c590e6cab47100f23919a2696cc7fd', 'win32' : 'a3dcff227458e423c132f16f57e26510', - 'linux' : '083b3d8f614b538696041c7364e0f334', + 'linux' : '382c01bae24ace03ec8ae1ba6d76351a', } # And the location where they can be downloaded from diff --git a/buildtools/config.py b/buildtools/config.py index 36c7f4ad..e4559ecf 100644 --- a/buildtools/config.py +++ b/buildtools/config.py @@ -119,9 +119,8 @@ class Configuration(object): self.SIPOPTS = ' '.join(['-w', # enable warnings '-o', # turn on auto-docstrings - #'-e', # turn on exceptions support - '-T', # turn off writing the timestamp to the generated files - '-g', # always release and reaquire the GIL + #'-e', # turn on exceptions support + '-T', # turn off writing the timestamp to the generated files '-g', # always release and reaquire the GIL #'-r', # turn on function call tracing '-I', os.path.join(phoenixDir(), 'src'), '-I', os.path.join(phoenixDir(), 'sip', 'gen'), diff --git a/sip/siplib/bool.cpp b/sip/siplib/bool.cpp index d2849973..5c48aa32 100644 --- a/sip/siplib/bool.cpp +++ b/sip/siplib/bool.cpp @@ -18,5 +18,5 @@ // Set a C++ bool for the main C implementation of the module. extern "C" void sipSetBool(void *ptr, int val) { - *reinterpret_cast(ptr) = val; + *reinterpret_cast(ptr) = val; } diff --git a/sip/siplib/qtlib.c b/sip/siplib/qtlib.c index 3b637fa4..384cf3d7 100644 --- a/sip/siplib/qtlib.c +++ b/sip/siplib/qtlib.c @@ -72,7 +72,11 @@ static void *newSignal(void *txrx, const char **sig) static void *createUniversalSlot(sipWrapper *txSelf, const char *sig, PyObject *rxObj, const char *slot, const char **member, int flags) { - void *us = sipQtSupport->qt_create_universal_slot(txSelf, sig, rxObj, slot, + void *us; + + assert(sipQtSupport->qt_create_universal_slot); + + us = sipQtSupport->qt_create_universal_slot(txSelf, sig, rxObj, slot, member, flags); if (us && txSelf) @@ -89,6 +93,8 @@ PyObject *sip_api_invoke_slot(const sipSlot *slot, PyObject *sigargs) { PyObject *sa, *oxtype, *oxvalue, *oxtb, *sfunc, *sref; + assert(sipQtSupport); + /* Keep some compilers quiet. */ oxtype = oxvalue = oxtb = NULL; @@ -301,6 +307,9 @@ PyObject *sip_api_invoke_slot(const sipSlot *slot, PyObject *sigargs) */ int sip_api_same_slot(const sipSlot *sp, PyObject *rxObj, const char *slot) { + assert(sipQtSupport); + assert(sipQtSupport->qt_same_name); + /* See if they are signals or Qt slots, ie. they have a name. */ if (slot != NULL) { @@ -345,6 +354,9 @@ int sip_api_same_slot(const sipSlot *sp, PyObject *rxObj, const char *slot) void *sipGetRx(sipSimpleWrapper *txSelf, const char *sigargs, PyObject *rxObj, const char *slot, const char **memberp) { + assert(sipQtSupport); + assert(sipQtSupport->qt_find_slot); + if (slot != NULL) if (isQtSlot(slot) || isQtSignal(slot)) { @@ -377,6 +389,8 @@ void *sipGetRx(sipSimpleWrapper *txSelf, const char *sigargs, PyObject *rxObj, void *sip_api_convert_rx(sipWrapper *txSelf, const char *sigargs, PyObject *rxObj, const char *slot, const char **memberp, int flags) { + assert(sipQtSupport); + if (slot == NULL) return createUniversalSlot(txSelf, sigargs, rxObj, NULL, memberp, flags); @@ -407,6 +421,9 @@ void *sip_api_convert_rx(sipWrapper *txSelf, const char *sigargs, PyObject *sip_api_connect_rx(PyObject *txObj, const char *sig, PyObject *rxObj, const char *slot, int type) { + assert(sipQtSupport); + assert(sipQtSupport->qt_connect); + /* Handle Qt signals. */ if (isQtSignal(sig)) { @@ -447,6 +464,10 @@ PyObject *sip_api_connect_rx(PyObject *txObj, const char *sig, PyObject *rxObj, PyObject *sip_api_disconnect_rx(PyObject *txObj,const char *sig, PyObject *rxObj,const char *slot) { + assert(sipQtSupport); + assert(sipQtSupport->qt_disconnect); + assert(sipQtSupport->qt_destroy_universal_slot); + /* Handle Qt signals. */ if (isQtSignal(sig)) { @@ -494,6 +515,8 @@ PyObject *sip_api_disconnect_rx(PyObject *txObj,const char *sig, */ void sip_api_free_sipslot(sipSlot *slot) { + assert(sipQtSupport); + if (slot->name != NULL) { sip_api_free(slot->name); @@ -529,6 +552,8 @@ static char *sipStrdup(const char *s) */ int sip_api_save_slot(sipSlot *sp, PyObject *rxObj, const char *slot) { + assert(sipQtSupport); + sp -> weakSlot = NULL; if (slot == NULL) diff --git a/sip/siplib/sip.h b/sip/siplib/sip.h index b9cec556..b2bbbafa 100644 --- a/sip/siplib/sip.h +++ b/sip/siplib/sip.h @@ -54,8 +54,8 @@ extern "C" { /* * Define the SIP version number. */ -#define SIP_VERSION 0x040e04 -#define SIP_VERSION_STR "4.14.4" +#define SIP_VERSION 0x040e07 +#define SIP_VERSION_STR "4.14.7" /* @@ -68,6 +68,11 @@ extern "C" { * * History: * + * 10.0 Added sip_api_set_destroy_on_exit(). + * Added sip_api_enable_autoconversion(). + * Removed sip_api_call_error_handler_old(). + * Removed sip_api_start_thread(). + * * 9.2 Added sip_gilstate_t and SIP_RELEASE_GIL to the public API. * Renamed sip_api_call_error_handler() to * sip_api_call_error_handler_old(). @@ -190,8 +195,8 @@ extern "C" { * * 0.0 Original version. */ -#define SIP_API_MAJOR_NR 9 -#define SIP_API_MINOR_NR 2 +#define SIP_API_MAJOR_NR 10 +#define SIP_API_MINOR_NR 0 /* The name of the sip module. */ @@ -350,7 +355,6 @@ typedef int (*sipConvertToFunc)(PyObject *, void **, int *, PyObject *); typedef PyObject *(*sipConvertFromFunc)(void *, PyObject *); typedef void (*sipVirtErrorHandlerFunc)(struct _sipSimpleWrapper *, sip_gilstate_t); -typedef void (*sipVirtErrorHandlerFuncOld)(struct _sipSimpleWrapper *); typedef int (*sipVirtHandlerFunc)(sip_gilstate_t, sipVirtErrorHandlerFunc, struct _sipSimpleWrapper *, PyObject *, ...); typedef void (*sipAssignFunc)(void *, SIP_SSIZE_T, const void *); @@ -858,6 +862,9 @@ typedef struct _sipClassTypeDef { /* The optional convert to function. */ sipConvertToFunc ctd_cto; + /* The optional convert from function. */ + sipConvertFromFunc ctd_cfrom; + /* The next namespace extender. */ struct _sipClassTypeDef *ctd_nsextender; @@ -1380,6 +1387,8 @@ typedef struct _sipAPIDef { int (*api_is_api_enabled)(const char *name, int from, int to); sipErrorState (*api_bad_callable_arg)(int arg_nr, PyObject *arg); void *(*api_get_address)(struct _sipSimpleWrapper *w); + void (*api_set_destroy_on_exit)(int); + int (*api_enable_autoconversion)(const sipTypeDef *td, int enable); /* * The following are deprecated parts of the public API. @@ -1426,7 +1435,6 @@ typedef struct _sipAPIDef { PyObject *(*api_is_py_method)(sip_gilstate_t *gil, char *pymc, sipSimpleWrapper *sipSelf, const char *cname, const char *mname); void (*api_call_hook)(const char *hookname); - void (*api_start_thread)(void); void (*api_end_thread)(void); void (*api_raise_unknown_exception)(void); void (*api_raise_type_exception)(const sipTypeDef *td, void *ptr); @@ -1461,8 +1469,6 @@ typedef struct _sipAPIDef { int (*api_parse_result_ex)(sip_gilstate_t, sipVirtErrorHandlerFunc, sipSimpleWrapper *, PyObject *method, PyObject *res, const char *fmt, ...); - void (*api_call_error_handler_old)(sipVirtErrorHandlerFuncOld, - sipSimpleWrapper *); void (*api_call_error_handler)(sipVirtErrorHandlerFunc, sipSimpleWrapper *, sip_gilstate_t); } sipAPIDef; diff --git a/sip/siplib/sipint.h b/sip/siplib/sipint.h index 05bcf229..05cd9dd5 100644 --- a/sip/siplib/sipint.h +++ b/sip/siplib/sipint.h @@ -111,7 +111,6 @@ void *sip_api_get_cpp_ptr(sipSimpleWrapper *w, const sipTypeDef *td); PyObject *sip_api_convert_from_type(void *cppPtr, const sipTypeDef *td, PyObject *transferObj); void sip_api_common_dtor(sipSimpleWrapper *sipSelf); -void sip_api_start_thread(void); void sip_api_end_thread(void); void sip_api_free_sipslot(sipSlot *slot); int sip_api_same_slot(const sipSlot *sp, PyObject *rxObj, const char *slot); diff --git a/sip/siplib/siplib.c b/sip/siplib/siplib.c index 2cd1b75b..164ef478 100644 --- a/sip/siplib/siplib.c +++ b/sip/siplib/siplib.c @@ -186,8 +186,6 @@ static int sip_api_parse_result(int *isErr, PyObject *method, PyObject *res, const char *fmt, ...); static void sip_api_call_error_handler(sipVirtErrorHandlerFunc error_handler, sipSimpleWrapper *py_self, sip_gilstate_t gil_state); -static void sip_api_call_error_handler_old( - sipVirtErrorHandlerFuncOld error_handler, sipSimpleWrapper *py_self); static void sip_api_trace(unsigned mask,const char *fmt,...); static void sip_api_transfer_back(PyObject *self); static void sip_api_transfer_to(PyObject *self, PyObject *owner); @@ -258,6 +256,8 @@ static void sip_api_clear_any_slot_reference(sipSlot *slot); static int sip_api_visit_slot(sipSlot *slot, visitproc visit, void *arg); static void sip_api_keep_reference(PyObject *self, int key, PyObject *obj); static void sip_api_add_exception(sipErrorState es, PyObject **parseErrp); +static void sip_api_set_destroy_on_exit(int value); +static int sip_api_enable_autoconversion(const sipTypeDef *td, int enable); /* @@ -315,6 +315,8 @@ static const sipAPIDef sip_api = { sip_api_is_api_enabled, sip_api_bad_callable_arg, sip_api_get_address, + sip_api_set_destroy_on_exit, + sip_api_enable_autoconversion, /* * The following are deprecated parts of the public API. */ @@ -349,7 +351,6 @@ static const sipAPIDef sip_api = { sip_api_get_complex_cpp_ptr, sip_api_is_py_method, sip_api_call_hook, - sip_api_start_thread, sip_api_end_thread, sip_api_raise_unknown_exception, sip_api_raise_type_exception, @@ -372,8 +373,7 @@ static const sipAPIDef sip_api = { sip_api_parse_kwd_args, sip_api_add_exception, sip_api_parse_result_ex, - sip_api_call_error_handler_old, - sip_api_call_error_handler + sip_api_call_error_handler, }; @@ -529,6 +529,7 @@ static PyObject *enum_unpickler; /* The enum unpickler function. */ static sipSymbol *sipSymbolList = NULL; /* The list of published symbols. */ static sipAttrGetter *sipAttrGetters = NULL; /* The list of attribute getters. */ static sipPyObject *sipRegisteredPyTypes = NULL; /* Registered Python types. */ +static sipPyObject *sipDisabledAutoconversions = NULL; /* Python types whose auto-conversion is disabled. */ static PyInterpreterState *sipInterpreter = NULL; /* The interpreter. */ static int destroy_on_exit = TRUE; /* Destroy owned objects on exit. */ @@ -615,6 +616,7 @@ static int addLicense(PyObject *dict, sipLicenseDef *lc); static PyObject *cast(PyObject *self, PyObject *args); static PyObject *callDtor(PyObject *self, PyObject *args); static PyObject *dumpWrapper(PyObject *self, PyObject *args); +static PyObject *enableAutoconversion(PyObject *self, PyObject *args); static PyObject *isDeleted(PyObject *self, PyObject *args); static PyObject *isPyCreated(PyObject *self, PyObject *args); static PyObject *isPyOwned(PyObject *self, PyObject *args); @@ -675,6 +677,9 @@ static PyObject *create_property(sipVariableDef *vd); static PyObject *create_function(PyMethodDef *ml); static PyObject *sip_exit(PyObject *obj, PyObject *ignore); static void register_exit_notifier(void); +static sipConvertFromFunc get_from_convertor(sipTypeDef *td); +static sipPyObject **autoconversion_disabled(const sipTypeDef *td); +static void fix_slots(PyTypeObject *py_type, sipPySlotDef *psd); /* @@ -704,6 +709,7 @@ PyMODINIT_FUNC SIP_MODULE_ENTRY(void) {"cast", cast, METH_VARARGS, NULL}, {"delete", callDtor, METH_VARARGS, NULL}, {"dump", dumpWrapper, METH_VARARGS, NULL}, + {"enableautoconversion", enableAutoconversion, METH_VARARGS, NULL}, {"getapi", sipGetAPI, METH_VARARGS, NULL}, {"isdeleted", isDeleted, METH_VARARGS, NULL}, {"ispycreated", isPyCreated, METH_VARARGS, NULL}, @@ -742,7 +748,7 @@ PyMODINIT_FUNC SIP_MODULE_ENTRY(void) * Remind ourselves to add support for capsule variables when we have * another reason to move to the next major version number. */ -#if SIP_API_MAJOR_NR > 9 +#if SIP_API_MAJOR_NR > 10 #error "Add support for capsule variables" #endif @@ -1229,7 +1235,7 @@ static PyObject *wrapInstance(PyObject *self, PyObject *args) /* - * Set the destroy on exit flag. + * Set the destroy on exit flag from Python code. */ static PyObject *setDestroyOnExit(PyObject *self, PyObject *args) { @@ -1243,6 +1249,15 @@ static PyObject *setDestroyOnExit(PyObject *self, PyObject *args) } +/* + * Set the destroy on exit flag from C++ code. + */ +static void sip_api_set_destroy_on_exit(int value) +{ + destroy_on_exit = value; +} + + /* * Register a client module. A negative value is returned and an exception * raised if there was an error. @@ -2273,33 +2288,6 @@ static void sip_api_call_error_handler(sipVirtErrorHandlerFunc error_handler, } -/* - * Call a virtual error handler. This is called without the GIL. This is - * deprecated. - */ -#if SIP_API_MAJOR_NR != 9 -#error Remove deprecated error handler support. -#endif -static void sip_api_call_error_handler_old( - sipVirtErrorHandlerFuncOld error_handler, sipSimpleWrapper *py_self) -{ - if (error_handler != NULL) - { - error_handler(py_self); - } - else - { - SIP_BLOCK_THREADS - /* - * The current thread may not be the one that raised the exception and - * so may not print anything. This is why this function is deprecated. - */ - PyErr_Print(); - SIP_UNBLOCK_THREADS - } -} - - /* * Do the main work of parsing a result object based on a format string. */ @@ -5285,6 +5273,7 @@ static int parsePass2(sipSimpleWrapper *self, int selfarg, PyObject *sipArgs, case 'T': case 'k': case 'K': + case 'U': va_arg(va, void *); /* Drop through. */ @@ -5852,6 +5841,9 @@ static int createClassType(sipExportedModuleDef *client, sipClassTypeDef *ctd, if ((py_type = createContainerType(&ctd->ctd_container, (sipTypeDef *)ctd, bases, metatype, mod_dict, type_dict, client)) == NULL) goto reldict; + if (ctd->ctd_pyslots != NULL) + fix_slots((PyTypeObject *)py_type, ctd->ctd_pyslots); + /* Handle the pickle function. */ if (ctd->ctd_pickle != NULL) { @@ -6232,6 +6224,9 @@ static int createEnumType(sipExportedModuleDef *client, sipEnumTypeDef *etd, goto relname; } + if (etd->etd_pyslots != NULL) + fix_slots((PyTypeObject *)py_type, etd->etd_pyslots); + /* We can now release our remaining references. */ Py_DECREF(name); @@ -7788,19 +7783,18 @@ static int addSingleTypeInstance(PyObject *dict, const char *name, int rc; PyObject *obj; - if (sipTypeIsClass(td)) - { - obj = sipWrapSimpleInstance(cppPtr, td, NULL, initflags); - } - else if (sipTypeIsEnum(td)) + if (sipTypeIsEnum(td)) { obj = sip_api_convert_from_enum(*(int *)cppPtr, td); } else { - assert(sipTypeIsMapped(td)); + sipConvertFromFunc cfrom = get_from_convertor(td); - obj = ((const sipMappedTypeDef *)td)->mtd_cfrom(cppPtr, NULL); + if (cfrom != NULL) + obj = cfrom(cppPtr, NULL); + else + obj = sipWrapSimpleInstance(cppPtr, td, NULL, initflags); } if (obj == NULL) @@ -8403,6 +8397,7 @@ PyObject *sip_api_convert_from_type(void *cpp, const sipTypeDef *td, PyObject *transferObj) { PyObject *py; + sipConvertFromFunc cfrom; assert(sipTypeIsClass(td) || sipTypeIsMapped(td)); @@ -8413,8 +8408,10 @@ PyObject *sip_api_convert_from_type(void *cpp, const sipTypeDef *td, return Py_None; } - if (sipTypeIsMapped(td)) - return ((const sipMappedTypeDef *)td)->mtd_cfrom(cpp, transferObj); + cfrom = get_from_convertor(td); + + if (cfrom != NULL) + return cfrom(cpp, transferObj); /* Apply any sub-class convertor. */ if (sipTypeHasSCC(td)) @@ -8446,6 +8443,7 @@ static PyObject *sip_api_convert_from_new_type(void *cpp, const sipTypeDef *td, PyObject *transferObj) { sipWrapper *owner; + sipConvertFromFunc cfrom; /* Handle None. */ if (cpp == NULL) @@ -8454,17 +8452,18 @@ static PyObject *sip_api_convert_from_new_type(void *cpp, const sipTypeDef *td, return Py_None; } - if (sipTypeIsMapped(td)) + cfrom = get_from_convertor(td); + + if (cfrom != NULL) { - PyObject *res = ((const sipMappedTypeDef *)td)->mtd_cfrom(cpp, - transferObj); + PyObject *res = cfrom(cpp, transferObj); if (res != NULL) { /* * We no longer need the C/C++ instance so we release it (unless * its ownership is transferred). This means this call is - * semantically equivalent to the case where the type is a wrapped + * semantically equivalent to the case where we are wrapping a * class. */ if (transferObj == NULL || transferObj == Py_None) @@ -8474,8 +8473,6 @@ static PyObject *sip_api_convert_from_new_type(void *cpp, const sipTypeDef *td, return res; } - assert(sipTypeIsClass(td)); - /* Apply any sub-class convertor. */ if (sipTypeHasSCC(td)) td = convertSubClass(td, &cpp); @@ -9949,6 +9946,8 @@ static int sipWrapper_clear(sipWrapper *self) sipSlot *slot; void *context = NULL; + assert (sipQtSupport->qt_find_sipslot); + while ((slot = sipQtSupport->qt_find_sipslot(tx, &context)) != NULL) { sip_api_clear_any_slot_reference(slot); @@ -9998,7 +9997,7 @@ static int sipWrapper_traverse(sipWrapper *self, visitproc visit, void *arg) return vret; /* This should be handwritten code in PyQt. */ - if (sipQtSupport != NULL) + if (sipQtSupport != NULL && sipQtSupport->qt_find_sipslot) { void *tx = sip_api_get_address(sw); @@ -11360,3 +11359,130 @@ static void register_exit_notifier(void) Py_DECREF(atexit_module); Py_DECREF(notifier); } + + +/* + * Return the function that converts a C++ instance to a Python object. + */ +static sipConvertFromFunc get_from_convertor(sipTypeDef *td) +{ + if (sipTypeIsMapped(td)) + return ((const sipMappedTypeDef *)td)->mtd_cfrom; + + assert(sipTypeIsClass(td)); + + if (autoconversion_disabled(td) != NULL) + return NULL; + + return ((const sipClassTypeDef *)td)->ctd_cfrom; +} + + +/* + * Enable or disable the auto-conversion. Returns the previous enabled state + * or -1 on error. + */ +static int sip_api_enable_autoconversion(const sipTypeDef *td, int enable) +{ + sipPyObject **pop; + + assert(sipTypeIsClass(td)); + + pop = autoconversion_disabled(td); + + /* See if there is anything to do. */ + if (pop == NULL && enable) + return TRUE; + + if (pop != NULL && !enable) + return FALSE; + + if (pop != NULL) + { + /* Remove it from the list. */ + sipPyObject *po = *pop; + + *pop = po->next; + sip_api_free(po); + } + else + { + /* Add it to the list. */ + if (addPyObjectToList(&sipDisabledAutoconversions, (PyObject *)sipTypeAsPyTypeObject(td)) < 0) + return -1; + } + + return !enable; +} + + +/* + * Return a pointer to the entry in the list of disabled auto-conversions for a + * type. + */ +static sipPyObject **autoconversion_disabled(const sipTypeDef *td) +{ + PyObject *type = (PyObject *)sipTypeAsPyTypeObject(td); + sipPyObject **pop; + + for (pop = &sipDisabledAutoconversions; *pop != NULL; pop = &(*pop)->next) + if ((*pop)->object == type) + return pop; + + return NULL; +} + + +/* + * Enable or disable auto-conversion of a class that supports it. + */ +static PyObject *enableAutoconversion(PyObject *self, PyObject *args) +{ + sipWrapperType *wt; + int enable; + + if (PyArg_ParseTuple(args, "O!i:enableautoconversion", &sipWrapperType_Type, &wt, &enable)) + { + sipTypeDef *td = wt->type; + int was_enabled; + PyObject *res; + + if (!sipTypeIsClass(td) || ((sipClassTypeDef *)td)->ctd_cfrom == NULL) + { + PyErr_Format(PyExc_TypeError, + "%s is not a wrapped class that supports optional auto-conversion", ((PyTypeObject *)wt)->tp_name); + + return NULL; + } + + if ((was_enabled = sip_api_enable_autoconversion(td, enable)) < 0) + return NULL; + + res = (was_enabled ? Py_True : Py_False); + + Py_INCREF(res); + return res; + } + + return NULL; +} + + +/* + * Python copies the nb_inplace_add slot to the sq_inplace_concat slot and vice + * versa if either are missing. This is a bug because they don't have the same + * API. We therefore reverse this. + */ +static void fix_slots(PyTypeObject *py_type, sipPySlotDef *psd) +{ + while (psd->psd_func != NULL) + { + if (psd->psd_type == iadd_slot && py_type->tp_as_sequence != NULL) + py_type->tp_as_sequence->sq_inplace_concat = NULL; + + if (psd->psd_type == iconcat_slot && py_type->tp_as_number != NULL) + py_type->tp_as_number->nb_inplace_add = NULL; + + ++psd; + } +} diff --git a/sip/siplib/threads.c b/sip/siplib/threads.c index 992e3fc3..bc22907d 100644 --- a/sip/siplib/threads.c +++ b/sip/siplib/threads.c @@ -132,22 +132,6 @@ PyObject *sipWrapSimpleInstance(void *cppPtr, const sipTypeDef *td, } -/* - * This is called from a newly created thread to initialise some thread local - * storage. - */ -#if SIP_API_MAJOR_NR != 9 -#error Remove deprecated sip_api_start_thread(). -#endif -void sip_api_start_thread(void) -{ - /* - * The thread local storage allocation now happens when it is needed, so - * this is now redundant. - */ -} - - /* * Handle the termination of a thread. */