Start of porting to newest sip. Not quite ready yet…

This commit is contained in:
Robin Dunn
2015-03-13 18:28:33 -07:00
parent 2c3b7a813d
commit db20285f49
15 changed files with 2451 additions and 333 deletions

View File

@@ -58,9 +58,9 @@ 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.7'
sipCurrentVersion = '4.16.7-snapshot-f652446e2462'
sipMD5 = {
'darwin' : '836e78f3c2bf9f8233b32c1a3599efec',
'darwin' : '72f61157902148d067eed3145d22990d',
'win32' : '208e8472342c07c2679868602d96a42b',
'linux' : '382c01bae24ace03ec8ae1ba6d76351a',
}

View File

@@ -120,7 +120,7 @@ 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
#'-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'),

View File

@@ -1,7 +1,7 @@
/*
* The implementation of the supprt for setting API versions.
*
* Copyright (c) 2013 Riverbank Computing Limited <info@riverbankcomputing.com>
* Copyright (c) 2015 Riverbank Computing Limited <info@riverbankcomputing.com>
*
* This file is part of SIP.
*
@@ -185,6 +185,8 @@ PyObject *sipGetAPI(PyObject *self, PyObject *args)
const char *api;
const apiVersionDef *avd;
(void)self;
if (!PyArg_ParseTuple(args, "s:getapi", &api))
return NULL;
@@ -211,6 +213,8 @@ PyObject *sipSetAPI(PyObject *self, PyObject *args)
int version_nr;
const apiVersionDef *avd;
(void)self;
if (!PyArg_ParseTuple(args, "si:setapi", &api, &version_nr))
return NULL;

887
sip/siplib/array.c Normal file
View File

@@ -0,0 +1,887 @@
/*
* This file implements the API for the array type.
*
* Copyright (c) 2015 Riverbank Computing Limited <info@riverbankcomputing.com>
*
* This file is part of SIP.
*
* This copy of SIP is licensed for use under the terms of the SIP License
* Agreement. See the file LICENSE for more details.
*
* This copy of SIP may also used under the terms of the GNU General Public
* License v2 or v3 as published by the Free Software Foundation which can be
* found in the files LICENSE-GPL2 and LICENSE-GPL3 included in this package.
*
* SIP is supplied WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
*/
#include <Python.h>
#include <stddef.h>
#include <string.h>
#include "sip.h"
#include "sipint.h"
#include "array.h"
/* The object data structure. */
typedef struct {
PyObject_HEAD
void *data;
const sipTypeDef *td;
const char *format;
size_t stride;
SIP_SSIZE_T len;
int flags;
PyObject *owner;
} sipArrayObject;
static int check_writable(sipArrayObject *array);
static int check_index(sipArrayObject *array, SIP_SSIZE_T idx);
static void *get_value(sipArrayObject *array, PyObject *value);
static void *get_slice(sipArrayObject *array, PyObject *value,
SIP_SSIZE_T len);
#if PY_VERSION_HEX < 0x02050000
static void fix_bounds(int len, int *left, int *right);
#endif
#if PY_VERSION_HEX >= 0x02050000
static void bad_key(PyObject *key);
#endif
static void *element(sipArrayObject *array, SIP_SSIZE_T idx);
static PyObject *make_array(void *data, const sipTypeDef *td,
const char *format, size_t stride, SIP_SSIZE_T len, int flags,
PyObject *owner);
/*
* Implement len() for the type.
*/
static SIP_SSIZE_T sipArray_length(PyObject *self)
{
return ((sipArrayObject *)self)->len;
}
/*
* Implement sequence item sub-script for the type.
*/
static PyObject *sipArray_item(PyObject *self, SIP_SSIZE_T idx)
{
sipArrayObject *array = (sipArrayObject *)self;
PyObject *py_item;
void *data;
if (check_index(array, idx) < 0)
return NULL;
data = element(array, idx);
if (array->td != NULL)
{
py_item = sip_api_convert_from_type(data, array->td, NULL);
}
else
{
switch (*array->format)
{
case 'b':
py_item = SIPLong_FromLong(*(char *)data);
break;
case 'B':
py_item = PyLong_FromUnsignedLong(*(unsigned char *)data);
break;
case 'h':
py_item = SIPLong_FromLong(*(short *)data);
break;
case 'H':
py_item = PyLong_FromUnsignedLong(*(unsigned short *)data);
break;
case 'i':
py_item = SIPLong_FromLong(*(int *)data);
break;
case 'I':
py_item = PyLong_FromUnsignedLong(*(unsigned int *)data);
break;
case 'f':
py_item = PyFloat_FromDouble(*(float *)data);
break;
case 'd':
py_item = PyFloat_FromDouble(*(double *)data);
break;
default:
py_item = NULL;
}
}
return py_item;
}
#if PY_VERSION_HEX < 0x02050000
/*
* Implement sequence slice sub-script for the type.
*/
static PyObject *sipArray_slice(PyObject *self, int left, int right)
{
sipArrayObject *array = (sipArrayObject *)self;
fix_bounds(array->len, &left, &right);
if (left == right)
left = right = 0;
return make_array(element(array, left), array->td, array->format,
array->stride, right - left, (array->flags & ~SIP_OWNS_MEMORY),
array->owner);
}
/*
* Implement sequence assignment item sub-script for the type.
*/
static int sipArray_ass_item(PyObject *self, int idx, PyObject *value)
{
sipArrayObject *array = (sipArrayObject *)self;
void *value_data;
if (check_writable(array) < 0 || check_index(array, idx) < 0)
return -1;
if ((value_data = get_value(array, value)) == NULL)
return -1;
memmove(element(array, idx), value_data, array->stride);
return 0;
}
/*
* Implement sequence assignment slice sub-script for the type.
*/
static int sipArray_ass_slice(PyObject *self, int left, int right,
PyObject *value)
{
sipArrayObject *array = (sipArrayObject *)self;
void *value_data;
if (check_writable(array) < 0)
return -1;
fix_bounds(array->len, &left, &right);
if ((value_data = get_slice(array, value, right - left)) == NULL)
return -1;
memmove(element(array, left), value_data, (right - left) * array->stride);
return 0;
}
#endif
/* The sequence methods data structure. */
static PySequenceMethods sipArray_SequenceMethods = {
sipArray_length, /* sq_length */
0, /* sq_concat */
0, /* sq_repeat */
sipArray_item, /* sq_item */
#if PY_VERSION_HEX >= 0x02050000
0, /* sq_slice */
0, /* sq_ass_item */
0, /* sq_ass_slice */
#else
sipArray_slice, /* sq_slice */
sipArray_ass_item, /* sq_ass_item */
sipArray_ass_slice, /* sq_ass_slice */
#endif
0, /* sq_contains */
0, /* sq_inplace_concat */
0, /* sq_inplace_repeat */
};
#if PY_VERSION_HEX >= 0x02050000
/*
* Implement mapping sub-script for the type.
*/
static PyObject *sipArray_subscript(PyObject *self, PyObject *key)
{
sipArrayObject *array = (sipArrayObject *)self;
if (PyIndex_Check(key))
{
Py_ssize_t idx = PyNumber_AsSsize_t(key, PyExc_IndexError);
if (idx == -1 && PyErr_Occurred())
return NULL;
if (idx < 0)
idx += array->len;
return sipArray_item(self, idx);
}
if (PySlice_Check(key))
{
Py_ssize_t start, stop, step, slicelength;
if (sipConvertFromSliceObject(key, array->len, &start, &stop, &step, &slicelength) < 0)
return NULL;
if (step != 1)
{
PyErr_SetNone(PyExc_NotImplementedError);
return NULL;
}
return make_array(element(array->data, start), array->td,
array->format, array->stride, slicelength,
(array->flags & ~SIP_OWNS_MEMORY), array->owner);
}
bad_key(key);
return NULL;
}
/*
* Implement mapping assignment sub-script for the type.
*/
static int sipArray_ass_subscript(PyObject *self, PyObject *key,
PyObject *value)
{
sipArrayObject *array = (sipArrayObject *)self;
SIP_SSIZE_T start, len;
void *value_data;
if (check_writable(array) < 0)
return -1;
if (PyIndex_Check(key))
{
start = PyNumber_AsSsize_t(key, PyExc_IndexError);
if (start == -1 && PyErr_Occurred())
return -1;
if (start < 0)
start += array->len;
if (check_index(array, start) < 0)
return -1;
if ((value_data = get_value(array, value)) == NULL)
return -1;
len = 1;
}
else if (PySlice_Check(key))
{
Py_ssize_t stop, step;
if (sipConvertFromSliceObject(key, array->len, &start, &stop, &step, &len) < 0)
return -1;
if (step != 1)
{
PyErr_SetNone(PyExc_NotImplementedError);
return -1;
}
if ((value_data = get_slice(array, value, len)) == NULL)
return -1;
}
else
{
bad_key(key);
return -1;
}
memmove(element(array, start), value_data, len * array->stride);
return 0;
}
/* The mapping methods data structure. */
static PyMappingMethods sipArray_MappingMethods = {
sipArray_length, /* mp_length */
sipArray_subscript, /* mp_subscript */
sipArray_ass_subscript, /* mp_ass_subscript */
};
#endif
#if PY_VERSION_HEX >= 0x02060300
/*
* The buffer implementation for Python v2.6.3 and later.
*/
static int sipArray_getbuffer(PyObject *self, Py_buffer *view, int flags)
{
sipArrayObject *array = (sipArrayObject *)self;
if (view == NULL)
return 0;
if (((flags & PyBUF_WRITABLE) == PyBUF_WRITABLE) && (array->flags & SIP_READ_ONLY))
{
PyErr_SetString(PyExc_BufferError, "object is not writable.");
return -1;
}
view->obj = self;
Py_INCREF(self);
view->buf = array->data;
view->len = array->len;
view->readonly = (array->flags & SIP_READ_ONLY);
view->itemsize = array->stride;
view->format = NULL;
if ((flags & PyBUF_FORMAT) == PyBUF_FORMAT)
view->format = (char *)array->format;
view->ndim = 1;
view->shape = NULL;
if ((flags & PyBUF_ND) == PyBUF_ND)
view->shape = &view->len;
view->strides = NULL;
if ((flags & PyBUF_STRIDES) == PyBUF_STRIDES)
view->strides = &view->itemsize;
view->suboffsets = NULL;
view->internal = NULL;
return 0;
}
#endif
#if PY_MAJOR_VERSION < 3
/*
* The read buffer implementation for Python v2.
*/
static SIP_SSIZE_T sipArray_getreadbuffer(PyObject *self, SIP_SSIZE_T seg,
void **ptr)
{
sipArrayObject *array = (sipArrayObject *)self;
if (seg != 0)
{
PyErr_SetString(PyExc_SystemError, "invalid buffer segment");
return -1;
}
*ptr = array->data;
return array->len;
}
#endif
#if PY_MAJOR_VERSION < 3
/*
* The write buffer implementation for Python v2.
*/
static SIP_SSIZE_T sipArray_getwritebuffer(PyObject *self, SIP_SSIZE_T seg,
void **ptr)
{
if (check_writable((sipArrayObject *)self) < 0)
return -1;
return sipArray_getreadbuffer(self, seg, ptr);
}
#endif
#if PY_MAJOR_VERSION < 3
/*
* The segment count implementation for Python v2.
*/
static SIP_SSIZE_T sipArray_getsegcount(PyObject *self, SIP_SSIZE_T *lenp)
{
SIP_SSIZE_T segs, len;
len = ((sipArrayObject *)self)->len;
segs = (len < 0 ? 0 : 1);
if (lenp != NULL)
*lenp = len;
return segs;
}
#endif
/* The buffer methods data structure. */
static PyBufferProcs sipArray_BufferProcs = {
#if PY_MAJOR_VERSION >= 3
sipArray_getbuffer, /* bf_getbuffer */
0 /* bf_releasebuffer */
#else
sipArray_getreadbuffer, /* bf_getreadbuffer */
sipArray_getwritebuffer, /* bf_getwritebuffer */
sipArray_getsegcount, /* bf_getsegcount */
#if PY_VERSION_HEX >= 0x02050000
(charbufferproc)sipArray_getreadbuffer, /* bf_getcharbuffer */
#if PY_VERSION_HEX >= 0x02060300
sipArray_getbuffer, /* bf_getbuffer */
0 /* bf_releasebuffer */
#endif
#else
(getcharbufferproc)sipArray_getreadbuffer /* bf_getcharbuffer */
#endif
#endif
};
/* The instance deallocation function. */
static void sipArray_dealloc(PyObject *self)
{
sipArrayObject *array = (sipArrayObject *)self;
if (array->flags & SIP_OWNS_MEMORY)
sip_api_free(array->data);
else
Py_XDECREF(array->owner);
}
/* The type data structure. */
PyTypeObject sipArray_Type = {
PyVarObject_HEAD_INIT(NULL, 0)
"sip.array", /* tp_name */
sizeof (sipArrayObject), /* tp_basicsize */
0, /* tp_itemsize */
sipArray_dealloc, /* tp_dealloc */
0, /* tp_print */
0, /* tp_getattr */
0, /* tp_setattr */
0, /* tp_reserved (Python v3), tp_compare (Python v2) */
0, /* tp_repr */
0, /* tp_as_number */
&sipArray_SequenceMethods, /* tp_as_sequence */
#if PY_VERSION_HEX >= 0x02050000
&sipArray_MappingMethods, /* tp_as_mapping */
#else
0, /* tp_as_mapping */
#endif
0, /* tp_hash */
0, /* tp_call */
0, /* tp_str */
0, /* tp_getattro */
0, /* tp_setattro */
&sipArray_BufferProcs, /* tp_as_buffer */
#if defined(Py_TPFLAGS_HAVE_NEWBUFFER)
Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_NEWBUFFER, /* tp_flags */
#else
Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */
#endif
0, /* tp_doc */
0, /* tp_traverse */
0, /* tp_clear */
0, /* tp_richcompare */
0, /* tp_weaklistoffset */
0, /* tp_iter */
0, /* tp_iternext */
0, /* tp_methods */
0, /* tp_members */
0, /* tp_getset */
0, /* tp_base */
0, /* tp_dict */
0, /* tp_descr_get */
0, /* tp_descr_set */
0, /* tp_dictoffset */
0, /* tp_init */
0, /* tp_alloc */
0, /* tp_new */
0, /* tp_free */
0, /* tp_is_gc */
0, /* tp_bases */
0, /* tp_mro */
0, /* tp_cache */
0, /* tp_subclasses */
0, /* tp_weaklist */
0, /* tp_del */
#if PY_VERSION_HEX >= 0x02060000
0, /* tp_version_tag */
#endif
#if PY_VERSION_HEX >= 0x03040000
0, /* tp_finalize */
#endif
};
/*
* Check that an array is writable.
*/
static int check_writable(sipArrayObject *array)
{
if (array->flags & SIP_READ_ONLY)
{
PyErr_SetString(PyExc_TypeError, "sip.array object is read-only");
return -1;
}
return 0;
}
/*
* Check that an index is valid for an array.
*/
static int check_index(sipArrayObject *array, SIP_SSIZE_T idx)
{
if (idx >= 0 && idx < array->len)
return 0;
PyErr_SetString(PyExc_IndexError, "index out of bounds");
return -1;
}
#if PY_VERSION_HEX < 0x02050000
/*
* Fix the bounds of a slice in the same way that the Python buffer object
* does.
*/
static void fix_bounds(int len, int *left, int *right)
{
if (*left < 0)
*left = 0;
else if (*left > len)
*left = len;
if (*right < *left)
*right = *left;
else if (*right > len)
*right = len;
}
#endif
#if PY_VERSION_HEX >= 0x02050000
/*
* Raise an exception about a bad sub-script key.
*/
static void bad_key(PyObject *key)
{
PyErr_Format(PyExc_TypeError,
"cannot index a sip.array object using '%s'",
Py_TYPE(key)->tp_name);
}
#endif
/*
* Get the address of an element of an array.
*/
static void *element(sipArrayObject *array, SIP_SSIZE_T idx)
{
return (unsigned char *)(array->data) + idx * array->stride;
}
/*
* Get the address of a value that will be copied to an array.
*/
static void *get_value(sipArrayObject *array, PyObject *value)
{
static union {
signed char s_char_t;
unsigned char u_char_t;
signed short s_short_t;
unsigned short u_short_t;
signed int s_int_t;
unsigned int u_int_t;
float float_t;
double double_t;
} static_data;
void *data;
if (array->td != NULL)
{
int iserr = FALSE;
data = sip_api_force_convert_to_type(value, array->td, NULL,
SIP_NOT_NONE|SIP_NO_CONVERTORS, NULL, &iserr);
}
else
{
PyErr_Clear();
switch (*array->format)
{
case 'b':
static_data.s_char_t = (signed char)SIPLong_AsLong(value);
data = &static_data.s_char_t;
break;
case 'B':
static_data.u_char_t = (unsigned char)sip_api_long_as_unsigned_long(value);
data = &static_data.u_char_t;
break;
case 'h':
static_data.s_short_t = (signed short)SIPLong_AsLong(value);
data = &static_data.s_short_t;
break;
case 'H':
static_data.u_short_t = (unsigned short)sip_api_long_as_unsigned_long(value);
data = &static_data.u_short_t;
break;
case 'i':
static_data.s_int_t = SIPLong_AsLong(value);
data = &static_data.s_int_t;
break;
case 'I':
static_data.u_int_t = sip_api_long_as_unsigned_long(value);
data = &static_data.u_int_t;
break;
case 'f':
static_data.float_t = (float)PyFloat_AsDouble(value);
data = &static_data.float_t;
break;
case 'd':
static_data.double_t = PyFloat_AsDouble(value);
data = &static_data.double_t;
break;
default:
data = NULL;
}
if (PyErr_Occurred())
data = NULL;
}
return data;
}
/*
* Get the address of an value that will be copied to an array slice.
*/
static void *get_slice(sipArrayObject *array, PyObject *value, SIP_SSIZE_T len)
{
sipArrayObject *other = (sipArrayObject *)value;
if (!PyObject_IsInstance(value, (PyObject *)&sipArray_Type) || array->td != other->td || strcmp(array->format, other->format) != 0)
{
const char *type;
if (array->td != NULL)
{
type = sipTypeName(array->td);
}
else
{
switch (*array->format)
{
case 'b':
type = "char";
break;
case 'B':
type = "unsigned char";
break;
case 'h':
type = "short";
break;
case 'H':
type = "unsigned short";
break;
case 'i':
type = "int";
break;
case 'I':
type = "unsigned int";
break;
case 'f':
type = "float";
break;
case 'd':
type = "double";
break;
default:
type = "";
}
}
PyErr_Format(PyExc_TypeError,
"can only assign another array of %s to the slice", type);
return NULL;
}
if (other->len != len)
{
PyErr_Format(PyExc_TypeError,
"the array being assigned must have length " SIP_SSIZE_T_FORMAT,
len);
return NULL;
}
if (other->stride == array->stride)
{
PyErr_Format(PyExc_TypeError,
#if PY_VERSION_HEX >= 0x02050000
"the array being assigned must have stride %zu",
array->stride);
#else
"the array being assigned must have stride %ld",
(unsigned long)array->stride);
#endif
return NULL;
}
return other->data;
}
/*
* Do the work of creating an array.
*/
static PyObject *make_array(void *data, const sipTypeDef *td,
const char *format, size_t stride, SIP_SSIZE_T len, int flags,
PyObject *owner)
{
sipArrayObject *array;
if ((array = PyObject_NEW(sipArrayObject, &sipArray_Type)) == NULL)
return NULL;
array->data = data;
array->td = td;
array->format = format;
array->stride = stride;
array->len = len;
array->flags = flags;
if (flags & SIP_OWNS_MEMORY)
{
/* This is a borrowed reference to itself. */
array->owner = (PyObject *)array;
}
else
{
Py_XINCREF(owner);
array->owner = owner;
}
return (PyObject *)array;
}
/*
* Wrap an array of instances of a fundamental type. At the moment format must
* be either "b" (char), "B" (unsigned char), "h" (short), "H" (unsigned
* short), "i" (int), "I" (unsigned int), "f" (float) or "d" (double).
*/
PyObject *sip_api_convert_to_array(void *data, const char *format,
SIP_SSIZE_T len, int flags)
{
size_t stride;
if (data == NULL)
{
Py_INCREF(Py_None);
return Py_None;
}
switch (*format)
{
case 'b':
stride = sizeof (char);
break;
case 'B':
stride = sizeof (unsigned char);
break;
case 'h':
stride = sizeof (short);
break;
case 'H':
stride = sizeof (unsigned short);
break;
case 'i':
stride = sizeof (int);
break;
case 'I':
stride = sizeof (unsigned int);
break;
case 'f':
stride = sizeof (float);
break;
case 'd':
stride = sizeof (double);
break;
default:
stride = 0;
}
assert(stride > 0);
assert(len >= 0);
return make_array(data, NULL, format, stride, len, flags, NULL);
}
/*
* Wrap an array of instances of a defined type.
*/
PyObject *sip_api_convert_to_typed_array(void *data, const sipTypeDef *td,
const char *format, size_t stride, SIP_SSIZE_T len, int flags)
{
if (data == NULL)
{
Py_INCREF(Py_None);
return Py_None;
}
assert(stride > 0);
assert(len >= 0);
return make_array(data, td, format, stride, len, flags, NULL);
}

