From 4a262bcb91b7b620f434397fe2f7cb1454950397 Mon Sep 17 00:00:00 2001 From: Lauro Neto Date: Wed, 30 Mar 2011 16:37:43 -0300 Subject: Check for old-style bases before calling tp_new Instead of creating the type instance and them checking for old-style base classes, check for them in the beginning. The later check was causing the new type object to "leak" and failing an assert in the garbage collector. Reviewer: Luciano Wolf Reviewer: Hugo Lima --- libshiboken/basewrapper.cpp | 32 ++++++++++++++++++++++---------- 1 file changed, 22 insertions(+), 10 deletions(-) (limited to 'libshiboken/basewrapper.cpp') diff --git a/libshiboken/basewrapper.cpp b/libshiboken/basewrapper.cpp index 310ce2b12..fbf6c215f 100644 --- a/libshiboken/basewrapper.cpp +++ b/libshiboken/basewrapper.cpp @@ -203,17 +203,21 @@ void SbkObjectTypeDealloc(PyObject* pyObj) PyObject* SbkObjectTypeTpNew(PyTypeObject* metatype, PyObject* args, PyObject* kwds) { - // The meta type creates a new type when the Python programmer extends a wrapped C++ class. - SbkObjectType* newType = reinterpret_cast(PyType_Type.tp_new(metatype, args, kwds)); - - if (!newType) - return 0; - - Shiboken::ObjectType::initPrivateData(newType); - SbkObjectTypePrivate* d = newType->d; + // Check if all bases are new style before calling type.tp_new + // Was causing gc assert errors in test_bug704.py when + // this check happened after creating the type object. + // Argument parsing take from type.tp_new code. + PyObject* name; + PyObject* pyBases; + PyObject* dict; + static char* kwlist[] = { "name", "bases", "dict", 0}; + + if (!PyArg_ParseTupleAndKeywords(args, kwds, "SO!O!:sbktype", kwlist, + &name, + &PyTuple_Type, &pyBases, + &PyDict_Type, &dict)) + return NULL; - // Check if all objects are python new style - PyObject* pyBases = ((PyTypeObject*)newType)->tp_bases; for(int i=0, i_max=PyTuple_GET_SIZE(pyBases); i < i_max; i++) { PyObject* baseType = PyTuple_GET_ITEM(pyBases, i); if (PyClass_Check(baseType)) { @@ -222,6 +226,14 @@ PyObject* SbkObjectTypeTpNew(PyTypeObject* metatype, PyObject* args, PyObject* k } } + // The meta type creates a new type when the Python programmer extends a wrapped C++ class. + SbkObjectType* newType = reinterpret_cast(PyType_Type.tp_new(metatype, args, kwds)); + + if (!newType) + return 0; + + Shiboken::ObjectType::initPrivateData(newType); + SbkObjectTypePrivate* d = newType->d; std::list bases = Shiboken::getCppBaseClasses(reinterpret_cast(newType)); if (bases.size() == 1) { -- cgit v1.2.3