From 5e00e331b79ece72843aa62af1a79090d0997a0e Mon Sep 17 00:00:00 2001 From: aneejit1 Date: Tue, 19 Apr 2022 00:17:45 +0000 Subject: Updates for Python 3 Support MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The following changes have been made to support Python 3: - in sip-tqt.h, remove the cast in the "sipConvertFromSliceObject" macro in versions 3.2+ as the API changed causing a compile error; - in voidptr.h, alter the precompile conditions to remove the PyCObject API cals for version 3.2+ (causes runtime symbol resolution error) and amend the flags for "asstring"; - alter module import process in siplib.c to avoid re-loading an already loaded module. Signed-off-by: aneejit1 Signed-off-by: Slávek Banko (cherry picked from commit 5b12d262dc940b6fe9e2766988917665c970318d) --- siplib/sip.h | 14 +++++++++++++- siplib/siplib.c | 30 +++++++++++++++++++++++++----- siplib/voidptr.c | 12 ++++++++++-- 3 files changed, 48 insertions(+), 8 deletions(-) diff --git a/siplib/sip.h b/siplib/sip.h index 3e9a3c6..48180a3 100644 --- a/siplib/sip.h +++ b/siplib/sip.h @@ -208,10 +208,14 @@ extern "C" { #define SIPBytes_AS_STRING PyBytes_AS_STRING #define SIPBytes_GET_SIZE PyBytes_GET_SIZE -#if PY_MINOR_VERSION >= 1 +#if (PY_MAJOR_VERSION > 3) || ((PY_MAJOR_VERSION == 3) && (PY_MINOR_VERSION >= 1)) #define SIP_USE_PYCAPSULE #endif +#if (PY_MAJOR_VERSION == 3) && (PY_MINOR_VERSION < 2) +#define SIP_SUPPORT_PYCOBJECT +#endif + #else #define SIPLong_FromLong PyInt_FromLong @@ -227,6 +231,8 @@ extern "C" { #define SIP_USE_PYCAPSULE #endif +#define SIP_SUPPORT_PYCOBJECT + #endif #if !defined(Py_REFCNT) @@ -1465,9 +1471,15 @@ typedef struct _sipTQtAPI { #define sipIsExactWrappedType(wt) (sipTypeAsPyTypeObject((wt)->type) == (PyTypeObject *)(wt)) +#if PY_VERSION_HEX >= 0x03020000 +#define sipConvertFromSliceObject(o,len,start,stop,step,slen) \ + PySlice_GetIndicesEx((o), (len), (start), (stop), \ + (step), (slen)) +#else #define sipConvertFromSliceObject(o,len,start,stop,step,slen) \ PySlice_GetIndicesEx((PySliceObject *)(o), (len), (start), (stop), \ (step), (slen)) +#endif /* diff --git a/siplib/siplib.c b/siplib/siplib.c index d43f121..ebbc194 100644 --- a/siplib/siplib.c +++ b/siplib/siplib.c @@ -648,6 +648,8 @@ static int add_all_lazy_attrs(sipTypeDef *td); static int objectify(const char *s, PyObject **objp); static void add_failure(PyObject **parseErrp, sipParseFailure *failure); static PyObject *bad_type_str(int arg_nr, PyObject *arg); +static sipExportedModuleDef *isModuleLoaded(sipExportedModuleDef *table, + char *name); /* @@ -1200,12 +1202,14 @@ static int sip_api_export_module(sipExportedModuleDef *client, { PyObject *mod; - if ((mod = PyImport_ImportModule(im->im_name)) == NULL) - return -1; + em = isModuleLoaded(moduleList, im->im_name); - for (em = moduleList; em != NULL; em = em->em_next) - if (strcmp(sipNameOfModule(em), im->im_name) == 0) - break; + if (em == NULL) + { + if ((mod = PyImport_ImportModule(im->im_name)) == NULL) + return -1; + em = isModuleLoaded(moduleList, im->im_name); + } if (em == NULL) { @@ -1276,6 +1280,22 @@ static int sip_api_export_module(sipExportedModuleDef *client, } +/* + * Find out if a client module has been loaded already. + */ +static sipExportedModuleDef *isModuleLoaded(sipExportedModuleDef *table, + char *name) +{ + sipExportedModuleDef *em = table; + + for (em = moduleList; em != NULL; em = em->em_next) + if (strcmp(sipNameOfModule(em), name) == 0) + return em; + + return NULL; +} + + /* * Initialise the contents of a client module. By this time anything that * this depends on should have been initialised. A negative value is returned diff --git a/siplib/voidptr.c b/siplib/voidptr.c index fc26046..dd7e039 100644 --- a/siplib/voidptr.c +++ b/siplib/voidptr.c @@ -195,6 +195,7 @@ static PyObject *sipVoidPtr_ascapsule(sipVoidPtrObject *v, PyObject *arg) #endif +#if defined(SIP_SUPPORT_PYCOBJECT) /* * Implement ascobject() for the type. */ @@ -202,6 +203,7 @@ static PyObject *sipVoidPtr_ascobject(sipVoidPtrObject *v, PyObject *arg) { return PyCObject_FromVoidPtr(v->voidptr, NULL); } +#endif /* @@ -311,8 +313,10 @@ static PyMethodDef sipVoidPtr_Methods[] = { #if defined(SIP_USE_PYCAPSULE) {"ascapsule", (PyCFunction)sipVoidPtr_ascapsule, METH_NOARGS, NULL}, #endif +#if defined(SIP_SUPPORT_PYCOBJECT) {"ascobject", (PyCFunction)sipVoidPtr_ascobject, METH_NOARGS, NULL}, - {"asstring", (PyCFunction)sipVoidPtr_asstring, METH_KEYWORDS, NULL}, +#endif + {"asstring", (PyCFunction)sipVoidPtr_asstring, METH_VARARGS|METH_KEYWORDS, NULL}, {"getsize", (PyCFunction)sipVoidPtr_getsize, METH_NOARGS, NULL}, {"setsize", (PyCFunction)sipVoidPtr_setsize, METH_O, NULL}, {"getwriteable", (PyCFunction)sipVoidPtr_getwriteable, METH_NOARGS, NULL}, @@ -456,9 +460,11 @@ void *sip_api_convert_to_void_ptr(PyObject *obj) if (PyCapsule_CheckExact(obj)) return PyCapsule_GetPointer(obj, NULL); #endif - +#if defined(SIP_SUPPORT_PYCOBJECT) if (PyCObject_Check(obj)) return PyCObject_AsVoidPtr(obj); +#endif + #if PY_MAJOR_VERSION >= 3 return PyLong_AsVoidPtr(obj); @@ -544,8 +550,10 @@ static int vp_convertor(PyObject *arg, struct vp_values *vp) else if (PyCapsule_CheckExact(arg)) ptr = PyCapsule_GetPointer(arg, NULL); #endif +#if defined(SIP_SUPPORT_PYCOBJECT) else if (PyCObject_Check(arg)) ptr = PyCObject_AsVoidPtr(arg); +#endif else if (PyObject_TypeCheck(arg, &sipVoidPtr_Type)) { ptr = ((sipVoidPtrObject *)arg)->voidptr; -- cgit v1.2.1