46
sip/siplib/array.h Normal file
View File

@@ -0,0 +1,46 @@
/*
* This file defines the API for the array type.
*
* Copyright (c) 2015 Riverbank Computing Limited <info@riverbankcomputing.com>
*
* This file is part of SIP.
*
* This copy of SIP is licensed for use under the terms of the SIP License
* Agreement. See the file LICENSE for more details.
*
* This copy of SIP may also used under the terms of the GNU General Public
* License v2 or v3 as published by the Free Software Foundation which can be
* found in the files LICENSE-GPL2 and LICENSE-GPL3 included in this package.
*
* SIP is supplied WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
*/
#ifndef _ARRAY_H
#define _ARRAY_H
#include <Python.h>
#include "sip.h"
#ifdef __cplusplus
extern "C" {
#endif
extern PyTypeObject sipArray_Type;
PyObject *sip_api_convert_to_array(void *data, const char *format,
SIP_SSIZE_T len, int flags);
PyObject *sip_api_convert_to_typed_array(void *data, const sipTypeDef *td,
const char *format, size_t stride, SIP_SSIZE_T len, int flags);
#ifdef __cplusplus
}
#endif
#endif

View File

@@ -1,6 +1,6 @@
// This contains all the C++ code that is needed by the sip module.
//
// Copyright (c) 2013 Riverbank Computing Limited <info@riverbankcomputing.com>
// Copyright (c) 2015 Riverbank Computing Limited <info@riverbankcomputing.com>
//
// This file is part of SIP.
//
@@ -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<bool *>(ptr) = val;
*reinterpret_cast<bool *>(ptr) = !!val;
}

