summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorHugo Parente Lima <hugo.lima@openbossa.org>2010-04-07 17:31:22 -0300
committerHugo Parente Lima <hugo.lima@openbossa.org>2010-04-08 18:37:52 -0300
commit62c909a374789f16ad97014464f91821f714cea6 (patch)
tree63b1c0cd2aa2301984022db067a0809fdf9c3683
parent0650666ccfe1ac83b20a4ffffa1d8b61669c2dd8 (diff)
downloadshiboken-62c909a374789f16ad97014464f91821f714cea6.tar.gz
shiboken-62c909a374789f16ad97014464f91821f714cea6.tar.xz
shiboken-62c909a374789f16ad97014464f91821f714cea6.zip
Better error messages when reimplementing virtual methods.
-rw-r--r--cppgenerator.cpp42
-rw-r--r--tests/libsample/virtualmethods.h6
-rwxr-xr-xtests/samplebinding/virtualmethods_test.py10
3 files changed, 42 insertions, 16 deletions
diff --git a/cppgenerator.cpp b/cppgenerator.cpp
index 561d8dc9..ae4a055c 100644
--- a/cppgenerator.cpp
+++ b/cppgenerator.cpp
@@ -529,22 +529,34 @@ void CppGenerator::writeVirtualMethodNative(QTextStream &s, const AbstractMetaFu
}
s << INDENT << '}' << endl;
- s << INDENT << "// Check return type" << endl;
- s << INDENT << "bool typeIsValid = ";
- if (func->typeReplaced(0).isEmpty())
- s << cpythonCheckFunction(func->type());
- else
- s << guessCPythonCheckFunction(func->typeReplaced(0));
- s << "(" << PYTHON_RETURN_VAR << ");" << endl;
- if (func->type()->isQObject() || func->type()->isObject() || func->type()->isValuePointer()) {
- s << INDENT << "typeIsValid = typeIsValid || (" << PYTHON_RETURN_VAR << " == Py_None);" << endl;
+ if (func->type()) {
+ s << INDENT << "// Check return type" << endl;
+ s << INDENT << "bool typeIsValid = ";
+ QString desiredType;
+ if (func->typeReplaced(0).isEmpty()) {
+ s << cpythonCheckFunction(func->type());
+ // SbkType would return null when the type is a container.
+ if (func->type()->typeEntry()->isContainer())
+ desiredType = '"' + reinterpret_cast<const ContainerTypeEntry*>(func->type()->typeEntry())->typeName() + '"';
+ else
+ desiredType = "SbkType<" + func->type()->cppSignature() + " >()->tp_name";
+ } else {
+ s << guessCPythonCheckFunction(func->typeReplaced(0));
+ desiredType = '"' + func->typeReplaced(0) + '"';
+ }
+ s << "(" << PYTHON_RETURN_VAR << ");" << endl;
+ if (func->type()->isQObject() || func->type()->isObject() || func->type()->isValuePointer())
+ s << INDENT << "typeIsValid = typeIsValid || (" << PYTHON_RETURN_VAR << " == Py_None);" << endl;
+
+ s << INDENT << "if (!typeIsValid) {" << endl;
+ s << INDENT << INDENT << "PyErr_Format(PyExc_TypeError, \"Invalid return value in function %s, expected %s, got %s.\", \""
+ << func->ownerClass()->name() << '.' << func->name() << "\", " << desiredType << ", "
+ << PYTHON_RETURN_VAR << "->ob_type->tp_name);" << endl;
+ s << INDENT << INDENT << "return ";
+ writeMinimalConstructorCallArguments(s, func->type());
+ s << INDENT << INDENT << ";" << endl;
+ s << INDENT << "}" << endl;
}
- s << INDENT << "if (!typeIsValid) {" << endl;
- s << INDENT << INDENT << "PyErr_SetString(PyExc_TypeError, \"Invalid return value in function " << func->ownerClass()->name() << "." << func->name() << "\");" << endl;
- s << INDENT << INDENT << "return ";
- writeMinimalConstructorCallArguments(s, func->type());
- s << INDENT << INDENT << ";" << endl;
- s << INDENT << "}" << endl;
bool hasConversionRule = !func->conversionRule(TypeSystem::NativeCode, 0).isEmpty();
if (hasConversionRule) {
diff --git a/tests/libsample/virtualmethods.h b/tests/libsample/virtualmethods.h
index 287f10e6..de4149a8 100644
--- a/tests/libsample/virtualmethods.h
+++ b/tests/libsample/virtualmethods.h
@@ -40,6 +40,7 @@
#include "str.h"
#include "libsamplemacros.h"
+#include "strlist.h"
class LIBSAMPLE_API VirtualMethods
{
@@ -88,6 +89,11 @@ public:
virtual bool createStr(const char* text, Str*& ret);
bool callCreateStr(const char* text, Str*& ret) { return createStr(text, ret); }
+ // Return a non-binded method
+ std::list<Str> callStrListToStdList(const StrList& strList) { return strListToStdList(strList); }
+ virtual std::list<Str> strListToStdList(const StrList& strList ) { return strList; }
+
+
private:
Str m_name;
};
diff --git a/tests/samplebinding/virtualmethods_test.py b/tests/samplebinding/virtualmethods_test.py
index be8abfb8..0ddb7e44 100755
--- a/tests/samplebinding/virtualmethods_test.py
+++ b/tests/samplebinding/virtualmethods_test.py
@@ -29,7 +29,7 @@
import sys
import unittest
-from sample import VirtualMethods, VirtualDaughter, Point, Str
+from sample import *
class ExtendedVirtualMethods(VirtualMethods):
def __init__(self):
@@ -40,6 +40,10 @@ class ExtendedVirtualMethods(VirtualMethods):
self.virtual_method0_called = True
return VirtualMethods.virtualMethod0(self, pt, val, cpx, b) * -1.0
+ def strListToStdList(self, arg):
+ # returnning wrong type for test purporses.
+ return True
+
class ExtendedVirtualDaughter(VirtualDaughter):
def __init__(self, name):
VirtualDaughter.__init__(self, name)
@@ -107,6 +111,10 @@ class VirtualMethodsTest(unittest.TestCase):
self.assert_(eevd.grand_grand_daughter_name_called)
self.assertEqual(eevd.name().prepend(self.prefix_from_codeinjection), name)
+class PrettyErrorMessageTest(unittest.TestCase):
+ def testIt(self):
+ obj = ExtendedVirtualMethods()
+ self.assertRaises(TypeError, obj.callStrListToStdList, StrList())
if __name__ == '__main__':
unittest.main()