Skip to content

Commit 157d211

Browse files
author
florianlink
committed
adapted to new py_ naming of special methods and added support for py_toString
git-svn-id: http://svn.code.sf.net/p/pythonqt/code/trunk@153 ea8d5007-eb21-0410-b261-ccb3ea6e24a9
1 parent d72f41f commit 157d211

File tree

3 files changed

+47
-14
lines changed

3 files changed

+47
-14
lines changed

src/PythonQtClassInfo.cpp

+4-1
Original file line numberDiff line numberDiff line change
@@ -412,6 +412,9 @@ void PythonQtClassInfo::listDecoratorSlotsFromDecoratorProvider(QStringList& lis
412412
continue;
413413
} else if (qstrncmp(sigStart, "delete_", 7)==0) {
414414
continue;
415+
} else if (qstrncmp(sigStart, "py_", 3)==0) {
416+
// hide everything that starts with py_
417+
continue;
415418
}
416419
// find the first '('
417420
int offset = findCharOffset(sigStart, '(');
@@ -712,7 +715,7 @@ QObject* PythonQtClassInfo::decorator()
712715

713716
bool PythonQtClassInfo::hasOwnerMethodButNoOwner(void* object)
714717
{
715-
PythonQtMemberInfo info = member("hasOwner");
718+
PythonQtMemberInfo info = member("py_hasOwner");
716719
if (info._type == PythonQtMemberInfo::Slot) {
717720
void* obj = object;
718721
bool result = false;

src/PythonQtClassInfo.h

+1-1
Original file line numberDiff line numberDiff line change
@@ -169,7 +169,7 @@ class PythonQtClassInfo {
169169
//! add the parent class info of a CPP object
170170
void addParentClass(const ParentClassInfo& info) { _parentClasses.append(info); }
171171

172-
//! check if the special method "hasOwner" is implemented and if it returns false, which means that the object may be destroyed
172+
//! check if the special method "py_hasOwner" is implemented and if it returns false, which means that the object may be destroyed
173173
bool hasOwnerMethodButNoOwner(void* object);
174174

175175
//! set the associated PythonQtClassWrapper (which handles instance creation of this type)

src/PythonQtInstanceWrapper.cpp

+42-12
Original file line numberDiff line numberDiff line change
@@ -301,8 +301,9 @@ static PyObject *PythonQtInstanceWrapper_getattro(PyObject *obj,PyObject *name)
301301
break;
302302
case PythonQtMemberInfo::NotFound:
303303
{
304-
// check for a getter_
305-
PythonQtMemberInfo member = wrapper->classInfo()->member(QByteArray("getter_") + attributeName);
304+
static const QByteArray getterString("py_get_");
305+
// check for a getter slot
306+
PythonQtMemberInfo member = wrapper->classInfo()->member(getterString + attributeName);
306307
if (member._type == PythonQtMemberInfo::Slot) {
307308
return PythonQtSlotFunction_CallImpl(wrapper->classInfo(), wrapper->_obj, member._slot, NULL, NULL, wrapper->_wrappedPtr);
308309
}
@@ -393,8 +394,9 @@ static int PythonQtInstanceWrapper_setattro(PyObject *obj,PyObject *name,PyObjec
393394
} else if (member._type == PythonQtMemberInfo::EnumWrapper) {
394395
error = QString("Enum '") + attributeName + "' can not be overwritten on " + obj->ob_type->tp_name + " object";
395396
} else if (member._type == PythonQtMemberInfo::NotFound) {
396-
// check for a setter_
397-
PythonQtMemberInfo setter = wrapper->classInfo()->member(QByteArray("setter_") + attributeName);
397+
// check for a setter slot
398+
static const QByteArray setterString("py_set_");
399+
PythonQtMemberInfo setter = wrapper->classInfo()->member(setterString + attributeName);
398400
if (setter._type == PythonQtMemberInfo::Slot) {
399401
// call the setter and ignore the result value
400402
void* result;
@@ -438,16 +440,39 @@ static int PythonQtInstanceWrapper_setattro(PyObject *obj,PyObject *name,PyObjec
438440
return -1;
439441
}
440442

443+
static QString getStringFromObject(PythonQtInstanceWrapper* wrapper) {
444+
QString result;
445+
if (wrapper->_wrappedPtr) {
446+
// first try some manually string conversions for some variants
447+
int metaid = wrapper->classInfo()->metaTypeId();
448+
result = PythonQtConv::CPPObjectToString(metaid, wrapper->_wrappedPtr);
449+
if (!result.isEmpty()) {
450+
return result;
451+
}
452+
}
453+
// next, try to call py_toString
454+
PythonQtMemberInfo info = wrapper->classInfo()->member("py_toString");
455+
if (info._type == PythonQtMemberInfo::Slot) {
456+
PyObject* resultObj = PythonQtSlotFunction_CallImpl(wrapper->classInfo(), wrapper->_obj, info._slot, NULL, NULL, wrapper->_wrappedPtr);
457+
if (resultObj) {
458+
// TODO this is one conversion too much, would be nicer to call the slot directly...
459+
result = PythonQtConv::PyObjGetString(resultObj);
460+
Py_DECREF(resultObj);
461+
}
462+
}
463+
return result;
464+
}
465+
441466
static PyObject * PythonQtInstanceWrapper_str(PyObject * obj)
442467
{
443468
PythonQtInstanceWrapper* wrapper = (PythonQtInstanceWrapper*)obj;
444469
const char* typeName = obj->ob_type->tp_name;
445470
QObject *qobj = wrapper->_obj;
471+
QString str = getStringFromObject(wrapper);
472+
if (!str.isEmpty()) {
473+
return PyString_FromFormat("%s", str.toLatin1().constData());
474+
}
446475
if (wrapper->_wrappedPtr) {
447-
QString str = PythonQtConv::CPPObjectToString(wrapper->classInfo()->metaTypeId(), wrapper->_wrappedPtr);
448-
if (!str.isEmpty()) {
449-
return PyString_FromFormat("%s", str.toLatin1().constData());
450-
} else
451476
if (wrapper->_obj) {
452477
return PyString_FromFormat("%s (C++ Object %p wrapped by %s %p))", typeName, wrapper->_wrappedPtr, wrapper->_obj->metaObject()->className(), qobj);
453478
} else {
@@ -464,11 +489,15 @@ static PyObject * PythonQtInstanceWrapper_repr(PyObject * obj)
464489
const char* typeName = obj->ob_type->tp_name;
465490

466491
QObject *qobj = wrapper->_obj;
467-
if (wrapper->_wrappedPtr) {
468-
QString str = PythonQtConv::CPPObjectToString(wrapper->classInfo()->metaTypeId(), wrapper->_wrappedPtr);
469-
if (!str.isEmpty()) {
492+
QString str = getStringFromObject(wrapper);
493+
if (!str.isEmpty()) {
494+
if (str.startsWith(typeName)) {
495+
return PyString_FromFormat("%s", str.toLatin1().constData());
496+
} else {
470497
return PyString_FromFormat("%s(%s, %p)", typeName, str.toLatin1().constData(), wrapper->_wrappedPtr);
471-
} else
498+
}
499+
}
500+
if (wrapper->_wrappedPtr) {
472501
if (wrapper->_obj) {
473502
return PyString_FromFormat("%s (C++ Object %p wrapped by %s %p))", typeName, wrapper->_wrappedPtr, wrapper->_obj->metaObject()->className(), qobj);
474503
} else {
@@ -526,6 +555,7 @@ static int PythonQtInstanceWrapper_compare(PyObject * obj1, PyObject * obj2)
526555
args[0] = &result;
527556
args[1] = obj2; // this is a reference, so it needs the direct pointer
528557
w1->_obj->qt_metacall(QMetaObject::InvokeMetaMethod, info._slot->slotIndex(), args);
558+
return result?0:-1;
529559
}
530560
}
531561
}

0 commit comments

Comments
 (0)