View File

@@ -1,7 +1,7 @@
/*
* The implementation of the different descriptors.
*
* Copyright (c) 2013 Riverbank Computing Limited <info@riverbankcomputing.com>
* Copyright (c) 2015 Riverbank Computing Limited <info@riverbankcomputing.com>
*
* This file is part of SIP.
*
@@ -25,7 +25,8 @@
/*****************************************************************************
* A method descriptor. We don't use the similar Python descriptor because it
* doesn't support a method having static and non-static overloads.
* doesn't support a method having static and non-static overloads, and we
* handle mixins via a delegate.
*****************************************************************************/
@@ -33,6 +34,9 @@
static PyObject *sipMethodDescr_descr_get(PyObject *self, PyObject *obj,
PyObject *type);
static PyObject *sipMethodDescr_repr(PyObject *self);
static int sipMethodDescr_traverse(PyObject *self, visitproc visit, void *arg);
static int sipMethodDescr_clear(PyObject *self);
static void sipMethodDescr_dealloc(PyObject *self);
/*
@@ -43,6 +47,9 @@ typedef struct _sipMethodDescr {
/* The method definition. */
PyMethodDef *pmd;
/* The mixin name, if any. */
PyObject *mixin_name;
} sipMethodDescr;
@@ -54,7 +61,7 @@ PyTypeObject sipMethodDescr_Type = {
"sip.methoddescriptor", /* tp_name */
sizeof (sipMethodDescr), /* tp_basicsize */
0, /* tp_itemsize */
0, /* tp_dealloc */
sipMethodDescr_dealloc, /* tp_dealloc */
0, /* tp_print */
0, /* tp_getattr */
0, /* tp_setattr */
@@ -69,10 +76,10 @@ PyTypeObject sipMethodDescr_Type = {
0, /* tp_getattro */
0, /* tp_setattro */
0, /* tp_as_buffer */
Py_TPFLAGS_DEFAULT, /* tp_flags */
Py_TPFLAGS_DEFAULT|Py_TPFLAGS_HAVE_GC, /* tp_flags */
0, /* tp_doc */
0, /* tp_traverse */
0, /* tp_clear */
sipMethodDescr_traverse,/* tp_traverse */
sipMethodDescr_clear, /* tp_clear */
0, /* tp_richcompare */
0, /* tp_weaklistoffset */
0, /* tp_iter */
@@ -83,6 +90,25 @@ PyTypeObject sipMethodDescr_Type = {
0, /* tp_base */
0, /* tp_dict */
sipMethodDescr_descr_get, /* tp_descr_get */
0, /* tp_descr_set */
0, /* tp_dictoffset */
0, /* tp_init */
0, /* tp_alloc */
0, /* tp_new */
0, /* tp_free */
0, /* tp_is_gc */
0, /* tp_bases */
0, /* tp_mro */
0, /* tp_cache */
0, /* tp_subclasses */
0, /* tp_weaklist */
0, /* tp_del */
#if PY_VERSION_HEX >= 0x02060000
0, /* tp_version_tag */
#endif
#if PY_VERSION_HEX >= 0x03040000
0, /* tp_finalize */
#endif
};
@@ -94,7 +120,28 @@ PyObject *sipMethodDescr_New(PyMethodDef *pmd)
PyObject *descr = PyType_GenericAlloc(&sipMethodDescr_Type, 0);
if (descr != NULL)
{
((sipMethodDescr *)descr)->pmd = pmd;
((sipMethodDescr *)descr)->mixin_name = NULL;
}
return descr;
}
/*
* Return a new method descriptor based on an existing one and a mixin name.
*/
PyObject *sipMethodDescr_Copy(PyObject *orig, PyObject *mixin_name)
{
PyObject *descr = PyType_GenericAlloc(&sipMethodDescr_Type, 0);
if (descr != NULL)
{
((sipMethodDescr *)descr)->pmd = ((sipMethodDescr *)orig)->pmd;
((sipMethodDescr *)descr)->mixin_name = mixin_name;
Py_INCREF(mixin_name);
}
return descr;
}
@@ -108,8 +155,12 @@ static PyObject *sipMethodDescr_descr_get(PyObject *self, PyObject *obj,
{
sipMethodDescr *md = (sipMethodDescr *)self;
(void)type;
if (obj == Py_None)
obj = NULL;
else if (md->mixin_name != NULL)
obj = PyObject_GetAttr(obj, md->mixin_name);
return PyCFunction_New(md->pmd, obj);
}
@@ -133,6 +184,47 @@ static PyObject *sipMethodDescr_repr(PyObject *self)
}
/*
* The descriptor's traverse slot.
*/
static int sipMethodDescr_traverse(PyObject *self, visitproc visit, void *arg)
{
if (((sipMethodDescr *)self)->mixin_name != NULL)
{
int vret = visit(((sipMethodDescr *)self)->mixin_name, arg);
if (vret != 0)
return vret;
}
return 0;
}
/*
* The descriptor's clear slot.
*/
static int sipMethodDescr_clear(PyObject *self)
{
PyObject *tmp = ((sipMethodDescr *)self)->mixin_name;
((sipMethodDescr *)self)->mixin_name = NULL;
Py_XDECREF(tmp);
return 0;
}
/*
* The descriptor's dealloc slot.
*/
static void sipMethodDescr_dealloc(PyObject *self)
{
sipMethodDescr_clear(self);
Py_TYPE(self)->tp_free(self);
}
/*****************************************************************************
* A variable descriptor. We don't use the similar Python descriptor because
* it doesn't support static variables.
@@ -144,6 +236,10 @@ static PyObject *sipVariableDescr_descr_get(PyObject *self, PyObject *obj,
PyObject *type);
static int sipVariableDescr_descr_set(PyObject *self, PyObject *obj,
PyObject *value);
static int sipVariableDescr_traverse(PyObject *self, visitproc visit,
void *arg);
static int sipVariableDescr_clear(PyObject *self);
static void sipVariableDescr_dealloc(PyObject *self);
/*
@@ -160,6 +256,9 @@ typedef struct _sipVariableDescr {
/* The generated container definition. */
const sipContainerDef *cod;
/* The mixin name, if any. */
PyObject *mixin_name;
} sipVariableDescr;
@@ -171,7 +270,7 @@ PyTypeObject sipVariableDescr_Type = {
"sip.variabledescriptor", /* tp_name */
sizeof (sipVariableDescr), /* tp_basicsize */
0, /* tp_itemsize */
0, /* tp_dealloc */
sipVariableDescr_dealloc, /* tp_dealloc */
0, /* tp_print */
0, /* tp_getattr */
0, /* tp_setattr */
@@ -186,10 +285,10 @@ PyTypeObject sipVariableDescr_Type = {
0, /* tp_getattro */
0, /* tp_setattro */
0, /* tp_as_buffer */
Py_TPFLAGS_DEFAULT, /* tp_flags */
Py_TPFLAGS_DEFAULT|Py_TPFLAGS_HAVE_GC, /* tp_flags */
0, /* tp_doc */
0, /* tp_traverse */
0, /* tp_clear */
sipVariableDescr_traverse, /* tp_traverse */
sipVariableDescr_clear, /* tp_clear */
0, /* tp_richcompare */
0, /* tp_weaklistoffset */
0, /* tp_iter */
@@ -201,6 +300,24 @@ PyTypeObject sipVariableDescr_Type = {
0, /* tp_dict */
sipVariableDescr_descr_get, /* tp_descr_get */
sipVariableDescr_descr_set, /* tp_descr_set */
0, /* tp_dictoffset */
0, /* tp_init */
0, /* tp_alloc */
0, /* tp_new */
0, /* tp_free */
0, /* tp_is_gc */
0, /* tp_bases */
0, /* tp_mro */
0, /* tp_cache */
0, /* tp_subclasses */
0, /* tp_weaklist */
0, /* tp_del */
#if PY_VERSION_HEX >= 0x02060000
0, /* tp_version_tag */
#endif
#if PY_VERSION_HEX >= 0x03040000
0, /* tp_finalize */
#endif
};
@@ -222,6 +339,27 @@ PyObject *sipVariableDescr_New(sipVariableDef *vd, const sipTypeDef *td,
((sipVariableDescr *)descr)->vd = vd;
((sipVariableDescr *)descr)->td = td;
((sipVariableDescr *)descr)->cod = cod;
((sipVariableDescr *)descr)->mixin_name = NULL;
}
return descr;
}
/*
* Return a new variable descriptor based on an existing one and a mixin name.
*/
PyObject *sipVariableDescr_Copy(PyObject *orig, PyObject *mixin_name)
{
PyObject *descr = PyType_GenericAlloc(&sipVariableDescr_Type, 0);
if (descr != NULL)
{
((sipVariableDescr *)descr)->vd = ((sipVariableDescr *)orig)->vd;
((sipVariableDescr *)descr)->td = ((sipVariableDescr *)orig)->td;
((sipVariableDescr *)descr)->cod = ((sipVariableDescr *)orig)->cod;
((sipVariableDescr *)descr)->mixin_name = mixin_name;
Py_INCREF(mixin_name);
}
return descr;
@@ -294,6 +432,9 @@ static int get_instance_address(sipVariableDescr *vd, PyObject *obj,
return -1;
}
if (vd->mixin_name != NULL)
obj = PyObject_GetAttr(obj, vd->mixin_name);
/* Get the C++ instance. */
if ((addr = sip_api_get_cpp_ptr((sipSimpleWrapper *)obj, vd->td)) == NULL)
return -1;
@@ -303,3 +444,44 @@ static int get_instance_address(sipVariableDescr *vd, PyObject *obj,
return 0;
}
/*
* The descriptor's traverse slot.
*/
static int sipVariableDescr_traverse(PyObject *self, visitproc visit, void *arg)
{
if (((sipVariableDescr *)self)->mixin_name != NULL)
{
int vret = visit(((sipVariableDescr *)self)->mixin_name, arg);
if (vret != 0)
return vret;
}
return 0;
}
/*
* The descriptor's clear slot.
*/
static int sipVariableDescr_clear(PyObject *self)
{
PyObject *tmp = ((sipVariableDescr *)self)->mixin_name;
((sipVariableDescr *)self)->mixin_name = NULL;
Py_XDECREF(tmp);
return 0;
}
/*
* The descriptor's dealloc slot.
*/
static void sipVariableDescr_dealloc(PyObject *self)
{
sipVariableDescr_clear(self);
Py_TYPE(self)->tp_free(self);
}

View File

@@ -2,7 +2,7 @@
* This module implements a hash table class for mapping C/C++ addresses to the
* corresponding wrapped Python object.
*
* Copyright (c) 2013 Riverbank Computing Limited <info@riverbankcomputing.com>
* Copyright (c) 2015 Riverbank Computing Limited <info@riverbankcomputing.com>
*
* This file is part of SIP.
*
@@ -197,7 +197,7 @@ static void add_aliases(sipObjectMap *om, void *addr, sipSimpleWrapper *val,
/* Recurse up the hierachy for the remaining super-classes. */
add_aliases(om, addr, val, base_ctd, sup_ctd);
sup_addr = (*base_ctd->ctd_cast)(addr, sup_ctd);
sup_addr = (*base_ctd->ctd_cast)(addr, (sipTypeDef *)sup_ctd);
if (sup_addr != addr)
{
@@ -403,7 +403,7 @@ static void remove_aliases(sipObjectMap *om, void *addr, sipSimpleWrapper *val,
/* Recurse up the hierachy for the remaining super-classes. */
remove_aliases(om, addr, val, base_ctd, sup_ctd);
sup_addr = (*base_ctd->ctd_cast)(addr, sup_ctd);
sup_addr = (*base_ctd->ctd_cast)(addr, (sipTypeDef *)sup_ctd);
if (sup_addr != addr)
remove_object(om, sup_addr, val);

View File

@@ -2,7 +2,7 @@
* The SIP library code that implements the interface to the optional module
* supplied Qt support.
*
* Copyright (c) 2013 Riverbank Computing Limited <info@riverbankcomputing.com>
* Copyright (c) 2015 Riverbank Computing Limited <info@riverbankcomputing.com>
*
* This file is part of SIP.
*
@@ -87,9 +87,21 @@ static void *createUniversalSlot(sipWrapper *txSelf, const char *sig,
/*
* Invoke a single slot (Qt or Python) and return the result.
* Invoke a single slot (Qt or Python) and return the result. Don't check if
* any receiver C++ object still exists.
*/
PyObject *sip_api_invoke_slot(const sipSlot *slot, PyObject *sigargs)
{
return sip_api_invoke_slot_ex(slot, sigargs, TRUE);
}
/*
* Invoke a single slot (Qt or Python) and return the result. Optionally check
* that any receiver C++ object still exist.
*/
PyObject *sip_api_invoke_slot_ex(const sipSlot *slot, PyObject *sigargs,
int no_receiver_check)
{
PyObject *sa, *oxtype, *oxvalue, *oxtb, *sfunc, *sref;
@@ -145,11 +157,18 @@ PyObject *sip_api_invoke_slot(const sipSlot *slot, PyObject *sigargs)
PyObject *self = (sref != NULL ? sref : slot->meth.mself);
/*
* 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 the receiver wraps a C++ object then ignore the call if it no
* longer exists.
*/
if (!no_receiver_check &&
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);

View File

@@ -1,7 +1,7 @@
/*
* The SIP module interface.
*
* Copyright (c) 2013 Riverbank Computing Limited <info@riverbankcomputing.com>
* Copyright (c) 2015 Riverbank Computing Limited <info@riverbankcomputing.com>
*
* This file is part of SIP.
*
@@ -54,8 +54,8 @@ extern "C" {
/*
* Define the SIP version number.
*/
#define SIP_VERSION 0x040e07
#define SIP_VERSION_STR "4.14.7"
#define SIP_VERSION 0x041007
#define SIP_VERSION_STR "4.16.7-snapshot-f652446e2462"
/*
@@ -68,6 +68,22 @@ extern "C" {
*
* History:
*
* 11.1 Added sip_api_invoke_slot_ex().
*
* 11.0 Added the pyqt5QtSignal and pyqt5ClassTypeDef structures.
* Removed qt_interface from pyqt4ClassTypeDef.
* Added hack to pyqt4QtSignal.
*
* 10.1 Added ctd_final to sipClassTypeDef.
* Added ctd_init_mixin to sipClassTypeDef.
* Added sip_api_get_mixin_address() to the public API.
* Added sip_api_convert_from_new_pytype() to the public API.
* Added sip_api_convert_to_array() to the public API.
* Added sip_api_convert_to_typed_array() to the public API.
* Added sip_api_register_proxy_resolver() to the public API.
* Added sip_api_init_mixin() to the private API.
* Added qt_interface to pyqt4ClassTypeDef.
*
* 10.0 Added sip_api_set_destroy_on_exit().
* Added sip_api_enable_autoconversion().
* Removed sip_api_call_error_handler_old().
@@ -195,8 +211,8 @@ extern "C" {
*
* 0.0 Original version.
*/
#define SIP_API_MAJOR_NR 10
#define SIP_API_MINOR_NR 0
#define SIP_API_MAJOR_NR 11
#define SIP_API_MINOR_NR 1
/* The name of the sip module. */
@@ -217,6 +233,7 @@ typedef unsigned int uint;
#if PY_VERSION_HEX >= 0x02050000
#define SIP_SSIZE_T Py_ssize_t
#define SIP_SSIZE_T_FORMAT "%zd"
#define SIP_MLNAME_CAST(s) (s)
#define SIP_MLDOC_CAST(s) (s)
@@ -225,6 +242,7 @@ typedef unsigned int uint;
#else
#define SIP_SSIZE_T int
#define SIP_SSIZE_T_FORMAT "%d"
#define SIP_MLNAME_CAST(s) ((char *)(s))
#define SIP_MLDOC_CAST(s) ((char *)(s))
@@ -338,6 +356,7 @@ struct _sipTypeDef;
typedef void *(*sipInitFunc)(struct _sipSimpleWrapper *, PyObject *,
PyObject *, PyObject **, PyObject **, PyObject **);
typedef int (*sipFinalFunc)(PyObject *, void *, PyObject *, PyObject **);
typedef void *(*sipAccessFunc)(struct _sipSimpleWrapper *, AccessFuncOp);
typedef int (*sipTraverseFunc)(void *, visitproc, void *);
typedef int (*sipClearFunc)(void *);
@@ -365,6 +384,7 @@ typedef PyObject *(*sipPickleFunc)(void *);
typedef int (*sipAttrGetterFunc)(const struct _sipTypeDef *, PyObject *);
typedef PyObject *(*sipVariableGetterFunc)(void *, PyObject *, PyObject *);
typedef int (*sipVariableSetterFunc)(void *, PyObject *, PyObject *);
typedef void *(*sipProxyResolverFunc)(void *);
/*
@@ -415,6 +435,9 @@ typedef struct _sipSimpleWrapper {
/* The instance dictionary. */
PyObject *dict;
/* The main instance if this is a mixin. */
PyObject *mixin_main;
/* Next object at this address. */
struct _sipSimpleWrapper *next;
} sipSimpleWrapper;
@@ -853,7 +876,7 @@ typedef struct _sipClassTypeDef {
/* The optional copy function. */
sipCopyFunc ctd_copy;
/* The release function, 0 if a C strict. */
/* The release function, 0 if a C struct. */
sipReleaseFunc ctd_release;
/* The cast function, 0 if a C struct. */
@@ -870,6 +893,12 @@ typedef struct _sipClassTypeDef {
/* The pickle function. */
sipPickleFunc ctd_pickle;
/* The finalisation function. */
sipFinalFunc ctd_final;
/* The mixin initialisation function. */
initproc ctd_init_mixin;
} sipClassTypeDef;
@@ -1471,6 +1500,28 @@ typedef struct _sipAPIDef {
const char *fmt, ...);
void (*api_call_error_handler)(sipVirtErrorHandlerFunc,
sipSimpleWrapper *, sip_gilstate_t);
int (*api_init_mixin)(PyObject *self, PyObject *args, PyObject *kwds,
const sipClassTypeDef *ctd);
/*
* The following are part of the public API.
*/
void *(*api_get_mixin_address)(struct _sipSimpleWrapper *w,
const sipTypeDef *td);
PyObject *(*api_convert_from_new_pytype)(void *cpp, PyTypeObject *py_type,
sipWrapper *owner, sipSimpleWrapper **selfp, const char *fmt, ...);
PyObject *(*api_convert_to_typed_array)(void *data, const sipTypeDef *td,
const char *format, size_t stride, SIP_SSIZE_T len, int flags);
PyObject *(*api_convert_to_array)(void *data, const char *format,
SIP_SSIZE_T len, int flags);
int (*api_register_proxy_resolver)(const sipTypeDef *td,
sipProxyResolverFunc resolver);
/*
* The following may be used by Qt support code but no other handwritten
* code.
*/
PyObject *(*api_invoke_slot_ex)(const sipSlot *slot, PyObject *sigargs,
int check_receiver);
} sipAPIDef;
@@ -1506,6 +1557,13 @@ typedef struct _sipQtAPI {
#define SIP_NO_CONVERTORS 0x02 /* Disable any type convertors. */
/*
* These are flags that can be passed to sipConvertToArray().
*/
#define SIP_READ_ONLY 0x01 /* The array is read-only. */
#define SIP_OWNS_MEMORY 0x02 /* The array owns its memory. */
/*
* These are the state flags returned by %ConvertToTypeCode. Note that these
* share the same "namespace" as the flags below.
@@ -1560,6 +1618,7 @@ typedef struct _sipQtAPI {
#define SIP_TYPE_ALLOW_NONE 0x0020 /* If the type can handle None. */
#define SIP_TYPE_STUB 0x0040 /* If the type is a stub. */
#define SIP_TYPE_NONLAZY 0x0080 /* If the type has a non-lazy method. */
#define SIP_TYPE_SUPER_INIT 0x0100 /* If the instance's super init should be called. */
/*
@@ -1598,6 +1657,7 @@ typedef struct _sipQtAPI {
#define sipTypeIsStub(td) ((td)->td_flags & SIP_TYPE_STUB)
#define sipTypeSetStub(td) ((td)->td_flags |= SIP_TYPE_STUB)
#define sipTypeHasNonlazyMethod(td) ((td)->td_flags & SIP_TYPE_NONLAZY)
#define sipTypeCallSuperInit(td) ((td)->td_flags & SIP_TYPE_SUPER_INIT)
/*
* Get various names from the string pool for various data types.
@@ -1613,12 +1673,12 @@ typedef struct _sipQtAPI {
* out to a plugin supplied by PyQt3.
*/
typedef int (*pyqt3EmitFunc)(sipSimpleWrapper *, PyObject *);
/*
* Maps the name of a Qt signal to a wrapper function to emit it.
*/
typedef int (*pyqt3EmitFunc)(sipSimpleWrapper *, PyObject *);
typedef struct _pyqt3QtSignal {
/* The signal name. */
const char *st_name;
@@ -1663,6 +1723,16 @@ typedef struct _pyqt4QtSignal {
* code that implements those methods.
*/
PyMethodDef *non_signals;
/*
* The hack to apply when built against Qt5:
*
* 0 - no hack
* 1 - add an optional None
* 2 - add an optional []
* 3 - add an optional False
*/
int hack;
} pyqt4QtSignal;
@@ -1677,22 +1747,83 @@ typedef struct _pyqt4ClassTypeDef {
sipClassTypeDef super;
/* A pointer to the QObject sub-class's staticMetaObject class variable. */
const void *qt4_static_metaobject;
const void *static_metaobject;
/*
* A set of flags. At the moment only bit 0 is used to say if the type is
* derived from QFlags.
*/
unsigned qt4_flags;
unsigned flags;
/*
* The table of signals emitted by the type. These are grouped by signal
* name.
*/
const pyqt4QtSignal *qt4_signals;
const pyqt4QtSignal *qt_signals;
} pyqt4ClassTypeDef;
/*
* The following are PyQt5-specific extensions. In SIP v5 they will be pushed
* out to a plugin supplied by PyQt5.
*/
/*
* The description of a Qt signal for PyQt5.
*/
typedef int (*pyqt5EmitFunc)(void *, PyObject *);
typedef struct _pyqt5QtSignal {
/* The normalised C++ name and signature of the signal. */
const char *signature;
/* The optional docstring. */
const char *docstring;
/*
* If the signal is an overload of regular methods then this points to the
* code that implements those methods.
*/
PyMethodDef *non_signals;
/*
* If the signal has optional arguments then this function will implement
* emit() for the signal.
*/
pyqt5EmitFunc emitter;
} pyqt5QtSignal;
/*
* This is the PyQt5-specific extension to the generated class type structure.
*/
typedef struct _pyqt5ClassTypeDef {
/*
* The super-type structure. This must be first in the structure so that
* it can be cast to sipClassTypeDef *.
*/
sipClassTypeDef super;
/* A pointer to the QObject sub-class's staticMetaObject class variable. */
const void *static_metaobject;
/*
* A set of flags. At the moment only bit 0 is used to say if the type is
* derived from QFlags.
*/
unsigned flags;
/*
* The table of signals emitted by the type. These are grouped by signal
* name.
*/
const pyqt5QtSignal *qt_signals;
/* The name of the interface that the class defines. */
const char *qt_interface;
} pyqt5ClassTypeDef;
#ifdef __cplusplus
}
#endif

View File

@@ -1,7 +1,7 @@
/*
* This file defines the SIP library internal interfaces.
*
* Copyright (c) 2013 Riverbank Computing Limited <info@riverbankcomputing.com>
* Copyright (c) 2015 Riverbank Computing Limited <info@riverbankcomputing.com>
*
* This file is part of SIP.
*
@@ -61,10 +61,12 @@ typedef struct
*/
extern PyTypeObject sipMethodDescr_Type;
PyObject *sipMethodDescr_New(PyMethodDef *pmd);
PyObject *sipMethodDescr_Copy(PyObject *orig, PyObject *mixin_name);
extern PyTypeObject sipVariableDescr_Type;
PyObject *sipVariableDescr_New(sipVariableDef *vd, const sipTypeDef *td,
const sipContainerDef *cod);
PyObject *sipVariableDescr_Copy(PyObject *orig, PyObject *mixin_name);
/*
@@ -112,9 +114,14 @@ PyObject *sip_api_convert_from_type(void *cppPtr, const sipTypeDef *td,
PyObject *transferObj);
void sip_api_common_dtor(sipSimpleWrapper *sipSelf);
void sip_api_end_thread(void);
void *sip_api_force_convert_to_type(PyObject *pyObj, const sipTypeDef *td,
PyObject *transferObj, int flags, int *statep, int *iserrp);
void sip_api_free_sipslot(sipSlot *slot);
unsigned long sip_api_long_as_unsigned_long(PyObject *o);
int sip_api_same_slot(const sipSlot *sp, PyObject *rxObj, const char *slot);
PyObject *sip_api_invoke_slot(const sipSlot *slot, PyObject *sigargs);
PyObject *sip_api_invoke_slot_ex(const sipSlot *slot, PyObject *sigargs,
int no_receiver_check);
void *sip_api_convert_rx(sipWrapper *txSelf, const char *sigargs,
PyObject *rxObj, const char *slot, const char **memberp, int flags);
int sip_api_save_slot(sipSlot *sp, PyObject *rxObj, const char *slot);
@@ -123,13 +130,13 @@ int sip_api_save_slot(sipSlot *sp, PyObject *rxObj, const char *slot);
/*
* These are not part of the SIP API but are used within the SIP module.
*/
sipClassTypeDef *sipGetGeneratedClassType(sipEncodedTypeDef *enc,
sipClassTypeDef *sipGetGeneratedClassType(const sipEncodedTypeDef *enc,
const sipClassTypeDef *ctd);
void sipSaveMethod(sipPyMethod *pm,PyObject *meth);
int sipGetPending(void **pp, sipWrapper **op, int *fp);
int sipIsPending();
PyObject *sipWrapSimpleInstance(void *cppPtr, const sipTypeDef *td,
sipWrapper *owner, int initflags);
PyObject *sipWrapInstance(void *cpp, PyTypeObject *py_type, PyObject *args,
sipWrapper *owner, int flags);
void *sipConvertRxEx(sipWrapper *txSelf, const char *sigargs,
PyObject *rxObj, const char *slot, const char **memberp, int flags);

File diff suppressed because it is too large Load Diff

View File

@@ -3,7 +3,7 @@
* C++ classes that provide a thread interface to interact properly with the
* Python threading infrastructure.
*
* Copyright (c) 2013 Riverbank Computing Limited <info@riverbankcomputing.com>
* Copyright (c) 2015 Riverbank Computing Limited <info@riverbankcomputing.com>
*
* This file is part of SIP.
*
@@ -71,6 +71,9 @@ int sipGetPending(void **pp, sipWrapper **op, int *fp)
*op = pd->owner;
*fp = pd->flags;
/* Clear in case we execute Python code before finishing this wrapping. */
pd->cpp = NULL;
return 0;
}
@@ -92,18 +95,13 @@ int sipIsPending()
/*
* Convert a new C/C++ pointer to a Python instance.
*/
PyObject *sipWrapSimpleInstance(void *cppPtr, const sipTypeDef *td,
PyObject *sipWrapInstance(void *cpp, PyTypeObject *py_type, PyObject *args,
sipWrapper *owner, int flags)
{
static PyObject *nullargs = NULL;
pendingDef old_pending, *pd;
PyObject *self;
if (nullargs == NULL && (nullargs = PyTuple_New(0)) == NULL)
return NULL;
if (cppPtr == NULL)
if (cpp == NULL)
{
Py_INCREF(Py_None);
return Py_None;
@@ -120,11 +118,11 @@ PyObject *sipWrapSimpleInstance(void *cppPtr, const sipTypeDef *td,
old_pending = *pd;
pd->cpp = cppPtr;
pd->cpp = cpp;
pd->owner = owner;
pd->flags = flags;
self = PyObject_Call((PyObject *)sipTypeAsPyTypeObject(td), nullargs, NULL);
self = PyObject_Call((PyObject *)py_type, args, NULL);
*pd = old_pending;

View File

@@ -1,7 +1,7 @@
/*
* SIP library code.
*
* Copyright (c) 2013 Riverbank Computing Limited <info@riverbankcomputing.com>
* Copyright (c) 2015 Riverbank Computing Limited <info@riverbankcomputing.com>
*
* This file is part of SIP.
*
@@ -24,6 +24,7 @@
#include "sip.h"
#include "sipint.h"
#include "array.h"
/* The object data structure. */
@@ -58,6 +59,7 @@ static void bad_key(PyObject *key);
static int check_slice_size(SIP_SSIZE_T size, SIP_SSIZE_T value_size);
static PyObject *make_voidptr(void *voidptr, SIP_SSIZE_T size, int rw);
static int vp_convertor(PyObject *arg, struct vp_values *vp);
static SIP_SSIZE_T get_size_from_arg(sipVoidPtrObject *v, SIP_SSIZE_T size);
#if defined(SIP_USE_PYCAPSULE)
@@ -66,6 +68,8 @@ static int vp_convertor(PyObject *arg, struct vp_values *vp);
*/
static PyObject *sipVoidPtr_ascapsule(sipVoidPtrObject *v, PyObject *arg)
{
(void)arg;
return PyCapsule_New(v->voidptr, NULL, NULL);
}
#endif
@@ -77,11 +81,40 @@ static PyObject *sipVoidPtr_ascapsule(sipVoidPtrObject *v, PyObject *arg)
*/
static PyObject *sipVoidPtr_ascobject(sipVoidPtrObject *v, PyObject *arg)
{
(void)arg;
return PyCObject_FromVoidPtr(v->voidptr, NULL);
}
#endif
/*
* Implement asarray() for the type.
*/
static PyObject *sipVoidPtr_asarray(sipVoidPtrObject *v, PyObject *args,
PyObject *kw)
{
static char *kwlist[] = {"size", NULL};
SIP_SSIZE_T size = -1;
if (!PyArg_ParseTupleAndKeywords(args, kw,
#if PY_VERSION_HEX >= 0x02050000
"|n:asarray",
#else
"|i:asarray",
#endif
kwlist, &size))
return NULL;
if ((size = get_size_from_arg(v, size)) < 0)
return NULL;
return sip_api_convert_to_array(v->voidptr, "B", size,
(v->rw ? 0 : SIP_READ_ONLY));
}
/*
* Implement asstring() for the type.
*/
@@ -101,16 +134,8 @@ static PyObject *sipVoidPtr_asstring(sipVoidPtrObject *v, PyObject *args,
kwlist, &size))
return NULL;
/* Use the current size if one wasn't explicitly given. */
if (size < 0)
size = v->size;
if (size < 0)
{
PyErr_SetString(PyExc_ValueError,
"a size must be given or the sip.voidptr object must have a size");
if ((size = get_size_from_arg(v, size)) < 0)
return NULL;
}
return SIPBytes_FromStringAndSize(v->voidptr, size);
}
@@ -121,6 +146,8 @@ static PyObject *sipVoidPtr_asstring(sipVoidPtrObject *v, PyObject *args,
*/
static PyObject *sipVoidPtr_getsize(sipVoidPtrObject *v, PyObject *arg)
{
(void)arg;
#if PY_MAJOR_VERSION >= 3
return PyLong_FromSsize_t(v->size);
#elif PY_VERSION_HEX >= 0x02050000
@@ -161,6 +188,8 @@ static PyObject *sipVoidPtr_setsize(sipVoidPtrObject *v, PyObject *arg)
*/
static PyObject *sipVoidPtr_getwriteable(sipVoidPtrObject *v, PyObject *arg)
{
(void)arg;
return PyBool_FromLong(v->rw);
}
@@ -186,21 +215,31 @@ static PyObject *sipVoidPtr_setwriteable(sipVoidPtrObject *v, PyObject *arg)
/* The methods data structure. */
static PyMethodDef sipVoidPtr_Methods[] = {
{"asarray", (PyCFunction)sipVoidPtr_asarray, METH_VARARGS|METH_KEYWORDS, NULL},
#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},
#endif
{"asstring", (PyCFunction)sipVoidPtr_asstring, METH_KEYWORDS, NULL},
{"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},
{"setwriteable", (PyCFunction)sipVoidPtr_setwriteable, METH_O, NULL},
{NULL}
{NULL, NULL, 0, NULL}
};
/*
* Implement bool() for the type.
*/
static int sipVoidPtr_bool(PyObject *self)
{
return (((sipVoidPtrObject *)self)->voidptr != NULL);
}
/*
* Implement int() for the type.
*/
@@ -240,7 +279,7 @@ static PyNumberMethods sipVoidPtr_NumberMethods = {
0, /* nb_negative */
0, /* nb_positive */
0, /* nb_absolute */
0, /* nb_bool (Python v3), nb_nonzero (Python v2) */
sipVoidPtr_bool, /* nb_bool (Python v3), nb_nonzero (Python v2) */
0, /* nb_invert */
0, /* nb_lshift */
0, /* nb_rshift */
@@ -391,11 +430,18 @@ static PySequenceMethods sipVoidPtr_SequenceMethods = {
0, /* sq_concat */
0, /* sq_repeat */
sipVoidPtr_item, /* sq_item */
#if PY_VERSION_HEX < 0x02050000
#if PY_VERSION_HEX >= 0x02050000
0, /* sq_slice */
0, /* sq_ass_item */
0, /* sq_ass_slice */
#else
sipVoidPtr_slice, /* sq_slice */
sipVoidPtr_ass_item, /* sq_ass_item */
sipVoidPtr_ass_slice, /* sq_ass_slice */
#endif
0, /* sq_contains */
0, /* sq_inplace_concat */
0, /* sq_inplace_repeat */
};
@@ -741,6 +787,20 @@ PyTypeObject sipVoidPtr_Type = {
0, /* tp_init */
0, /* tp_alloc */
sipVoidPtr_new, /* tp_new */
0, /* tp_free */
0, /* tp_is_gc */
0, /* tp_bases */
0, /* tp_mro */
0, /* tp_cache */
0, /* tp_subclasses */
0, /* tp_weaklist */
0, /* tp_del */
#if PY_VERSION_HEX >= 0x02060000
0, /* tp_version_tag */
#endif
#if PY_VERSION_HEX >= 0x03040000
0, /* tp_finalize */
#endif
};
@@ -986,10 +1046,12 @@ static int vp_convertor(PyObject *arg, struct vp_values *vp)
ptr = view.buf;
size = view.len;
rw = !view.readonly;
PyBuffer_Release(&view);
}
#endif
#if PY_VERSION_HEX < 0x03000000
else if (PyObject_AsReadBuffer(arg, &ptr, &size) >= 0)
else if (PyObject_AsReadBuffer(arg, (const void **)&ptr, &size) >= 0)
{
rw = (Py_TYPE(arg)->tp_as_buffer->bf_getwritebuffer != NULL);
}
@@ -1016,3 +1078,21 @@ static int vp_convertor(PyObject *arg, struct vp_values *vp)
return 1;
}
/*
* Get a size possibly supplied as an argument, otherwise get it from the
* object. Raise an exception if there was no size specified.
*/
static SIP_SSIZE_T get_size_from_arg(sipVoidPtrObject *v, SIP_SSIZE_T size)
{
/* Use the current size if one wasn't explicitly given. */
if (size < 0)
size = v->size;
if (size < 0)
PyErr_SetString(PyExc_ValueError,
"a size must be given or the sip.voidptr object must have a size");
return size;
}

View File

@@ -440,6 +440,7 @@ def build(bld):
features = 'c cxx cshlib cxxshlib pyext',
target = makeTargetName(bld, 'siplib'),
source = ['sip/siplib/apiversions.c',
'sip/siplib/array.c',
'sip/siplib/bool.cpp',
'sip/siplib/descriptors.c',
'sip/siplib/objmap.c',