Skip to content

Commit

Permalink
Make converter branch work on a Python3.2 setup.
Browse files Browse the repository at this point in the history
  • Loading branch information
hugopl authored and Marcelo Lira committed Dec 9, 2011
1 parent 04546e2 commit b757d81
Show file tree
Hide file tree
Showing 9 changed files with 120 additions and 43 deletions.
2 changes: 1 addition & 1 deletion generator/shibokengenerator.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -966,7 +966,7 @@ QString ShibokenGenerator::cpythonCheckFunction(const AbstractMetaType* metaType

if (isCppPrimitive(metaType)) {
if (isCString(metaType))
return "SbkString_Check";
return "Shiboken::String::check";
if (isVoidPointer(metaType))
return "PyObject_Check";
return cpythonCheckFunction(metaType->typeEntry(), genericNumberType);
Expand Down
2 changes: 1 addition & 1 deletion libshiboken/sbkconverter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -222,7 +222,7 @@ void nonePythonToCppNullPtr(PyObject*, void* cppOut)
void* cppPointer(PyTypeObject* desiredType, SbkObject* pyIn)
{
assert(pyIn);
SbkObjectType* inType = (SbkObjectType*)pyIn->ob_type;
SbkObjectType* inType = (SbkObjectType*)Py_TYPE(pyIn);
if (ObjectType::hasCast(inType))
return ObjectType::cast(inType, pyIn, desiredType);
return Object::cppPointer(pyIn, desiredType);
Expand Down
28 changes: 13 additions & 15 deletions libshiboken/sbkconverter_p.h
Original file line number Diff line number Diff line change
Expand Up @@ -23,10 +23,11 @@
#ifndef SBK_CONVERTER_P_H
#define SBK_CONVERTER_P_H

#include <Python.h>
#include "sbkpython.h"
#include "sbkconverter.h"
#include "sbkstring.h"
#include <list>
#include <limits>
#include "sbkconverter.h"

#include "sbkdbg.h"

Expand Down Expand Up @@ -169,10 +170,6 @@ struct TwoPrimitive : OnePrimitive<T>

// Integers --------------------------------------------------------------------------------

// Note: if there wasn't for the old-style classes, a simple PyNumber_Check would suffice.
#define SbkNumber_Check(X) (PyNumber_Check(X) \
&& (!PyInstance_Check(X) || PyObject_HasAttrString(X, "__trunc__")))

template <typename INT>
struct IntPrimitive : TwoPrimitive<INT>
{
Expand Down Expand Up @@ -327,11 +324,12 @@ struct CharPrimitive : IntPrimitive<CHAR>
{
static void toCpp(PyObject* pyIn, void* cppOut)
{
*((CHAR*)cppOut) = (CHAR) PyString_AS_STRING(pyIn)[0];

*((CHAR*)cppOut) = (CHAR) Shiboken::String::toCString(pyIn)[0];
}
static PythonToCppFunc isConvertible(PyObject* pyIn)
{
if (PyString_Check(pyIn) && PyString_Size(pyIn) == 1)
if (Shiboken::String::checkChar(pyIn))
return toCpp;
return 0;
}
Expand Down Expand Up @@ -361,7 +359,7 @@ template <> struct Primitive<unsigned char> : CharPrimitive<unsigned char> {};
template <> struct Primitive<char> : CharPrimitive<char> {
using CharPrimitive<char>::toPython;
static PyObject* toPython(const void* cppIn) {
return PyString_FromFormat("%c", *((const char*)cppIn));
return Shiboken::String::fromCString((const char*)cppIn, 1);
}
};

Expand All @@ -376,7 +374,7 @@ struct Primitive<const char*> : TwoPrimitive<const char*>
{
if (!cppIn)
Py_RETURN_NONE;
return PyString_FromString((const char*)cppIn);
return Shiboken::String::fromCString((const char*)cppIn);
}
static void toCpp(PyObject* pyIn, void* cppOut)
{
Expand All @@ -390,11 +388,11 @@ struct Primitive<const char*> : TwoPrimitive<const char*>
}
static void otherToCpp(PyObject* pyIn, void* cppOut)
{
*((const char**)cppOut) = (const char*) PyString_AsString(pyIn);
*((const char**)cppOut) = (const char*) Shiboken::String::toCString(pyIn);
}
static PythonToCppFunc isOtherConvertible(PyObject* pyIn)
{
if (PyString_Check(pyIn))
if (Shiboken::String::check(pyIn))
return otherToCpp;
return 0;
}
Expand All @@ -405,7 +403,7 @@ struct Primitive<std::string> : TwoPrimitive<std::string>
{
static PyObject* toPython(const void* cppIn)
{
return PyString_FromString(((std::string*)cppIn)->c_str());
return Shiboken::String::fromCString(((std::string*)cppIn)->c_str());
}
static void toCpp(PyObject* pyIn, void* cppOut)
{
Expand All @@ -419,11 +417,11 @@ struct Primitive<std::string> : TwoPrimitive<std::string>
}
static void otherToCpp(PyObject* pyIn, void* cppOut)
{
*((std::string*)cppOut) = std::string(PyString_AsString(pyIn));
*((std::string*)cppOut) = Shiboken::String::toCString(pyIn);
}
static PythonToCppFunc isOtherConvertible(PyObject* pyIn)
{
if (PyString_Check(pyIn))
if (Shiboken::String::check(pyIn))
return otherToCpp;
return 0;
}
Expand Down
1 change: 1 addition & 0 deletions libshiboken/sbkpython.h
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@
#define SBK_NB_BOOL(x) (x).nb_bool
#define SBK_PyMethod_New PyMethod_New
#define PyInt_AsSsize_t(x) PyLong_AsSsize_t(x)
#define PyString_Type PyUnicode_Type

#else
// Note: if there wasn't for the old-style classes, only a PyNumber_Check would suffice.
Expand Down
27 changes: 24 additions & 3 deletions libshiboken/sbkstring.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
*/

#include "sbkstring.h"
#include "autodecref.h"

namespace Shiboken
{
Expand Down Expand Up @@ -68,16 +69,36 @@ PyObject* fromCString(const char* value)
#endif
}

const char* toCString(PyObject* str)
PyObject* fromCString(const char* value, int len)
{
#ifdef IS_PY3K
return PyUnicode_FromStringAndSize(value, len);
#else
return PyBytes_FromStringAndSize(value, len);
#endif
}

const char* toCString(PyObject* str, Py_ssize_t* len)
{
if (str == Py_None)
return NULL;
#ifdef IS_PY3K
if (PyUnicode_Check(str))
if (PyUnicode_Check(str)) {
if (len) {
// We need to encode the unicode string into utf8 to know the size of returned char*.
Shiboken::AutoDecRef uniStr(PyUnicode_AsUTF8String(str));
*len = PyBytes_GET_SIZE(uniStr.object());
}
// Return unicode from str instead of uniStr, because the lifetime of the returned pointer
// depends on the lifetime of str.
return _PyUnicode_AsString(str);
}
#endif
if (PyBytes_Check(str))
if (PyBytes_Check(str)) {
if (len)
*len = PyBytes_GET_SIZE(str);
return PyBytes_AS_STRING(str);
}
return 0;
}

Expand Down
3 changes: 2 additions & 1 deletion libshiboken/sbkstring.h
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,8 @@ namespace String
LIBSHIBOKEN_API bool checkChar(PyObject* obj);
LIBSHIBOKEN_API bool isConvertible(PyObject* obj);
LIBSHIBOKEN_API PyObject* fromCString(const char* value);
LIBSHIBOKEN_API const char* toCString(PyObject* str);
LIBSHIBOKEN_API PyObject* fromCString(const char* value, int len);
LIBSHIBOKEN_API const char* toCString(PyObject* str, Py_ssize_t* len = 0);
LIBSHIBOKEN_API bool concat(PyObject** val1, PyObject* val2);
LIBSHIBOKEN_API PyObject* fromFormat(const char* format, ...);
LIBSHIBOKEN_API PyObject* fromStringAndSize(const char* str, Py_ssize_t size);
Expand Down
6 changes: 2 additions & 4 deletions tests/samplebinding/injectcode_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -94,14 +94,12 @@ def testUsageOfTypeSystemCheckVariableOnPrimitiveType(self):
'''When the sequence item is convertible to an integer -1 is returned, or -2 if its not convertible.'''
ic = InjectCode()
values = (1, 2, 3, 4, '5', 6.7)
print values
result = ic.arrayMethod(values)
print result

fixedValues = [v for v in values if isinstance(v, int)]\
+ [-1 for v in values if isinstance(v, float)]\
+ [-2 for v in values if not isinstance(v, int) and not isinstance(v, float)]
print fixedValues
#self.assertEqual(result, sum(fixedValues))
self.assertEqual(result, sum(fixedValues))


class IntArrayTest(unittest.TestCase):
Expand Down
16 changes: 15 additions & 1 deletion tests/samplebinding/primitivestructpointer_conversions.h
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,11 @@ struct Converter<PrimitiveStructPtr>

static bool isConvertible(PyObject* pyobj)
{
#ifdef IS_PY3K
return PyCapsule_CheckExact(pyobj);
#else
return PyCObject_Check(pyobj);
#endif
}

static inline PyObject* toPython(void* cppobj)
Expand All @@ -19,12 +23,22 @@ struct Converter<PrimitiveStructPtr>

static PyObject* toPython(PrimitiveStructPtr cppobj)
{
#ifdef IS_PY3K
return PyCapsule_New(cppobj, 0, 0);
#else
return PyCObject_FromVoidPtr(cppobj, 0);
#endif
}

static PrimitiveStructPtr toCpp(PyObject* pyobj)
{
return (PrimitiveStructPtr) PyCObject_AsVoidPtr(pyobj);
void* ptr;
#ifdef IS_PY3K
ptr = PyCapsule_GetPointer(pyobj, 0);
#else
ptr = PyCObject_AsVoidPtr(pyobj);
#endif
return (PrimitiveStructPtr) ptr;
}
};
}
78 changes: 61 additions & 17 deletions tests/samplebinding/typesystem_sample.xml
Original file line number Diff line number Diff line change
Expand Up @@ -68,25 +68,61 @@
<include file-name="handle.h" location="local"/>
<conversion-rule file="handle_conversions.h">
<native-to-target>
return PyCObject_FromVoidPtr(%in, 0);
if (!%in)
Py_RETURN_NONE;
#ifdef IS_PY3K
return PyCapsule_New(%in, 0, 0);
#else
return PyCObject_FromVoidPtr(%in, 0);
#endif
</native-to-target>
<target-to-native>
<add-conversion type="PyCObject">
%out = (%OUTTYPE)PyCObject_AsVoidPtr(%in);
<add-conversion type="PyNone">
%out = 0;
</add-conversion>
<add-conversion check="checkPyCapsuleOrPyCObject(%in)" type="PyObject">
void* ptr;
#ifdef IS_PY3K
ptr = PyCapsule_GetPointer(%in, 0);
#else
ptr = PyCObject_AsVoidPtr(%in);
#endif
%out = *((%OUTTYPE*)ptr);
</add-conversion>
</target-to-native>
</conversion-rule>
</primitive-type>

<inject-code class="native" position="beginning">
static bool checkPyCapsuleOrPyCObject(PyObject* pyObj)
{
#ifdef IS_PY3K
return PyCapsule_CheckExact(pyObj);
#else
return PyCObject_Check(pyObj);
#endif
}
</inject-code>

<primitive-type name="PrimitiveStructPtr">
<include file-name="handle.h" location="local"/>
<conversion-rule file="primitivestructpointer_conversions.h">
<native-to-target>
return PyCObject_FromVoidPtr(&amp;%in, 0);
#ifdef IS_PY3K
return PyCapsule_New(&amp;%in, 0, 0);
#else
return PyCObject_FromVoidPtr(&amp;%in, 0);
#endif
</native-to-target>
<target-to-native>
<add-conversion type="PyCObject">
%out = *((%OUTTYPE*)PyCObject_AsVoidPtr(%in));
<add-conversion check="checkPyCapsuleOrPyCObject(%in)" type="PyObject">
void* ptr;
#ifdef IS_PY3K
ptr = PyCapsule_GetPointer(%in, 0);
#else
ptr = PyCObject_AsVoidPtr(%in);
#endif
%out = *((%OUTTYPE*)ptr);
</add-conversion>
</target-to-native>
</conversion-rule>
Expand Down Expand Up @@ -118,10 +154,10 @@
<include file-name="str.h" location="global"/>
<conversion-rule>
<native-to-target>
return PyString_FromStringAndSize(%in.cstring(), %in.size());
return Shiboken::String::fromCString(%in.cstring(), %in.size());
</native-to-target>
<target-to-native>
<add-conversion type="PyString">
<add-conversion type="PyUnicode" check="Shiboken::String::check(%in)">
const char* str = %CONVERTTOCPP[const char*](%in);
%out = %OUTTYPE(str);
</add-conversion>
Expand Down Expand Up @@ -1820,14 +1856,16 @@
<add-conversion type="Py_None">
%out = %OUTTYPE();
</add-conversion>
<add-conversion type="PyString">
%out = %OUTTYPE(PyString_AS_STRING(%in), PyString_GET_SIZE(%in));
<add-conversion type="PyObject" check="Shiboken::String::check(%in) || PyBytes_Check(%in)">
Py_ssize_t len;
const char* str = Shiboken::String::toCString(%in, &amp;len);
%out = %OUTTYPE(str, len);
</add-conversion>
</target-to-native>
</conversion-rule>

<modify-function signature="ByteArray(const char*,int)" remove="all" />
<modify-function signature="ByteArray(const char*)">
<modify-function signature="ByteArray(const char*)" remove="all" >
<!-- Keep \x00 bytes passed in Python strings. -->
<modify-argument index="1">
<replace-type modified-type="PyBytes"/>
Expand Down Expand Up @@ -1862,6 +1900,7 @@
</modify-function>

<modify-function signature="hash(const ByteArray&amp;)" remove="all" />
<!-- Functions removed to proper deal with strings containing zeroes -->
<modify-function signature="append(const char*)" remove="all" />
<modify-function signature="append(const char*,int)" remove="all" />
<modify-function signature="operator==(const char*,ByteArray)" remove="all" />
Expand Down Expand Up @@ -1909,12 +1948,17 @@
</add-function>
<add-function signature="__repr__" return-type="PyObject*">
<inject-code class="target" position="beginning">
ByteArray ba(((PyObject*)%PYSELF)->ob_type->tp_name);
ba += '(';
Shiboken::AutoDecRef contents(PyObject_Repr(PyBytes_FromStringAndSize(%CPPSELF.data(), %CPPSELF.size())));
ba += PyBytes_AS_STRING(contents.object());
ba += ")";
%PYARG_0 = PyBytes_FromStringAndSize(ba.data(), ba.size());
ByteArray b(((PyObject*)%PYSELF)->ob_type->tp_name);
PyObject* aux = Shiboken::String::fromStringAndSize(%CPPSELF.data(), %CPPSELF.size());
if (PyUnicode_CheckExact(aux)) {
PyObject* tmp = PyUnicode_AsASCIIString(aux);
Py_DECREF(aux);
aux = tmp;
}
b += "('";
b += ByteArray(PyBytes_AS_STRING(aux), PyBytes_GET_SIZE(aux));
b += "')";
%PYARG_0 = Shiboken::String::fromStringAndSize(b.data(), b.size());
</inject-code>
</add-function>

Expand Down

0 comments on commit b757d81

Please sign in to comment.