diff options
author | Lauro Neto <lauro.neto@openbossa.org> | 2011-03-30 16:37:43 -0300 |
---|---|---|
committer | Hugo Parente Lima <hugo.pl@gmail.com> | 2012-03-08 16:15:19 -0300 |
commit | 4a262bcb91b7b620f434397fe2f7cb1454950397 (patch) | |
tree | 2d6a7865a6b9b29d6d1259fa5c2380b8040680eb | |
parent | c5fd9d9dbb33bc4ddbf68315d6b15dc274f076cd (diff) |
Check for old-style bases before calling tp_new1.0.1
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 <luciano.wolf@openbossa.org>
Reviewer: Hugo Lima <hugo.lima@openbossa.org>
-rw-r--r-- | libshiboken/basewrapper.cpp | 32 |
1 files changed, 22 insertions, 10 deletions
diff --git a/libshiboken/basewrapper.cpp b/libshiboken/basewrapper.cpp index 310ce2b..fbf6c21 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<SbkObjectType*>(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<SbkObjectType*>(PyType_Type.tp_new(metatype, args, kwds)); + + if (!newType) + return 0; + + Shiboken::ObjectType::initPrivateData(newType); + SbkObjectTypePrivate* d = newType->d; std::list<SbkObjectType*> bases = Shiboken::getCppBaseClasses(reinterpret_cast<PyTypeObject*>(newType)); if (bases.size() == 1) { |