siplib updates from the sip-4.12.5-snapshot-de6a700f5faa development snapshot

git-svn-id: https://svn.wxwidgets.org/svn/wx/wxPython/Phoenix/trunk@69233 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775
This commit is contained in:
Robin Dunn
2011-09-29 20:53:43 +00:00
parent 2b2e7e0f16
commit 820a61dc4c
2 changed files with 112 additions and 16 deletions

View File

@@ -203,6 +203,9 @@ static void sip_api_abstract_method(const char *classname, const char *method);
static void sip_api_bad_class(const char *classname);
static void *sip_api_get_complex_cpp_ptr(sipSimpleWrapper *sw);
static PyObject *sip_api_is_py_method(sip_gilstate_t *gil, char *pymc,
sipSimpleWrapper * const *sipSelfp, const char *cname,
const char *mname);
static PyObject *sip_api_is_py_method_old(sip_gilstate_t *gil, char *pymc,
sipSimpleWrapper *sipSelf, const char *cname, const char *mname);
static void sip_api_call_hook(const char *hookname);
static void sip_api_raise_unknown_exception(void);
@@ -339,7 +342,7 @@ static const sipAPIDef sip_api = {
sip_api_bad_class,
sip_api_get_cpp_ptr,
sip_api_get_complex_cpp_ptr,
sip_api_is_py_method,
sip_api_is_py_method_old,
sip_api_call_hook,
sip_api_start_thread,
sip_api_end_thread,
@@ -366,7 +369,11 @@ static const sipAPIDef sip_api = {
/*
* The following are part of the public API.
*/
sip_api_get_address
sip_api_get_address,
/*
* The following are not part of the public API.
*/
sip_api_is_py_method
};
@@ -661,6 +668,8 @@ static int isNonlazyMethod(PyMethodDef *pmd);
static int addMethod(PyObject *dict, PyMethodDef *pmd);
static PyObject *create_property(sipVariableDef *vd);
static PyObject *create_function(PyMethodDef *ml);
static PyObject *sip_exit(PyObject *obj, PyObject *ignore);
static void register_exit_notifier(void);
/*
@@ -857,6 +866,9 @@ PyMODINIT_FUNC SIP_MODULE_ENTRY(void)
sipInterpreter = PyThreadState_Get()->interp;
}
/* Make sure are notified when starting to exit. */
register_exit_notifier();
SIP_MODULE_RETURN(mod);
}
@@ -1545,7 +1557,10 @@ static void finalise(void)
{
sipExportedModuleDef *em;
/* Mark the Python API as unavailable. */
/*
* Mark the Python API as unavailable. This should already have been done,
* but just in case...
*/
sipInterpreter = NULL;
/* Handle any delayed dtors. */
@@ -5203,7 +5218,7 @@ static void callPyDtor(sipSimpleWrapper *self)
char pymc = 0;
PyObject *meth;
meth = sip_api_is_py_method(&sipGILState, &pymc, self, NULL, "__dtor__");
meth = sip_api_is_py_method(&sipGILState, &pymc, &self, NULL, "__dtor__");
if (meth != NULL)
{
@@ -7516,15 +7531,29 @@ static PyObject *getDictFromObject(PyObject *obj)
}
/*
* Return a Python reimplementation corresponding to a C/C++ virtual function,
* if any. If one was found then the GIL is acquired. This is deprecated and
* only used by modules generated by an older version.
*/
static PyObject *sip_api_is_py_method_old(sip_gilstate_t *gil, char *pymc,
sipSimpleWrapper *sipSelf, const char *cname, const char *mname)
{
return sip_api_is_py_method(gil, pymc, &sipSelf, cname, mname);
}
/*
* Return a Python reimplementation corresponding to a C/C++ virtual function,
* if any. If one was found then the GIL is acquired.
*/
static PyObject *sip_api_is_py_method(sip_gilstate_t *gil, char *pymc,
sipSimpleWrapper *sipSelf, const char *cname, const char *mname)
sipSimpleWrapper * const *sipSelfp, const char *cname,
const char *mname)
{
PyObject *mname_obj, *reimp, *mro, *cls;
SIP_SSIZE_T i;
sipSimpleWrapper *sipSelf;
/*
* This is the most common case (where there is no Python reimplementation)
@@ -7537,22 +7566,28 @@ static PyObject *sip_api_is_py_method(sip_gilstate_t *gil, char *pymc,
if (sipInterpreter == NULL)
return NULL;
#ifdef WITH_THREAD
*gil = PyGILState_Ensure();
#endif
/*
* It's possible that the Python object has been deleted but the underlying
* C++ instance is still working and trying to handle virtual functions.
* Alternatively, an instance has started handling virtual functions before
* its ctor has returned. In either case say there is no Python
* reimplementation.
* reimplementation. We do this with the GIL in case the object is in the
* process of being garbage collected.
*/
if (sipSelf == NULL)
if ((sipSelf = *sipSelfp) == NULL)
{
#ifdef WITH_THREAD
PyGILState_Release(*gil);
#endif
return NULL;
}
/* Get any reimplementation. */
#ifdef WITH_THREAD
*gil = PyGILState_Ensure();
#endif
#if PY_MAJOR_VERSION >= 3
mname_obj = PyUnicode_FromString(mname);
#else
@@ -7575,6 +7610,8 @@ static PyObject *sip_api_is_py_method(sip_gilstate_t *gil, char *pymc,
*/
if (add_all_lazy_attrs(((sipWrapperType *)Py_TYPE(sipSelf))->type) < 0)
{
Py_DECREF(mname_obj);
#ifdef WITH_THREAD
PyGILState_Release(*gil);
#endif
@@ -7617,7 +7654,7 @@ static PyObject *sip_api_is_py_method(sip_gilstate_t *gil, char *pymc,
/*
* Check any possible reimplementation is not the wrapped C++ method or
* a default special method implementation..
* a default special method implementation.
*/
if (cls_dict != NULL && (cls_attr = PyDict_GetItem(cls_dict, mname_obj)) != NULL && Py_TYPE(cls_attr) != &sipMethodDescr_Type && Py_TYPE(cls_attr) != &PyWrapperDescr_Type)
{
@@ -10920,3 +10957,52 @@ static int check_encoded_string(PyObject *obj)
return -1;
}
/*
* This is called by the atexit module.
*/
static PyObject *sip_exit(PyObject *obj, PyObject *ignore)
{
/* Disable all Python reimplementations of virtuals. */
sipInterpreter = NULL;
Py_INCREF(Py_None);
return Py_None;
}
/*
* Register the exit notifier with the atexit module.
*/
static void register_exit_notifier(void)
{
static PyMethodDef md = {
"_sip_exit", sip_exit, METH_NOARGS, NULL
};
PyObject *notifier, *atexit_module, *register_func, *res;
if ((notifier = PyCFunction_New(&md, NULL)) == NULL)
return;
if ((atexit_module = PyImport_ImportModule("atexit")) == NULL)
{
Py_DECREF(notifier);
return;
}
if ((register_func = PyObject_GetAttrString(atexit_module, "register")) == NULL)
{
Py_DECREF(atexit_module);
Py_DECREF(notifier);
return;
}
res = PyObject_CallFunctionObjArgs(register_func, notifier, NULL);
Py_XDECREF(res);
Py_DECREF(register_func);
Py_DECREF(atexit_module);
Py_DECREF(notifier);
}