aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--cppgenerator.cpp28
-rw-r--r--headergenerator.cpp1
-rw-r--r--libshiboken/conversions.h32
-rw-r--r--shibokengenerator.cpp46
-rw-r--r--shibokengenerator.h12
-rwxr-xr-xtests/samplebinding/reference_test.py2
6 files changed, 92 insertions, 29 deletions
diff --git a/cppgenerator.cpp b/cppgenerator.cpp
index f032a6d6c..ebcf21a67 100644
--- a/cppgenerator.cpp
+++ b/cppgenerator.cpp
@@ -1183,11 +1183,11 @@ void CppGenerator::writeTypeCheck(QTextStream& s, const AbstractMetaType* argTyp
if (!customType.isEmpty())
s << guessCPythonCheckFunction(customType);
else if (argType->typeEntry()->isFlags())
- s << cpythonCheckFunction(((FlagsTypeEntry*) argType->typeEntry())->originator(), true);
+ s << cpythonIsConvertibleFunction(((FlagsTypeEntry*) argType->typeEntry())->originator(), true);
else if (argType->isEnum())
- s << cpythonCheckFunction(argType, false, true);
+ s << cpythonIsConvertibleFunction(argType, false);
else
- s << cpythonCheckFunction(argType, isNumber);
+ s << cpythonIsConvertibleFunction(argType, isNumber);
s << '(' << argumentName << ')';
}
@@ -1240,6 +1240,7 @@ void CppGenerator::writeArgumentConversion(QTextStream& s,
if (typeName.endsWith("&"))
typeName.chop(1);
}
+ typeName = typeName.trimmed();
bool hasImplicitConversions = !implicitConversions(argType).isEmpty();
@@ -1253,8 +1254,13 @@ void CppGenerator::writeArgumentConversion(QTextStream& s,
s << argName << "_auto_ptr;" << endl;
}
- s << INDENT << typeName << ' ' << argName << " = ";
- s << "Shiboken::Converter<" << typeName << " >::toCpp(" << pyArgName << ");" << endl;
+ if (usePySideExtensions() && typeName == "QStringRef") {
+ s << INDENT << "QString " << argName << "_qstring = Shiboken::Converter<QString>::toCpp(" << pyArgName << ");" << endl;
+ s << INDENT << "QStringRef " << argName << "(&" << argName << "_qstring);" << endl;
+ } else {
+ s << INDENT << typeName << ' ' << argName << " = ";
+ s << "Shiboken::Converter<" << typeName << " >::toCpp(" << pyArgName << ");" << endl;
+ }
if (hasImplicitConversions) {
s << INDENT << "if (!" << cpythonCheckFunction(argType->typeEntry()) << '(' << pyArgName << "))";
@@ -1437,8 +1443,8 @@ QString CppGenerator::argumentNameFromIndex(const AbstractMetaFunction* func, in
ReportHandler::warning("Invalid Argument index on function modification: " + func->name());
}
} else {
- int real_index = OverloadData::numberOfRemovedArguments(func, argIndex - 1);
- *wrappedClass = classes().findClass(func->arguments().at(real_index)->type()->typeEntry()->name());
+ int realIndex = argIndex - 1 - OverloadData::numberOfRemovedArguments(func, argIndex - 1);
+ *wrappedClass = classes().findClass(func->arguments().at(realIndex)->type()->typeEntry()->name());
if ((argIndex == 1)
&& OverloadData::isSingleArgument(getFunctionGroups(func->implementingClass())[func->name()]))
pyArgName = QString("arg");
@@ -1709,7 +1715,7 @@ void CppGenerator::writeMethodCall(QTextStream& s, const AbstractMetaFunction* f
const AbstractMetaClass* wrappedClass = 0;
QString pyArgName = argumentNameFromIndex(func, arg_mod.index, &wrappedClass);
if (!wrappedClass) {
- s << "#error Invalid ownership modification for argument " << arg_mod.index << endl << endl;
+ s << "#error Invalid ownership modification for argument " << arg_mod.index << '(' << pyArgName << ')' << endl << endl;
break;
}
@@ -1838,7 +1844,7 @@ void CppGenerator::writeExtendedIsConvertibleFunction(QTextStream& s, const Type
isFirst = false;
else
s << endl << INDENT << " || ";
- s << cpythonCheckFunction(metaClass->typeEntry()) << "(pyobj)";
+ s << cpythonIsConvertibleFunction(metaClass->typeEntry()) << "(pyobj)";
}
s << ';' << endl;
s << '}' << endl;
@@ -1856,7 +1862,7 @@ void CppGenerator::writeExtendedToCppFunction(QTextStream& s, const TypeEntry* e
isFirst = false;
else
s << "else ";
- s << "if (" << cpythonCheckFunction(metaClass->typeEntry()) << "(pyobj))" << endl;
+ s << "if (" << cpythonIsConvertibleFunction(metaClass->typeEntry()) << "(pyobj))" << endl;
Indentation indent(INDENT);
s << INDENT << "cptr = new " << externalType->name() << '(';
writeToCppConversion(s, metaClass, "pyobj");
@@ -2322,7 +2328,7 @@ void CppGenerator::writeRichCompareFunction(QTextStream& s, const AbstractMetaCl
s << INDENT;
}
- s << "if (" << cpythonCheckFunction(type, numberType) << "(other)) {" << endl;
+ s << "if (" << cpythonIsConvertibleFunction(type, numberType) << "(other)) {" << endl;
{
Indentation indent(INDENT);
s << INDENT << "// " << func->signature() << endl;
diff --git a/headergenerator.cpp b/headergenerator.cpp
index d696b92cb..4543799e2 100644
--- a/headergenerator.cpp
+++ b/headergenerator.cpp
@@ -246,6 +246,7 @@ void HeaderGenerator::writeTypeConverterDecl(QTextStream& s, const TypeEntry* ty
s << INDENT << "static " << type->name() << " toCpp(PyObject* pyobj);" << endl;
s << INDENT << "static bool isConvertible(PyObject* pyobj);" << endl;
if (hasCustomConversion) {
+ s << INDENT << "static bool checkType(PyObject* pyobj);" << endl;
s << INDENT << "static inline PyObject* toPython(void* cppObj) { return toPython(*reinterpret_cast<"
<< type->name() << (isAbstractOrObjectType ? "" : "*") << " >(cppObj)); }" << endl;
s << INDENT << "static PyObject* toPython(const " << type->name() << "& cppObj);" << endl;
diff --git a/libshiboken/conversions.h b/libshiboken/conversions.h
index 91243a07c..0d9c38608 100644
--- a/libshiboken/conversions.h
+++ b/libshiboken/conversions.h
@@ -131,6 +131,11 @@ template <typename T> struct Converter {};
template <typename T>
struct Converter<T*>
{
+ static inline bool checkType(PyObject* pyObj)
+ {
+ return Converter<T>::checkType(pyObj);
+ }
+
static inline bool isConvertible(PyObject* pyObj)
{
return pyObj == Py_None || PyObject_TypeCheck(pyObj, SbkType<T>());
@@ -166,6 +171,7 @@ template <typename T> struct Converter<const T*> : Converter<T*> {};
template <typename T>
struct Converter<T&>
{
+ static inline bool checkType(PyObject* pyObj) { return Converter<T>::checkType(pyObj); }
static inline bool isConvertible(PyObject* pyObj) { return Converter<T>::isConvertible(pyObj); }
static inline PyObject* toPython(const T& cppobj) { return Converter<T*>::toPython(&cppobj); }
static inline T& toCpp(PyObject* pyobj) { return *Converter<T*>::toCpp(pyobj); }
@@ -177,6 +183,7 @@ template <typename T> struct Converter<const T&> : Converter<T&> {};
template<>
struct Converter<void*>
{
+ static inline bool checkType(PyObject* pyObj) { return false; }
static inline bool isConvertible(PyObject* pyobj) { return true; }
static PyObject* toPython(void* cppobj)
{
@@ -205,6 +212,8 @@ template <> struct Converter<const void*> : Converter<void*> {};
template <typename T>
struct ValueTypeConverter
{
+ static inline bool checkType(PyObject* pyObj) { return PyObject_TypeCheck(pyObj, SbkType<T>()); }
+
// The basic version of this method also tries to use the extended 'isConvertible' method.
static inline bool isConvertible(PyObject* pyobj)
{
@@ -248,6 +257,7 @@ struct ValueTypeConverter
template <typename T>
struct ObjectTypeConverter
{
+ static inline bool checkType(PyObject* pyObj) { return PyObject_TypeCheck(pyObj, SbkType<T>()); }
/// Py_None objects are the only objects convertible to an object type (in the form of a NULL pointer).
static inline bool isConvertible(PyObject* pyObj) { return pyObj == Py_None || PyObject_TypeCheck(pyObj, SbkType<T>()); }
/// Convenience overload that calls "toPython(const T*)" method.
@@ -279,6 +289,7 @@ struct ObjectTypeConverter
template <typename T>
struct ObjectTypeReferenceConverter : ObjectTypeConverter<T>
{
+ static inline bool checkType(PyObject* pyObj) { return PyObject_TypeCheck(pyObj, SbkType<T>()); }
static inline bool isConvertible(PyObject* pyObj) { return PyObject_TypeCheck(pyObj, SbkType<T>()); }
static inline PyObject* toPython(const T& cppobj) { return Converter<T*>::toPython(&cppobj); }
static inline T& toCpp(PyObject* pyobj)
@@ -301,6 +312,7 @@ template <> struct Converter<const PyObject*> : Converter<PyObject*> {};
template <>
struct Converter<bool>
{
+ static inline bool checkType(PyObject* pyobj) { return PyBool_Check(pyobj); }
static inline bool isConvertible(PyObject* pyobj) { return PyInt_Check(pyobj); }
static inline PyObject* toPython(void* cppobj) { return toPython(*reinterpret_cast<bool*>(cppobj)); }
static inline PyObject* toPython(bool cppobj) { return PyBool_FromLong(cppobj); }
@@ -361,6 +373,7 @@ struct OverFlowChecker<float, true>
template <typename PyIntEquiv>
struct Converter_PyInt
{
+ static inline bool checkType(PyObject* pyobj) { return PyNumber_Check(pyobj); }
static inline bool isConvertible(PyObject* pyobj) { return PyNumber_Check(pyobj); }
static inline PyObject* toPython(void* cppobj) { return toPython(*reinterpret_cast<PyIntEquiv*>(cppobj)); }
static inline PyObject* toPython(const PyIntEquiv& cppobj) { return PyInt_FromLong((long) cppobj); }
@@ -396,6 +409,7 @@ struct Converter_PyULongInt : Converter_PyInt<T>
template <typename CharType>
struct CharConverter
{
+ static inline bool checkType(PyObject* pyobj) { return SbkChar_Check(pyobj); }
static inline bool isConvertible(PyObject* pyobj) { return SbkChar_Check(pyobj); }
static inline PyObject* toPython(void* cppobj) { return toPython(*reinterpret_cast<CharType*>(cppobj)); }
static inline PyObject* toPython(const CharType& cppobj) { return PyInt_FromLong(cppobj); }
@@ -457,6 +471,7 @@ struct Converter<unsigned PY_LONG_LONG>
template <typename PyFloatEquiv>
struct Converter_PyFloat
{
+ static inline bool checkType(PyObject* obj) { return PyNumber_Check(obj); }
static inline bool isConvertible(PyObject* obj) { return PyNumber_Check(obj); }
static inline PyObject* toPython(void* cppobj) { return toPython(*reinterpret_cast<PyFloatEquiv*>(cppobj)); }
static inline PyObject* toPython(PyFloatEquiv cppobj) { return PyFloat_FromDouble((double) cppobj); }
@@ -475,6 +490,7 @@ template <> struct Converter<double> : Converter_PyFloat<double> {};
template <typename CppEnum>
struct EnumConverter
{
+ static inline bool checkType(PyObject* pyObj) { return PyObject_TypeCheck(pyObj, SbkType<CppEnum>()); }
static inline bool isConvertible(PyObject* pyObj) { return PyObject_TypeCheck(pyObj, SbkType<CppEnum>()); }
static inline PyObject* toPython(void* cppobj) { return toPython(*reinterpret_cast<CppEnum*>(cppobj)); }
static inline PyObject* toPython(CppEnum cppenum)
@@ -491,6 +507,7 @@ struct EnumConverter
template <typename CString>
struct Converter_CString
{
+ static inline bool checkType(PyObject* pyObj) { return PyString_Check(pyObj); }
static inline bool isConvertible(PyObject* pyObj) { return pyObj == Py_None || PyString_Check(pyObj); }
static inline PyObject* toPython(void* cppobj) { return toPython(reinterpret_cast<CString>(cppobj)); }
static inline PyObject* toPython(CString cppobj)
@@ -523,6 +540,11 @@ template <> struct Converter<const char*> : Converter_CString<const char*> {};
template <typename StdList>
struct StdListConverter
{
+ static inline bool checkType(PyObject* pyObj)
+ {
+ return isConvertible(pyObj);
+ }
+
static inline bool isConvertible(PyObject* pyObj)
{
if (PyObject_TypeCheck(pyObj, SbkType<StdList>()))
@@ -567,6 +589,11 @@ struct StdListConverter
template <typename StdPair>
struct StdPairConverter
{
+ static inline bool checkType(PyObject* pyObj)
+ {
+ return isConvertible(pyObj);
+ }
+
static inline bool isConvertible(PyObject* pyObj)
{
if (PyObject_TypeCheck(pyObj, SbkType<StdPair>()))
@@ -606,6 +633,11 @@ struct StdPairConverter
template <typename StdMap>
struct StdMapConverter
{
+ static inline bool checkType(PyObject* pyObj)
+ {
+ return isConvertible(pyObj);
+ }
+
static inline bool isConvertible(PyObject* pyObj)
{
if (PyObject_TypeCheck(pyObj, SbkType<StdMap>()))
diff --git a/shibokengenerator.cpp b/shibokengenerator.cpp
index 690490ce5..f2fd835c4 100644
--- a/shibokengenerator.cpp
+++ b/shibokengenerator.cpp
@@ -641,7 +641,7 @@ static QString checkFunctionName(QString baseName, bool genericNumberType, bool
.arg((checkExact && !genericNumberType ? "Exact" : ""));
}
-QString ShibokenGenerator::cpythonCheckFunction(const AbstractMetaType* metaType, bool genericNumberType, bool checkExact)
+QString ShibokenGenerator::cpythonCheckFunction(const AbstractMetaType* metaType, bool genericNumberType)
{
QString baseName = cpythonBaseName(metaType);
if (metaType->typeEntry()->isCustom()) {
@@ -653,7 +653,7 @@ QString ShibokenGenerator::cpythonCheckFunction(const AbstractMetaType* metaType
QTextStream s(&str);
writeBaseConversion(s, metaType, 0);
s.flush();
- return str + "isConvertible";
+ return str + "checkType";
}
}
@@ -679,8 +679,27 @@ QString ShibokenGenerator::guessCPythonCheckFunction(const QString& type)
return retval;
}
-QString ShibokenGenerator::cpythonIsConvertibleFunction(const TypeEntry* type)
+QString ShibokenGenerator::guessCPythonIsConvertible(const QString& type)
{
+ QString retval;
+ AbstractMetaType* metaType = buildAbstractMetaTypeFromString(type);
+ if (metaType) {
+ retval = cpythonIsConvertibleFunction(metaType);
+ delete metaType;
+ } else if (type == "PyTypeObject") {
+ retval = "PyType_Check";
+ } else {
+ retval = QString("%1_Check").arg(type);
+ }
+ return retval;
+}
+
+QString ShibokenGenerator::cpythonIsConvertibleFunction(const TypeEntry* type, bool genericNumberType, bool checkExact)
+{
+ if (checkExact)
+ return cpythonCheckFunction(type, genericNumberType, checkExact);
+ if (type->isCustom())
+ return guessCPythonIsConvertible(type->name());
QString baseName;
QTextStream s(&baseName);
writeBaseConversion(s, type);
@@ -689,18 +708,21 @@ QString ShibokenGenerator::cpythonIsConvertibleFunction(const TypeEntry* type)
return baseName;
}
-QString ShibokenGenerator::cpythonIsConvertibleFunction(const AbstractMetaType* metaType)
+QString ShibokenGenerator::cpythonIsConvertibleFunction(const AbstractMetaType* metaType, bool genericNumberType)
{
- QString baseName;
- QTextStream s(&baseName);
- if (metaType->isValuePointer() || metaType->typeEntry()->isObject()) {
- const AbstractMetaClass* context = classes().findClass(metaType->typeEntry()->name());
- writeBaseConversion(s, metaType, context);
+
+ QString baseName = cpythonBaseName(metaType);
+ if (metaType->typeEntry()->isCustom()) {
+ return guessCPythonCheckFunction(metaType->typeEntry()->name());
+ } else if (isNumber(baseName)) {
+ return genericNumberType ? "PyNumber_Check" : baseName+"_Check";
} else {
- writeBaseConversion(s, metaType->typeEntry());
+ QString str;
+ QTextStream s(&str);
+ writeBaseConversion(s, metaType, 0);
+ s.flush();
+ return str + "isConvertible";
}
- s << "isConvertible";
- s.flush();
return baseName;
}
diff --git a/shibokengenerator.h b/shibokengenerator.h
index 786ace335..3985c95be 100644
--- a/shibokengenerator.h
+++ b/shibokengenerator.h
@@ -247,13 +247,15 @@ public:
QString cpythonTypeName(const TypeEntry* type);
QString cpythonTypeNameExt(const TypeEntry* type);
QString cpythonCheckFunction(const TypeEntry* type, bool genericNumberType = false, bool checkExact = false);
- QString cpythonCheckFunction(const AbstractMetaType* metaType, bool genericNumberType = false, bool checkExact = false);
+ QString cpythonCheckFunction(const AbstractMetaType* metaType, bool genericNumberType = false);
QString guessCPythonCheckFunction(const QString& type);
- QString cpythonIsConvertibleFunction(const TypeEntry* type);
- QString cpythonIsConvertibleFunction(const AbstractMetaType* metaType);
- QString cpythonIsConvertibleFunction(const AbstractMetaArgument* metaArg) {
- return cpythonIsConvertibleFunction(metaArg->type());
+ QString cpythonIsConvertibleFunction(const TypeEntry* type, bool genericNumberType = false, bool checkExact = false);
+ QString cpythonIsConvertibleFunction(const AbstractMetaType* metaType, bool genericNumberType = false);
+ QString cpythonIsConvertibleFunction(const AbstractMetaArgument* metaArg, bool genericNumberType = false)
+ {
+ return cpythonIsConvertibleFunction(metaArg->type(), genericNumberType);
}
+ QString guessCPythonIsConvertible(const QString& type);
QString cpythonFunctionName(const AbstractMetaFunction* func);
QString cpythonMethodDefinitionName(const AbstractMetaFunction* func);
QString cpythonGettersSettersDefinitionName(const AbstractMetaClass* metaClass);
diff --git a/tests/samplebinding/reference_test.py b/tests/samplebinding/reference_test.py
index f00e036e0..0c373ffac 100755
--- a/tests/samplebinding/reference_test.py
+++ b/tests/samplebinding/reference_test.py
@@ -64,7 +64,7 @@ class ReferenceTest(unittest.TestCase):
def testCantSegFaultWhenReceiveNone(self):
'''do not segfault when receiving None as argument.'''
s = Str()
- self.assertEqual(None, s)
+ self.assertNotEqual(None, s)
def testMethodThatReceivesConstReference(self):
'''Test a method that receives a const reference to an object as argument.'''