diff --git a/etg/dataobj.py b/etg/dataobj.py index 4944e7f4..a3d12fd1 100644 --- a/etg/dataobj.py +++ b/etg/dataobj.py @@ -50,7 +50,7 @@ def addGetAllFormats(klass, pureVirtual=False): isConst=True, doc="""\ Returns a list of wx.DataFormat objects which this data object - supports transfering in the given direction.""", + supports transferring in the given direction.""", body="""\ size_t count = self->GetFormatCount(dir); wxDataFormat* formats = new wxDataFormat[count]; @@ -116,12 +116,12 @@ def addBaseVirtuals(c): doc="", body="return self->SetData(*format, buf->m_len, buf->m_ptr);", virtualCatcherCode="""\ - {0}* self = ({0}*)sipPySelf->data; + {0}* self = static_cast<{0}*>(wxPyGetCppPtr(sipPySelf)); sipRes = self->{0}::SetData(format, len, buf); """.format(c.name)) # We need to let SIP know that the pure virtuals in the base class have - # impelmentations in C even though they will not be used much (if at + # implementations in C even though they will not be used much (if at # all.) if not c.findItem('GetFormatCount'): c.addItem( @@ -203,7 +203,7 @@ def run(): PyObject* resObj = NULL; Py_ssize_t size = 0; - self = PyMethod_Self(sipMethod); // this shouldn't fail, and the reference is borrowed + self = wxPyMethod_Self(sipMethod); // this shouldn't fail, and the reference is borrowed fmtObj = wxPyConstructObject((void*)&format, "wxDataFormat", false); if (!fmtObj) goto error; @@ -277,7 +277,7 @@ def run(): PyObject* resObj = NULL; Py_ssize_t size = 0; - self = PyMethod_Self(sipMethod); + self = wxPyMethod_Self(sipMethod); sizeObj = PyObject_CallMethod(self, "GetDataSize", "", NULL); if (!sizeObj) goto error; diff --git a/src/wxpy_api.h b/src/wxpy_api.h index 9e9edfb8..3cabfcd9 100644 --- a/src/wxpy_api.h +++ b/src/wxpy_api.h @@ -17,7 +17,7 @@ #if defined(__APPLE__) // When it's possible that we're building universal binaries with both - // 32-bit and 64-bit architectures then these need to be undefed because + // 32-bit and 64-bit architectures then these need to be undef'ed because // otherwise the values set by configure could conflict with those set // based on runtime flags in Python's headers. We also do something // similar in wx/platform.h so it's okay to undef them now because they @@ -98,16 +98,6 @@ inline void wxPyEndAllowThreads(PyThreadState* saved) { #define RETURN_NONE() { wxPyBLOCK_THREADS(Py_INCREF(Py_None)); return Py_None; } -// Make a memory view object from a C buffer and size. -inline PyObject* wxPyMakeBuffer(void* ptr, Py_ssize_t len, bool readOnly=false) { - // GIL should already be held - Py_buffer view; - int flags = PyBUF_FORMAT|PyBUF_ND; - if (!readOnly) - flags |= PyBUF_WRITABLE; - PyBuffer_FillInfo(&view, NULL, ptr, len, readOnly ? 1:0, flags); - return PyMemoryView_FromBuffer(&view); -} // Macros to work around some of the differences in the Python 3 API @@ -150,47 +140,6 @@ Py_ssize_t wxPyUnicode_AsWideChar(PyObject* unicode, wchar_t* w, Py_ssize_t size } -inline bool wxPyNumberSequenceCheck(PyObject* obj, int reqLength=-1) { - // Used in the various places where a sequence of numbers can be converted - // to a wx type, like wxPoint, wxSize, wxColour, etc. Returns true if the - // object is a Tuple, List or numpy Array of the proper length. - - // tuples or lists are easy - bool isFast = (PyTuple_Check(obj) || PyList_Check(obj)); - - if (!isFast ) { - // If it's not one of those, then check for an array. - // It's probably not a good idea to do it this way, but this allows us - // to check if the object is a numpy array without requiring that - // numpy be imported even for those applications tha are not using it. - if (strcmp(obj->ob_type->tp_name, "numpy.ndarray") != 0) - return false; - } - - // Bail out here if the length isn't given - if (reqLength == -1) - return true; - - // Now check that the length matches the expected length - if (PySequence_Length(obj) != reqLength) - return false; - - // Check that each item is a number - for (int i=0; ip_wxVariant_out_helper(value); } +// Check if a wx.App object has been created inline bool wxPyCheckForApp() { return wxPyGetAPIPtr()->p_wxPyCheckForApp(); } +// Create a buffer object from a pointer and size +inline PyObject* wxPyMakeBuffer(void* ptr, Py_ssize_t len, bool readOnly=false) + { return wxPyGetAPIPtr()->p_wxPyMakeBuffer(ptr, len, readOnly); } + +// Check if an object is a sequence of numbers +inline bool wxPyNumberSequenceCheck(PyObject* obj, int reqLength=-1) + { return wxPyGetAPIPtr()->p_wxPyNumberSequenceCheck(obj, reqLength); } + + +inline void* wxPyGetCppPtr(sipSimpleWrapper* sipPyObj) + { return wxPyGetAPIPtr()->p_wxPyGetCppPtr(sipPyObj); } + +inline PyObject* wxPyMethod_Self(PyObject* method) + { return wxPyGetAPIPtr()->p_wxPyMethod_Self(method); } + + //-------------------------------------------------------------------------- // Convenience helper for RAII-style thread blocking diff --git a/src/wxpy_api.sip b/src/wxpy_api.sip index 9eaf5b4f..8e9ff672 100644 --- a/src/wxpy_api.sip +++ b/src/wxpy_api.sip @@ -21,7 +21,6 @@ %ModuleCode // wxPython's API helper and utility functions - //-------------------------------------------------------------------------- // wxString conversion @@ -441,6 +440,92 @@ bool i_wxPyCheckForApp() { } } +//-------------------------------------------------------------------------- +// Make a memory view object from a C buffer and size. + +PyObject* i_wxPyMakeBuffer(void* ptr, Py_ssize_t len, bool readOnly=false) { + // GIL should already be held + Py_buffer view; + int flags = PyBUF_FORMAT|PyBUF_ND; + if (!readOnly) + flags |= PyBUF_WRITABLE; + PyBuffer_FillInfo(&view, NULL, ptr, len, readOnly ? 1:0, flags); + return PyMemoryView_FromBuffer(&view); + +// // TODO: Consider using a sip.array object instead, like this: +// // Create a sip.array of bytes, and then convert to a memoryview which is +// // basically the same thing but is a documented built-in Python type +// int flags = 0; +// if (readOnly) +// flags |= SIP_READ_ONLY; +// PyObject* array = sipConvertToArray(ptr, "B", len, flags); +// return array; +} + + +//-------------------------------------------------------------------------- +// Check if an object is suitable for conversion to various "value" types that +// can be created from a sequence of numbers, such as wx.Point, wx.Colour, +// wx.Rect, etc. + +bool i_wxPyNumberSequenceCheck(PyObject* obj, int reqLength=-1) { + // Used in the various places where a sequence of numbers can be converted + // to a wx type, like wxPoint, wxSize, wxColour, etc. Returns true if the + // object is a Tuple, List or numpy Array of the proper length. + + // tuples or lists are easy + bool isFast = (PyTuple_Check(obj) || PyList_Check(obj)); + + if (!isFast ) { + // If it's not one of those, then check for an array. + // It's probably not a good idea to do it this way, but this allows us + // to check if the object is a numpy array without requiring that + // numpy be imported even for those applications that are not using it. + if (strcmp(obj->ob_type->tp_name, "numpy.ndarray") != 0) + return false; + } + + // Bail out here if the length isn't given + if (reqLength == -1) + return true; + + // Now check that the length matches the expected length + if (PySequence_Length(obj) != reqLength) + return false; + + // Check that each item is a number + for (int i=0; idata; +} + +//-------------------------------------------------------------------------- +// Call the PyMethod_Self API, which is not available when the Python +// limited API is activated. + +inline PyObject* i_wxPyMethod_Self(PyObject* method) { + return PyMethod_Self(method); +} + //-------------------------------------------------------------------------- // An instance of the API structure @@ -456,7 +541,11 @@ static wxPyAPI API = { i_wxPyWrappedPtr_TypeCheck, i_wxVariant_in_helper, i_wxVariant_out_helper, - i_wxPyCheckForApp + i_wxPyCheckForApp, + i_wxPyMakeBuffer, + i_wxPyNumberSequenceCheck, + i_wxPyGetCppPtr, + i_wxPyMethod_Self }; %End