mirror of
https://github.com/wxWidgets/Phoenix.git
synced 2025-12-16 01:30:07 +01:00
Merge pull request #1026 from RobinD42/sip-4.19.13
Switch to SIP 4.19.13
(cherry picked from commit a268da9b84)
This commit is contained in:
@@ -1,7 +1,7 @@
|
||||
/*
|
||||
* SIP library code.
|
||||
*
|
||||
* Copyright (c) 2017 Riverbank Computing Limited <info@riverbankcomputing.com>
|
||||
* Copyright (c) 2018 Riverbank Computing Limited <info@riverbankcomputing.com>
|
||||
*
|
||||
* This file is part of SIP.
|
||||
*
|
||||
@@ -38,6 +38,24 @@
|
||||
#endif
|
||||
|
||||
|
||||
/*
|
||||
* The qualified and base names of the sip module. These should be defined in
|
||||
* the compiler invocation when creating a package-specific copy.
|
||||
*/
|
||||
#if !defined(SIP_MODULE_NAME)
|
||||
#define SIP_MODULE_NAME sip
|
||||
#endif
|
||||
|
||||
#if !defined(SIP_MODULE_BASENAME)
|
||||
#define SIP_MODULE_BASENAME sip
|
||||
#endif
|
||||
|
||||
#define STRINGIFY_EX(s) #s
|
||||
#define STRINGIFY(s) STRINGIFY_EX(s)
|
||||
|
||||
#define SIP_MODULE_NAME_STR STRINGIFY(SIP_MODULE_NAME)
|
||||
#define SIP_MODULE_BASENAME_STR STRINGIFY(SIP_MODULE_BASENAME)
|
||||
|
||||
/*
|
||||
* The Python metatype for a C++ wrapper type. We inherit everything from the
|
||||
* standard Python metatype except the init and getattro methods and the size
|
||||
@@ -438,6 +456,7 @@ static int sip_api_enable_gc(int enable);
|
||||
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);
|
||||
|
||||
|
||||
/*
|
||||
@@ -620,6 +639,14 @@ static const sipAPIDef sip_api = {
|
||||
0,
|
||||
0,
|
||||
#endif
|
||||
/*
|
||||
* The following are not part of the public API.
|
||||
*/
|
||||
sip_api_instance_destroyed_ex,
|
||||
/*
|
||||
* The following are part of the public API.
|
||||
*/
|
||||
sip_api_convert_from_slice_object,
|
||||
};
|
||||
|
||||
|
||||
@@ -722,6 +749,7 @@ typedef struct _sipEventHandler {
|
||||
*****************************************************************************/
|
||||
|
||||
static PyObject *sipEnumType_alloc(PyTypeObject *self, SIP_SSIZE_T nitems);
|
||||
static PyObject *sipEnumType_getattro(PyObject *self, PyObject *name);
|
||||
|
||||
|
||||
/*
|
||||
@@ -746,7 +774,7 @@ static PyTypeObject sipEnumType_Type = {
|
||||
0, /* tp_hash */
|
||||
0, /* tp_call */
|
||||
0, /* tp_str */
|
||||
0, /* tp_getattro */
|
||||
sipEnumType_getattro, /* tp_getattro */
|
||||
0, /* tp_setattro */
|
||||
0, /* tp_as_buffer */
|
||||
Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */
|
||||
@@ -1004,19 +1032,24 @@ static int long_as_nonoverflow_int(PyObject *val_obj);
|
||||
* The Python module initialisation function.
|
||||
*/
|
||||
#if PY_MAJOR_VERSION >= 3
|
||||
#define SIP_MODULE_ENTRY PyInit_siplib
|
||||
#define SIP_MODULE_ENTRY_PREFIX PyInit_
|
||||
#define SIP_MODULE_TYPE PyObject *
|
||||
#define SIP_MODULE_DISCARD(m) Py_DECREF(m)
|
||||
#define SIP_FATAL(s) return NULL
|
||||
#define SIP_MODULE_RETURN(m) return (m)
|
||||
#else
|
||||
#define SIP_MODULE_ENTRY initsiplib
|
||||
#define SIP_MODULE_ENTRY_PREFIX init
|
||||
#define SIP_MODULE_TYPE void
|
||||
#define SIP_MODULE_DISCARD(m)
|
||||
#define SIP_FATAL(s) Py_FatalError(s)
|
||||
#define SIP_MODULE_RETURN(m)
|
||||
#endif
|
||||
|
||||
#define CONCAT_EX(PREFIX, NAME) PREFIX ## NAME
|
||||
#define CONCAT(PREFIX, NAME) CONCAT_EX(PREFIX, NAME)
|
||||
|
||||
#define SIP_MODULE_ENTRY CONCAT(SIP_MODULE_ENTRY_PREFIX, SIP_MODULE_BASENAME)
|
||||
|
||||
#if defined(SIP_STATIC_MODULE)
|
||||
SIP_MODULE_TYPE SIP_MODULE_ENTRY(void)
|
||||
#else
|
||||
@@ -1050,7 +1083,7 @@ PyMODINIT_FUNC SIP_MODULE_ENTRY(void)
|
||||
#if PY_MAJOR_VERSION >= 3
|
||||
static PyModuleDef module_def = {
|
||||
PyModuleDef_HEAD_INIT,
|
||||
SIP_MODULE_NAME, /* m_name */
|
||||
SIP_MODULE_NAME_STR, /* m_name */
|
||||
NULL, /* m_doc */
|
||||
-1, /* m_size */
|
||||
methods, /* m_methods */
|
||||
@@ -1080,13 +1113,13 @@ PyMODINIT_FUNC SIP_MODULE_ENTRY(void)
|
||||
sipWrapperType_Type.tp_base = &PyType_Type;
|
||||
|
||||
if (PyType_Ready(&sipWrapperType_Type) < 0)
|
||||
SIP_FATAL(SIP_MODULE_NAME ": Failed to initialise sip.wrappertype type");
|
||||
SIP_FATAL(SIP_MODULE_NAME_STR ": Failed to initialise sip.wrappertype type");
|
||||
|
||||
if (PyType_Ready((PyTypeObject *)&sipSimpleWrapper_Type) < 0)
|
||||
SIP_FATAL(SIP_MODULE_NAME ": Failed to initialise sip.simplewrapper type");
|
||||
SIP_FATAL(SIP_MODULE_NAME_STR ": Failed to initialise sip.simplewrapper type");
|
||||
|
||||
if (sip_api_register_py_type((PyTypeObject *)&sipSimpleWrapper_Type) < 0)
|
||||
SIP_FATAL(SIP_MODULE_NAME ": Failed to register sip.simplewrapper type");
|
||||
SIP_FATAL(SIP_MODULE_NAME_STR ": Failed to register sip.simplewrapper type");
|
||||
|
||||
#if defined(STACKLESS)
|
||||
sipWrapper_Type.super.tp_base = (PyTypeObject *)&sipSimpleWrapper_Type;
|
||||
@@ -1097,33 +1130,33 @@ PyMODINIT_FUNC SIP_MODULE_ENTRY(void)
|
||||
#endif
|
||||
|
||||
if (PyType_Ready((PyTypeObject *)&sipWrapper_Type) < 0)
|
||||
SIP_FATAL(SIP_MODULE_NAME ": Failed to initialise sip.wrapper type");
|
||||
SIP_FATAL(SIP_MODULE_NAME_STR ": Failed to initialise sip.wrapper type");
|
||||
|
||||
if (PyType_Ready(&sipMethodDescr_Type) < 0)
|
||||
SIP_FATAL(SIP_MODULE_NAME ": Failed to initialise sip.methoddescriptor type");
|
||||
SIP_FATAL(SIP_MODULE_NAME_STR ": Failed to initialise sip.methoddescriptor type");
|
||||
|
||||
if (PyType_Ready(&sipVariableDescr_Type) < 0)
|
||||
SIP_FATAL(SIP_MODULE_NAME ": Failed to initialise sip.variabledescriptor type");
|
||||
SIP_FATAL(SIP_MODULE_NAME_STR ": Failed to initialise sip.variabledescriptor type");
|
||||
|
||||
sipEnumType_Type.tp_base = &PyType_Type;
|
||||
|
||||
if (PyType_Ready(&sipEnumType_Type) < 0)
|
||||
SIP_FATAL(SIP_MODULE_NAME ": Failed to initialise sip.enumtype type");
|
||||
SIP_FATAL(SIP_MODULE_NAME_STR ": Failed to initialise sip.enumtype type");
|
||||
|
||||
if (PyType_Ready(&sipVoidPtr_Type) < 0)
|
||||
SIP_FATAL(SIP_MODULE_NAME ": Failed to initialise sip.voidptr type");
|
||||
SIP_FATAL(SIP_MODULE_NAME_STR ": Failed to initialise sip.voidptr type");
|
||||
|
||||
if (PyType_Ready(&sipArray_Type) < 0)
|
||||
SIP_FATAL(SIP_MODULE_NAME ": Failed to initialise sip.array type");
|
||||
SIP_FATAL(SIP_MODULE_NAME_STR ": Failed to initialise sip.array type");
|
||||
|
||||
#if PY_MAJOR_VERSION >= 3
|
||||
mod = PyModule_Create(&module_def);
|
||||
#else
|
||||
mod = Py_InitModule(SIP_MODULE_NAME, methods);
|
||||
mod = Py_InitModule(SIP_MODULE_NAME_STR, methods);
|
||||
#endif
|
||||
|
||||
if (mod == NULL)
|
||||
SIP_FATAL(SIP_MODULE_NAME ": Failed to initialise sip module");
|
||||
SIP_FATAL(SIP_MODULE_NAME_STR ": Failed to initialise sip module");
|
||||
|
||||
mod_dict = PyModule_GetDict(mod);
|
||||
|
||||
@@ -1134,12 +1167,12 @@ PyMODINIT_FUNC SIP_MODULE_ENTRY(void)
|
||||
if (type_unpickler == NULL || enum_unpickler == NULL)
|
||||
{
|
||||
SIP_MODULE_DISCARD(mod);
|
||||
SIP_FATAL(SIP_MODULE_NAME ": Failed to get pickle helpers");
|
||||
SIP_FATAL(SIP_MODULE_NAME_STR ": Failed to get pickle helpers");
|
||||
}
|
||||
|
||||
/* Publish the SIP API. */
|
||||
#if defined(SIP_USE_PYCAPSULE)
|
||||
obj = PyCapsule_New((void *)&sip_api, SIP_MODULE_NAME "._C_API", NULL);
|
||||
obj = PyCapsule_New((void *)&sip_api, SIP_MODULE_NAME_STR "._C_API", NULL);
|
||||
#else
|
||||
obj = PyCObject_FromVoidPtr((void *)&sip_api, NULL);
|
||||
#endif
|
||||
@@ -1147,7 +1180,7 @@ PyMODINIT_FUNC SIP_MODULE_ENTRY(void)
|
||||
if (obj == NULL)
|
||||
{
|
||||
SIP_MODULE_DISCARD(mod);
|
||||
SIP_FATAL(SIP_MODULE_NAME ": Failed to create _C_API object");
|
||||
SIP_FATAL(SIP_MODULE_NAME_STR ": Failed to create _C_API object");
|
||||
}
|
||||
|
||||
rc = PyDict_SetItemString(mod_dict, "_C_API", obj);
|
||||
@@ -1156,20 +1189,20 @@ PyMODINIT_FUNC SIP_MODULE_ENTRY(void)
|
||||
if (rc < 0)
|
||||
{
|
||||
SIP_MODULE_DISCARD(mod);
|
||||
SIP_FATAL(SIP_MODULE_NAME ": Failed to add _C_API object to module dictionary");
|
||||
SIP_FATAL(SIP_MODULE_NAME_STR ": Failed to add _C_API object to module dictionary");
|
||||
}
|
||||
|
||||
/* These will always be needed. */
|
||||
if (objectify("__init__", &init_name) < 0)
|
||||
{
|
||||
SIP_MODULE_DISCARD(mod);
|
||||
SIP_FATAL(SIP_MODULE_NAME ": Failed to objectify '__init__'");
|
||||
SIP_FATAL(SIP_MODULE_NAME_STR ": Failed to objectify '__init__'");
|
||||
}
|
||||
|
||||
if ((empty_tuple = PyTuple_New(0)) == NULL)
|
||||
{
|
||||
SIP_MODULE_DISCARD(mod);
|
||||
SIP_FATAL(SIP_MODULE_NAME ": Failed to create empty tuple");
|
||||
SIP_FATAL(SIP_MODULE_NAME_STR ": Failed to create empty tuple");
|
||||
}
|
||||
|
||||
/* Add the SIP version number, but don't worry about errors. */
|
||||
@@ -1225,6 +1258,18 @@ PyMODINIT_FUNC SIP_MODULE_ENTRY(void)
|
||||
/* Make sure we are notified when starting to exit. */
|
||||
register_exit_notifier();
|
||||
|
||||
/*
|
||||
* Also install the package-specific module at the top level for backwards
|
||||
* compatibility.
|
||||
*/
|
||||
if (strcmp(SIP_MODULE_NAME_STR, "sip") != 0 && strcmp(SIP_MODULE_BASENAME_STR, "sip") == 0)
|
||||
{
|
||||
PyObject *modules = PySys_GetObject("modules");
|
||||
|
||||
if (modules != NULL)
|
||||
PyDict_SetItemString(modules, "sip", mod);
|
||||
}
|
||||
|
||||
SIP_MODULE_RETURN(mod);
|
||||
}
|
||||
|
||||
@@ -5373,11 +5418,11 @@ static int parsePass1(PyObject **parseErrp, sipSimpleWrapper **selfp,
|
||||
else
|
||||
{
|
||||
#if PY_MAJOR_VERSION >= 3
|
||||
PyErr_Format(PyExc_OverflowError, "argument '%d' overflowed: %S",
|
||||
failure.arg_nr, failure.detail_obj);
|
||||
PyErr_Format(PyExc_OverflowError, "argument '%s' overflowed: %S",
|
||||
failure.arg_name, failure.detail_obj);
|
||||
#else
|
||||
PyErr_Format(PyExc_OverflowError, "argument '%d' overflowed: %s",
|
||||
failure.arg_nr, exc_str);
|
||||
PyErr_Format(PyExc_OverflowError, "argument '%s' overflowed: %s",
|
||||
failure.arg_name, exc_str);
|
||||
#endif
|
||||
}
|
||||
|
||||
@@ -5999,17 +6044,28 @@ static PyObject *convertToSequence(void *array, SIP_SSIZE_T nr_elem,
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Perform housekeeping after a C++ instance has been destroyed.
|
||||
*/
|
||||
void sip_api_instance_destroyed(sipSimpleWrapper *sw)
|
||||
{
|
||||
sip_api_instance_destroyed_ex(&sw);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Carry out actions common to all dtors.
|
||||
*/
|
||||
void sip_api_instance_destroyed(sipSimpleWrapper *sipSelf)
|
||||
static void sip_api_instance_destroyed_ex(sipSimpleWrapper **sipSelfp)
|
||||
{
|
||||
SIP_BLOCK_THREADS
|
||||
|
||||
sipSimpleWrapper *sipSelf = *sipSelfp;
|
||||
|
||||
if (sipSelf != NULL && sipInterpreter != 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);
|
||||
@@ -6017,7 +6073,11 @@ void sip_api_instance_destroyed(sipSimpleWrapper *sipSelf)
|
||||
|
||||
sipOMRemoveObject(&cppPyMap, sipSelf);
|
||||
|
||||
/* This no longer points to anything useful. */
|
||||
/*
|
||||
* This no longer points to anything useful. Actually it might do as
|
||||
* the partialy destroyed C++ instance may still be trying to invoke
|
||||
* reimplemented virtuals.
|
||||
*/
|
||||
clear_access_func(sipSelf);
|
||||
|
||||
/*
|
||||
@@ -6030,10 +6090,20 @@ void sip_api_instance_destroyed(sipSimpleWrapper *sipSelf)
|
||||
Py_DECREF(sipSelf);
|
||||
}
|
||||
else if (PyObject_TypeCheck((PyObject *)sipSelf, (PyTypeObject *)&sipWrapper_Type))
|
||||
{
|
||||
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;
|
||||
|
||||
SIP_UNBLOCK_THREADS
|
||||
}
|
||||
|
||||
|
||||
@@ -6245,14 +6315,22 @@ static PyObject *createContainerType(sipContainerDef *cod, sipTypeDef *td,
|
||||
PyObject *type_dict, sipExportedModuleDef *client)
|
||||
{
|
||||
PyObject *py_type, *scope_dict, *name, *args;
|
||||
sipTypeDef *scope_td;
|
||||
|
||||
/* Get the dictionary to place the type in. */
|
||||
if (cod->cod_scope.sc_flag)
|
||||
{
|
||||
scope_td = NULL;
|
||||
scope_dict = mod_dict;
|
||||
}
|
||||
else if ((scope_dict = getScopeDict(getGeneratedType(&cod->cod_scope, client), mod_dict, client)) == NULL)
|
||||
goto reterr;
|
||||
else
|
||||
{
|
||||
scope_td = getGeneratedType(&cod->cod_scope, client);
|
||||
scope_dict = getScopeDict(scope_td, mod_dict, client);
|
||||
|
||||
if (scope_dict == NULL)
|
||||
goto reterr;
|
||||
}
|
||||
|
||||
/* Create an object corresponding to the type name. */
|
||||
#if PY_MAJOR_VERSION >= 3
|
||||
@@ -6283,6 +6361,23 @@ static PyObject *createContainerType(sipContainerDef *cod, sipTypeDef *td,
|
||||
if (py_type == NULL)
|
||||
goto relargs;
|
||||
|
||||
#if PY_VERSION_HEX >= 0x03030000
|
||||
/* Fix __qualname__ if there is a scope. */
|
||||
if (scope_td != NULL)
|
||||
{
|
||||
PyHeapTypeObject *ht;
|
||||
PyObject *qualname = get_qualname(scope_td, name);
|
||||
|
||||
if (qualname == NULL)
|
||||
goto reltype;
|
||||
|
||||
ht = (PyHeapTypeObject *)py_type;
|
||||
|
||||
Py_CLEAR(ht->ht_qualname);
|
||||
ht->ht_qualname = qualname;
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Add the type to the "parent" dictionary. */
|
||||
if (PyDict_SetItem(scope_dict, name, py_type) < 0)
|
||||
goto reltype;
|
||||
@@ -6378,6 +6473,16 @@ static int createClassType(sipExportedModuleDef *client, sipClassTypeDef *ctd,
|
||||
|
||||
Py_INCREF(st);
|
||||
PyTuple_SET_ITEM(bases, i, st);
|
||||
|
||||
/*
|
||||
* Inherit any garbage collector code rather than look for it each
|
||||
* time it is needed.
|
||||
*/
|
||||
if (ctd->ctd_traverse == NULL)
|
||||
ctd->ctd_traverse = ((sipClassTypeDef *)sup_td)->ctd_traverse;
|
||||
|
||||
if (ctd->ctd_clear == NULL)
|
||||
ctd->ctd_clear = ((sipClassTypeDef *)sup_td)->ctd_clear;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -7167,9 +7272,7 @@ static int add_lazy_container_attrs(sipTypeDef *td, sipContainerDef *cod,
|
||||
sipVariableDef *vd;
|
||||
|
||||
/* Do the methods. */
|
||||
pmd = cod->cod_methods;
|
||||
|
||||
for (i = 0; i < cod->cod_nrmethods; ++i)
|
||||
for (pmd = cod->cod_methods, i = 0; i < cod->cod_nrmethods; ++i, ++pmd)
|
||||
{
|
||||
/* Non-lazy methods will already have been handled. */
|
||||
if (!sipTypeHasNonlazyMethod(td) || !isNonlazyMethod(pmd))
|
||||
@@ -7177,14 +7280,10 @@ static int add_lazy_container_attrs(sipTypeDef *td, sipContainerDef *cod,
|
||||
if (addMethod(dict, pmd) < 0)
|
||||
return -1;
|
||||
}
|
||||
|
||||
++pmd;
|
||||
}
|
||||
|
||||
/* Do the unscoped enum members. */
|
||||
enm = cod->cod_enummembers;
|
||||
|
||||
for (i = 0; i < cod->cod_nrenummembers; ++i)
|
||||
for (enm = cod->cod_enummembers, i = 0; i < cod->cod_nrenummembers; ++i, ++enm)
|
||||
{
|
||||
int rc;
|
||||
PyObject *val;
|
||||
@@ -7217,14 +7316,10 @@ static int add_lazy_container_attrs(sipTypeDef *td, sipContainerDef *cod,
|
||||
|
||||
if (rc < 0)
|
||||
return -1;
|
||||
|
||||
++enm;
|
||||
}
|
||||
|
||||
/* Do the variables. */
|
||||
vd = cod->cod_variables;
|
||||
|
||||
for (i = 0; i < cod->cod_nrvariables; ++i)
|
||||
for (vd = cod->cod_variables, i = 0; i < cod->cod_nrvariables; ++i, ++vd)
|
||||
{
|
||||
int rc;
|
||||
PyObject *descr;
|
||||
@@ -7243,8 +7338,6 @@ static int add_lazy_container_attrs(sipTypeDef *td, sipContainerDef *cod,
|
||||
|
||||
if (rc < 0)
|
||||
return -1;
|
||||
|
||||
++vd;
|
||||
}
|
||||
|
||||
return 0;
|
||||
@@ -10935,25 +11028,11 @@ static int sipSimpleWrapper_traverse(sipSimpleWrapper *self, visitproc visit,
|
||||
void *ptr;
|
||||
const sipClassTypeDef *ctd;
|
||||
|
||||
/* Call the nearest handwritten traverse code in the class hierachy. */
|
||||
/* Call any handwritten traverse code. */
|
||||
if ((ptr = getPtrTypeDef(self, &ctd)) != NULL)
|
||||
{
|
||||
const sipClassTypeDef *sup_ctd = ctd;
|
||||
|
||||
if (ctd->ctd_traverse == NULL)
|
||||
{
|
||||
const sipEncodedTypeDef *sup;
|
||||
|
||||
if ((sup = ctd->ctd_supers) != NULL)
|
||||
do
|
||||
sup_ctd = sipGetGeneratedClassType(sup, ctd);
|
||||
while (sup_ctd->ctd_traverse == NULL && !sup++->sc_flag);
|
||||
}
|
||||
|
||||
if (sup_ctd->ctd_traverse != NULL)
|
||||
if ((vret = sup_ctd->ctd_traverse(ptr, visit, arg)) != 0)
|
||||
if (ctd->ctd_traverse != NULL)
|
||||
if ((vret = ctd->ctd_traverse(ptr, visit, arg)) != 0)
|
||||
return vret;
|
||||
}
|
||||
|
||||
if (self->dict != NULL)
|
||||
if ((vret = visit(self->dict, arg)) != 0)
|
||||
@@ -10985,24 +11064,10 @@ static int sipSimpleWrapper_clear(sipSimpleWrapper *self)
|
||||
const sipClassTypeDef *ctd;
|
||||
PyObject *tmp;
|
||||
|
||||
/* Call the nearest handwritten clear code in the class hierachy. */
|
||||
/* Call any handwritten clear code. */
|
||||
if ((ptr = getPtrTypeDef(self, &ctd)) != NULL)
|
||||
{
|
||||
const sipClassTypeDef *sup_ctd = ctd;
|
||||
|
||||
if (ctd->ctd_clear == NULL)
|
||||
{
|
||||
sipEncodedTypeDef *sup;
|
||||
|
||||
if ((sup = ctd->ctd_supers) != NULL)
|
||||
do
|
||||
sup_ctd = sipGetGeneratedClassType(sup, ctd);
|
||||
while (sup_ctd->ctd_clear == NULL && !sup++->sc_flag);
|
||||
}
|
||||
|
||||
if (sup_ctd->ctd_clear != NULL)
|
||||
vret = sup_ctd->ctd_clear(ptr);
|
||||
}
|
||||
if (ctd->ctd_clear != NULL)
|
||||
vret = ctd->ctd_clear(ptr);
|
||||
|
||||
/* Remove the instance dictionary. */
|
||||
tmp = self->dict;
|
||||
@@ -12545,10 +12610,25 @@ static int parseBytes_AsCharArray(PyObject *obj, const char **ap,
|
||||
a = SIPBytes_AS_STRING(obj);
|
||||
asz = SIPBytes_GET_SIZE(obj);
|
||||
}
|
||||
#if PY_MAJOR_VERSION >= 3
|
||||
else
|
||||
{
|
||||
Py_buffer view;
|
||||
|
||||
if (PyObject_GetBuffer(obj, &view, PyBUF_SIMPLE) < 0)
|
||||
return -1;
|
||||
|
||||
a = view.buf;
|
||||
asz = view.len;
|
||||
|
||||
PyBuffer_Release(&view);
|
||||
}
|
||||
#else
|
||||
else if (PyObject_AsCharBuffer(obj, &a, &asz) < 0)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
#endif
|
||||
|
||||
if (ap != NULL)
|
||||
*ap = a;
|
||||
@@ -12573,10 +12653,25 @@ static int parseBytes_AsChar(PyObject *obj, char *ap)
|
||||
chp = SIPBytes_AS_STRING(obj);
|
||||
sz = SIPBytes_GET_SIZE(obj);
|
||||
}
|
||||
#if PY_MAJOR_VERSION >= 3
|
||||
else
|
||||
{
|
||||
Py_buffer view;
|
||||
|
||||
if (PyObject_GetBuffer(obj, &view, PyBUF_SIMPLE) < 0)
|
||||
return -1;
|
||||
|
||||
chp = view.buf;
|
||||
sz = view.len;
|
||||
|
||||
PyBuffer_Release(&view);
|
||||
}
|
||||
#else
|
||||
else if (PyObject_AsCharBuffer(obj, &chp, &sz) < 0)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
#endif
|
||||
|
||||
if (sz != 1)
|
||||
return -1;
|
||||
@@ -12953,6 +13048,88 @@ static PyObject *sipEnumType_alloc(PyTypeObject *self, SIP_SSIZE_T nitems)
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* The enum type getattro slot.
|
||||
*/
|
||||
static PyObject *sipEnumType_getattro(PyObject *self, PyObject *name)
|
||||
{
|
||||
PyObject *res;
|
||||
sipEnumTypeDef *etd;
|
||||
sipExportedModuleDef *client;
|
||||
const sipEnumMemberDef *enm, *emd;
|
||||
int enum_nr, nr_members, m;
|
||||
const char *name_str;
|
||||
|
||||
/*
|
||||
* Try a generic lookup first. This has the side effect of checking the
|
||||
* type of the name object.
|
||||
*/
|
||||
if ((res = PyObject_GenericGetAttr(self, name)) != NULL)
|
||||
return res;
|
||||
|
||||
if (!PyErr_ExceptionMatches(PyExc_AttributeError))
|
||||
return NULL;
|
||||
|
||||
PyErr_Clear();
|
||||
|
||||
/* Get the member name. */
|
||||
#if PY_VERSION_HEX >= 0x03030000
|
||||
name_str = PyUnicode_AsUTF8(name);
|
||||
#elif PY_MAJOR_VERSION >= 3
|
||||
name_str = _PyUnicode_AsString(name);
|
||||
#else
|
||||
/* We don't handle Unicode names. */
|
||||
if (!PyString_Check(name))
|
||||
{
|
||||
PyErr_Format(PyExc_TypeError,
|
||||
"attribute name must be string, not '%.200s'",
|
||||
Py_TYPE(name)->tp_name);
|
||||
name_str = NULL;
|
||||
}
|
||||
else
|
||||
{
|
||||
name_str = PyString_AS_STRING(name);
|
||||
}
|
||||
#endif
|
||||
|
||||
if (name_str == NULL)
|
||||
return NULL;
|
||||
|
||||
etd = (sipEnumTypeDef *)((sipEnumTypeObject *)self)->type;
|
||||
client = ((sipTypeDef *)etd)->td_module;
|
||||
|
||||
/* Find the number of this enum. */
|
||||
for (enum_nr = 0; enum_nr < client->em_nrtypes; ++enum_nr)
|
||||
if (client->em_types[enum_nr] == (sipTypeDef *)etd)
|
||||
break;
|
||||
|
||||
/* Get the enum members in the same scope. */
|
||||
if (etd->etd_scope < 0)
|
||||
{
|
||||
nr_members = client->em_nrenummembers;
|
||||
enm = client->em_enummembers;
|
||||
}
|
||||
else
|
||||
{
|
||||
const sipContainerDef *cod = get_container(client->em_types[etd->etd_scope]);
|
||||
|
||||
nr_members = cod->cod_nrenummembers;
|
||||
enm = cod->cod_enummembers;
|
||||
}
|
||||
|
||||
/* Find the enum member. */
|
||||
for (emd = enm, m = 0; m < nr_members; ++m, ++emd)
|
||||
if (emd->em_enum == enum_nr && strcmp(emd->em_name, name_str) == 0)
|
||||
return sip_api_convert_from_enum(emd->em_val, (sipTypeDef *)etd);
|
||||
|
||||
PyErr_Format(PyExc_AttributeError,
|
||||
"sip.enumtype object '%s' has no member '%s'",
|
||||
sipPyNameOfEnum(etd), name_str);
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Check if an object is of the right type to convert to an encoded string.
|
||||
*/
|
||||
@@ -12967,8 +13144,24 @@ static int check_encoded_string(PyObject *obj)
|
||||
if (SIPBytes_Check(obj))
|
||||
return 0;
|
||||
|
||||
#if PY_MAJOR_VERSION >= 3
|
||||
{
|
||||
Py_buffer view;
|
||||
|
||||
if (PyObject_GetBuffer(obj, &view, PyBUF_SIMPLE) < 0)
|
||||
{
|
||||
PyErr_Clear();
|
||||
}
|
||||
else
|
||||
{
|
||||
PyBuffer_Release(&view);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
#else
|
||||
if (PyObject_CheckReadBuffer(obj))
|
||||
return 0;
|
||||
#endif
|
||||
|
||||
return -1;
|
||||
}
|
||||
@@ -13965,3 +14158,26 @@ static PyObject *get_qualname(const sipTypeDef *td, PyObject *name)
|
||||
((PyHeapTypeObject *)scope_type)->ht_qualname, name);
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
/*
|
||||
* Implement PySlice_GetIndicesEx() (or its subsequent replacement).
|
||||
*/
|
||||
int sip_api_convert_from_slice_object(PyObject *slice, SIP_SSIZE_T length,
|
||||
SIP_SSIZE_T *start, SIP_SSIZE_T *stop, SIP_SSIZE_T *step,
|
||||
SIP_SSIZE_T *slicelength)
|
||||
{
|
||||
#if PY_VERSION_HEX >= 0x03070000
|
||||
if (PySlice_Unpack(slice, start, stop, step) < 0)
|
||||
return -1;
|
||||
|
||||
*slicelength = PySlice_AdjustIndices(length, start, stop, *step);
|
||||
|
||||
return 0;
|
||||
#elif PY_VERSION_HEX >= 0x03020000
|
||||
return PySlice_GetIndicesEx(slice, length, start, stop, step, slicelength);
|
||||
#else
|
||||
return PySlice_GetIndicesEx((PySliceObject *)slice, length, start, stop,
|
||||
step, slicelength);
|
||||
#endif
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user