diff --git a/sip/siplib/array.c b/sip/siplib/array.c index c157d938..dede8372 100644 --- a/sip/siplib/array.c +++ b/sip/siplib/array.c @@ -1,7 +1,7 @@ /* * This file implements the API for the array type. * - * Copyright (c) 2018 Riverbank Computing Limited + * Copyright (c) 2019 Riverbank Computing Limited * * This file is part of SIP. * @@ -526,6 +526,9 @@ PyTypeObject sipArray_Type = { #if PY_VERSION_HEX >= 0x03040000 0, /* tp_finalize */ #endif +#if PY_VERSION_HEX >= 0x03080000 + 0, /* tp_vectorcall */ +#endif }; diff --git a/sip/siplib/descriptors.c b/sip/siplib/descriptors.c index 17f701ad..e6008167 100644 --- a/sip/siplib/descriptors.c +++ b/sip/siplib/descriptors.c @@ -1,7 +1,7 @@ /* * The implementation of the different descriptors. * - * Copyright (c) 2016 Riverbank Computing Limited + * Copyright (c) 2019 Riverbank Computing Limited * * This file is part of SIP. * @@ -108,6 +108,9 @@ PyTypeObject sipMethodDescr_Type = { #if PY_VERSION_HEX >= 0x03040000 0, /* tp_finalize */ #endif +#if PY_VERSION_HEX >= 0x03080000 + 0, /* tp_vectorcall */ +#endif }; @@ -317,6 +320,9 @@ PyTypeObject sipVariableDescr_Type = { #if PY_VERSION_HEX >= 0x03040000 0, /* tp_finalize */ #endif +#if PY_VERSION_HEX >= 0x03080000 + 0, /* tp_vectorcall */ +#endif }; diff --git a/sip/siplib/sip.h b/sip/siplib/sip.h index 09d2ab67..bcb53ab2 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 0x041310 -#define SIP_VERSION_STR "4.19.16" +#define SIP_VERSION 0x041313 +#define SIP_VERSION_STR "4.19.19" /* @@ -68,6 +68,10 @@ extern "C" { * * History: * + * 12.7 Added sip_api_visit_wrappers() to the public API. + * Added sip_api_register_exit_notifier() to the public API. + * sip_api_is_owned_by_python() is now part of the public API. + * * 12.6 Added sip_api_long_as_size_t() to the public API. * Added the '=' format character to sip_api_build_result(). * Added the '=' format character to sip_api_parse_result_ex(). @@ -272,7 +276,7 @@ extern "C" { * 0.0 Original version. */ #define SIP_API_MAJOR_NR 12 -#define SIP_API_MINOR_NR 6 +#define SIP_API_MINOR_NR 7 /* @@ -537,6 +541,7 @@ typedef PyObject *(*sipVariableGetterFunc)(void *, PyObject *, PyObject *); typedef int (*sipVariableSetterFunc)(void *, PyObject *, PyObject *); typedef void *(*sipProxyResolverFunc)(void *); typedef int (*sipNewUserTypeFunc)(sipWrapperType *); +typedef void (*sipWrapperVisitorFunc)(sipSimpleWrapper *, void *); #if !defined(Py_LIMITED_API) || PY_VERSION_HEX < 0x03020000 @@ -1871,7 +1876,15 @@ typedef struct _sipAPIDef { int (*api_init_mixin)(PyObject *self, PyObject *args, PyObject *kwds, const sipClassTypeDef *ctd); PyObject *(*api_get_reference)(PyObject *self, int key); + + /* + * The following are part of the public API. + */ int (*api_is_owned_by_python)(sipSimpleWrapper *); + + /* + * The following are not part of the public API. + */ int (*api_is_derived_class)(sipSimpleWrapper *); /* @@ -1939,6 +1952,8 @@ typedef struct _sipAPIDef { SIP_SSIZE_T *start, SIP_SSIZE_T *stop, SIP_SSIZE_T *step, SIP_SSIZE_T *slicelength); size_t (*api_long_as_size_t)(PyObject *o); + void (*api_visit_wrappers)(sipWrapperVisitorFunc visitor, void *closure); + int (*api_register_exit_notifier)(PyMethodDef *md); } sipAPIDef; diff --git a/sip/siplib/siplib.c b/sip/siplib/siplib.c index db60870c..e2c90784 100644 --- a/sip/siplib/siplib.c +++ b/sip/siplib/siplib.c @@ -1,7 +1,7 @@ /* * SIP library code. * - * Copyright (c) 2018 Riverbank Computing Limited + * Copyright (c) 2019 Riverbank Computing Limited * * This file is part of SIP. * @@ -121,6 +121,9 @@ static PyTypeObject sipWrapperType_Type = { #if PY_VERSION_HEX >= 0x03040000 0, /* tp_finalize */ #endif +#if PY_VERSION_HEX >= 0x03080000 + 0, /* tp_vectorcall */ +#endif }; @@ -189,6 +192,9 @@ static sipWrapperType sipWrapper_Type = { #endif #if PY_VERSION_HEX >= 0x03040000 0, /* tp_finalize */ +#endif +#if PY_VERSION_HEX >= 0x03080000 + 0, /* tp_vectorcall */ #endif }, #if PY_VERSION_HEX >= 0x03050000 @@ -457,6 +463,9 @@ static void sip_api_print_object(PyObject *o); static int sip_api_register_event_handler(sipEventType type, const sipTypeDef *td, void *handler); static void sip_api_instance_destroyed_ex(sipSimpleWrapper **sipSelfp); +static void sip_api_visit_wrappers(sipWrapperVisitorFunc visitor, + void *closure); +static int sip_api_register_exit_notifier(PyMethodDef *md); /* @@ -648,6 +657,8 @@ static const sipAPIDef sip_api = { */ sip_api_convert_from_slice_object, sip_api_long_as_size_t, + sip_api_visit_wrappers, + sip_api_register_exit_notifier, }; @@ -811,6 +822,9 @@ static PyTypeObject sipEnumType_Type = { #if PY_VERSION_HEX >= 0x03040000 0, /* tp_finalize */ #endif +#if PY_VERSION_HEX >= 0x03080000 + 0, /* tp_vectorcall */ +#endif }; @@ -1000,7 +1014,6 @@ static int addMethod(PyObject *dict, PyMethodDef *pmd); static PyObject *create_property(sipVariableDef *vd); static PyObject *create_function(PyMethodDef *ml); static PyObject *sip_exit(PyObject *self, PyObject *args); -static void register_exit_notifier(void); static sipConvertFromFunc get_from_convertor(const sipTypeDef *td); static sipPyObject **autoconversion_disabled(const sipTypeDef *td); static void fix_slots(PyTypeObject *py_type, sipPySlotDef *psd); @@ -1100,6 +1113,10 @@ PyMODINIT_FUNC SIP_MODULE_ENTRY(void) }; #endif + static PyMethodDef sip_exit_md = { + "_sip_exit", sip_exit, METH_NOARGS, NULL + }; + int rc; PyObject *mod, *mod_dict, *obj; @@ -1262,7 +1279,7 @@ PyMODINIT_FUNC SIP_MODULE_ENTRY(void) } /* Make sure we are notified when starting to exit. */ - register_exit_notifier(); + sip_api_register_exit_notifier(&sip_exit_md); /* * Also install the package-specific module at the top level for backwards @@ -2007,9 +2024,13 @@ static int sip_api_init_module(sipExportedModuleDef *client, /* Create the module's enum members. */ for (emd = client->em_enummembers, i = 0; i < client->em_nrenummembers; ++i, ++emd) { + sipTypeDef *etd = client->em_types[emd->em_enum]; PyObject *mo; - if ((mo = sip_api_convert_from_enum(emd->em_val, client->em_types[emd->em_enum])) == NULL) + if (sipTypeIsScopedEnum(etd)) + continue; + + if ((mo = sip_api_convert_from_enum(emd->em_val, etd)) == NULL) return -1; if (PyDict_SetItemString(mod_dict, emd->em_name, mo) < 0) @@ -6101,14 +6122,21 @@ void sip_api_instance_destroyed(sipSimpleWrapper *sw) */ static void sip_api_instance_destroyed_ex(sipSimpleWrapper **sipSelfp) { + /* If there is no interpreter just to the minimum and get out. */ + if (sipInterpreter == NULL) + { + *sipSelfp = NULL; + return; + } + + SIP_BLOCK_THREADS + sipSimpleWrapper *sipSelf = *sipSelfp; - if (sipSelf != NULL && sipInterpreter != NULL) + if (sipSelf != NULL) { PyObject *xtype, *xvalue, *xtb; - SIP_BLOCK_THREADS - /* We may be tidying up after an exception so preserve it. */ PyErr_Fetch(&xtype, &xvalue, &xtb); callPyDtor(sipSelf); @@ -6137,16 +6165,16 @@ static void sip_api_instance_destroyed_ex(sipSimpleWrapper **sipSelfp) removeFromParent((sipWrapper *)sipSelf); } - SIP_UNBLOCK_THREADS + /* + * Normally this is done in the generated dealloc function. However + * this is only called if the pointer/access function has not been + * reset (which it has). It acts as a guard to prevent any further + * invocations of reimplemented virtuals. + */ + *sipSelfp = NULL; } - /* - * Normally this is done in the generated dealloc function. However this - * is only called if the pointer/access function has not been reset (which - * it has). It acts as a guard to prevent any further invocations of - * reimplemented virtuals. - */ - *sipSelfp = NULL; + SIP_UNBLOCK_THREADS } @@ -11537,6 +11565,9 @@ sipWrapperType sipSimpleWrapper_Type = { 0, /* tp_version_tag */ #if PY_VERSION_HEX >= 0x03040000 0, /* tp_finalize */ +#endif +#if PY_VERSION_HEX >= 0x03080000 + 0, /* tp_vectorcall */ #endif }, #if PY_VERSION_HEX >= 0x03050000 @@ -13241,30 +13272,29 @@ static PyObject *sip_exit(PyObject *self, PyObject *args) /* - * Register the exit notifier with the atexit module. + * Register an exit notifier with the atexit module. */ -static void register_exit_notifier(void) +static int sip_api_register_exit_notifier(PyMethodDef *md) { - static PyMethodDef md = { - "_sip_exit", sip_exit, METH_NOARGS, NULL - }; + static PyObject *register_func = NULL; + PyObject *notifier, *res; - PyObject *notifier, *register_func, *res; + if (register_func == NULL && (register_func = import_module_attr("atexit", "register")) == NULL) + return -1; - if ((notifier = PyCFunction_New(&md, NULL)) == NULL) - return; - - if ((register_func = import_module_attr("atexit", "register")) == NULL) - { - Py_DECREF(notifier); - return; - } + if ((notifier = PyCFunction_New(md, NULL)) == NULL) + return -1; res = PyObject_CallFunctionObjArgs(register_func, notifier, NULL); - Py_XDECREF(res); - Py_DECREF(register_func); Py_DECREF(notifier); + + if (res == NULL) + return -1; + + Py_DECREF(res); + + return 0; } @@ -14238,3 +14268,25 @@ int sip_api_convert_from_slice_object(PyObject *slice, SIP_SSIZE_T length, step, slicelength); #endif } + + +/* + * Call a visitor function for every wrapped object. + */ +static void sip_api_visit_wrappers(sipWrapperVisitorFunc visitor, + void *closure) +{ + const sipHashEntry *he; + unsigned long i; + + for (he = cppPyMap.hash_array, i = 0; i < cppPyMap.size; ++i, ++he) + { + if (he->key != NULL) + { + sipSimpleWrapper *sw; + + for (sw = he->first; sw != NULL; sw = sw->next) + visitor(sw, closure); + } + } +} diff --git a/sip/siplib/voidptr.c b/sip/siplib/voidptr.c index 58633490..7c288bf6 100644 --- a/sip/siplib/voidptr.c +++ b/sip/siplib/voidptr.c @@ -1,7 +1,7 @@ /* * SIP library code. * - * Copyright (c) 2018 Riverbank Computing Limited + * Copyright (c) 2019 Riverbank Computing Limited * * This file is part of SIP. * @@ -802,6 +802,9 @@ PyTypeObject sipVoidPtr_Type = { #if PY_VERSION_HEX >= 0x03040000 0, /* tp_finalize */ #endif +#if PY_VERSION_HEX >= 0x03080000 + 0, /* tp_vectorcall */ +#endif }; diff --git a/wx/include/wxPython/sip.h b/wx/include/wxPython/sip.h index 09d2ab67..bcb53ab2 100644 --- a/wx/include/wxPython/sip.h +++ b/wx/include/wxPython/sip.h @@ -54,8 +54,8 @@ extern "C" { /* * Define the SIP version number. */ -#define SIP_VERSION 0x041310 -#define SIP_VERSION_STR "4.19.16" +#define SIP_VERSION 0x041313 +#define SIP_VERSION_STR "4.19.19" /* @@ -68,6 +68,10 @@ extern "C" { * * History: * + * 12.7 Added sip_api_visit_wrappers() to the public API. + * Added sip_api_register_exit_notifier() to the public API. + * sip_api_is_owned_by_python() is now part of the public API. + * * 12.6 Added sip_api_long_as_size_t() to the public API. * Added the '=' format character to sip_api_build_result(). * Added the '=' format character to sip_api_parse_result_ex(). @@ -272,7 +276,7 @@ extern "C" { * 0.0 Original version. */ #define SIP_API_MAJOR_NR 12 -#define SIP_API_MINOR_NR 6 +#define SIP_API_MINOR_NR 7 /* @@ -537,6 +541,7 @@ typedef PyObject *(*sipVariableGetterFunc)(void *, PyObject *, PyObject *); typedef int (*sipVariableSetterFunc)(void *, PyObject *, PyObject *); typedef void *(*sipProxyResolverFunc)(void *); typedef int (*sipNewUserTypeFunc)(sipWrapperType *); +typedef void (*sipWrapperVisitorFunc)(sipSimpleWrapper *, void *); #if !defined(Py_LIMITED_API) || PY_VERSION_HEX < 0x03020000 @@ -1871,7 +1876,15 @@ typedef struct _sipAPIDef { int (*api_init_mixin)(PyObject *self, PyObject *args, PyObject *kwds, const sipClassTypeDef *ctd); PyObject *(*api_get_reference)(PyObject *self, int key); + + /* + * The following are part of the public API. + */ int (*api_is_owned_by_python)(sipSimpleWrapper *); + + /* + * The following are not part of the public API. + */ int (*api_is_derived_class)(sipSimpleWrapper *); /* @@ -1939,6 +1952,8 @@ typedef struct _sipAPIDef { SIP_SSIZE_T *start, SIP_SSIZE_T *stop, SIP_SSIZE_T *step, SIP_SSIZE_T *slicelength); size_t (*api_long_as_size_t)(PyObject *o); + void (*api_visit_wrappers)(sipWrapperVisitorFunc visitor, void *closure); + int (*api_register_exit_notifier)(PyMethodDef *md); } sipAPIDef;