diff --git a/CMakeLists.txt b/CMakeLists.txt
index 4b689af..3a27eae 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -44,11 +44,11 @@ endif()
#-----------------------------------------------------------------------------
# Generator
-#if(PythonQt_Qt5)
-# add_subdirectory(generator_50 EXCLUDE_FROM_ALL)
-# add_custom_target(generator)
-# add_dependencies(generator pythonqt_generator)
-#endif()
+if(PythonQt_Qt5)
+ add_subdirectory(generator_50 EXCLUDE_FROM_ALL)
+ add_custom_target(generator)
+ add_dependencies(generator pythonqt_generator)
+endif()
# TODO
@@ -107,7 +107,6 @@ endif()
option(PythonQt_Python3 "Use Python 3.x (3.3+)" OFF)
if(PythonQt_Python3)
set(PythonQt_PythonMin 3.3)
- add_definitions(PYTHON3K)
else(PythonQt_Python3)
set(PythonQt_PythonMin 2.6)
endif()
diff --git a/generated_cpp_50/com_trolltech_qt_core_builtin/com_trolltech_qt_core_builtin0.h b/generated_cpp_50/com_trolltech_qt_core_builtin/com_trolltech_qt_core_builtin0.h
index 0aff7b0..8bcd2ef 100644
--- a/generated_cpp_50/com_trolltech_qt_core_builtin/com_trolltech_qt_core_builtin0.h
+++ b/generated_cpp_50/com_trolltech_qt_core_builtin/com_trolltech_qt_core_builtin0.h
@@ -174,7 +174,11 @@ void delete_QByteArray(QByteArray* obj) { delete obj; }
PyObject* data(QByteArray* b) {
if (b->data()) {
+#ifdef PY3K
+ return PyUnicode_FromStringAndSize(b->data(), b->size());
+#else
return PyString_FromStringAndSize(b->data(), b->size());
+#endif
} else {
Py_INCREF(Py_None);
return Py_None;
diff --git a/generator_50/typesystem_core.xml b/generator_50/typesystem_core.xml
index 52bde3d..5de2425 100644
--- a/generator_50/typesystem_core.xml
+++ b/generator_50/typesystem_core.xml
@@ -1426,7 +1426,7 @@
-
+
@@ -1439,7 +1439,7 @@
-
+
@@ -1447,7 +1447,7 @@
-
+
@@ -1505,14 +1505,6 @@
-
-
-
-
- QFile & %out% = *qscriptvalue_cast<QFile*>(%in%);
-
-
-
diff --git a/generator_50/typesystem_gui.xml b/generator_50/typesystem_gui.xml
index e53e876..a6aef44 100644
--- a/generator_50/typesystem_gui.xml
+++ b/generator_50/typesystem_gui.xml
@@ -1200,14 +1200,6 @@
-
-QImage* new_QImage( const uchar * data, int width, int height, QImage::Format format )
-{
- QImage* image = new QImage(width, height, format);
- memcpy(image->bits(), data, image->byteCount());
- return image;
-}
-
@@ -2101,23 +2093,31 @@ QImage* new_QImage( const uchar * data, int width, int height, QImage::Format fo
-
- QAction* addAction (QMenu* menu, const QString & text, PyObject* callable, const QKeySequence & shortcut = 0) {
- QAction* a = menu->addAction(text);
- a->setShortcut(shortcut);
- PythonQt::self()->addSignalHandler(a, SIGNAL(triggered(bool)), callable);
- return a;
- }
+
+
+
- QAction* addAction (QMenu* menu, const QIcon& icon, const QString& text, PyObject* callable, const QKeySequence& shortcut = 0)
- {
- QAction* a = menu->addAction(text);
- a->setIcon(icon);
- a->setShortcut(shortcut);
- PythonQt::self()->addSignalHandler(a, SIGNAL(triggered(bool)), callable);
- return a;
- }
-
+
+
+
+
+
+ QAction* addAction (QMenu* menu, const QString & text, PyObject* callable, const QKeySequence & shortcut = 0) {
+ QAction* a = menu->addAction(text);
+ a->setShortcut(shortcut);
+ PythonQt::self()->addSignalHandler(a, SIGNAL(triggered(bool)), callable);
+ return a;
+ }
+
+ QAction* addAction (QMenu* menu, const QIcon& icon, const QString& text, PyObject* callable, const QKeySequence& shortcut = 0)
+ {
+ QAction* a = menu->addAction(text);
+ a->setIcon(icon);
+ a->setShortcut(shortcut);
+ PythonQt::self()->addSignalHandler(a, SIGNAL(triggered(bool)), callable);
+ return a;
+ }
+
@@ -2158,14 +2158,15 @@ QImage* new_QImage( const uchar * data, int width, int height, QImage::Format fo
-
- QAction* addAction (QMenuBar* menu, const QString & text, PyObject* callable)
- {
- QAction* a = menu->addAction(text);
- PythonQt::self()->addSignalHandler(a, SIGNAL(triggered(bool)), callable);
- return a;
- }
-
+
+
+ QAction* addAction (QMenuBar* menu, const QString & text, PyObject* callable)
+ {
+ QAction* a = menu->addAction(text);
+ PythonQt::self()->addSignalHandler(a, SIGNAL(triggered(bool)), callable);
+ return a;
+ }
+
@@ -4887,22 +4888,23 @@ QImage* new_QImage( const uchar * data, int width, int height, QImage::Format fo
-
- QAction* addAction (QToolBar* menu, const QString & text, PyObject* callable)
- {
- QAction* a = menu->addAction(text);
- PythonQt::self()->addSignalHandler(a, SIGNAL(triggered(bool)), callable);
- return a;
- }
-
- QAction* addAction (QToolBar* menu, const QIcon& icon, const QString& text, PyObject* callable)
- {
- QAction* a = menu->addAction(text);
- a->setIcon(icon);
- PythonQt::self()->addSignalHandler(a, SIGNAL(triggered(bool)), callable);
- return a;
- }
-
+
+
+ QAction* addAction (QToolBar* menu, const QString & text, PyObject* callable)
+ {
+ QAction* a = menu->addAction(text);
+ PythonQt::self()->addSignalHandler(a, SIGNAL(triggered(bool)), callable);
+ return a;
+ }
+
+ QAction* addAction (QToolBar* menu, const QIcon& icon, const QString& text, PyObject* callable)
+ {
+ QAction* a = menu->addAction(text);
+ a->setIcon(icon);
+ PythonQt::self()->addSignalHandler(a, SIGNAL(triggered(bool)), callable);
+ return a;
+ }
+
@@ -5665,6 +5667,7 @@ QImage* new_QImage( const uchar * data, int width, int height, QImage::Format fo
+
diff --git a/generator_50/typesystem_opengl.xml b/generator_50/typesystem_opengl.xml
index 11e102c..70c250b 100644
--- a/generator_50/typesystem_opengl.xml
+++ b/generator_50/typesystem_opengl.xml
@@ -9,11 +9,6 @@
-
-
-
-
-
@@ -32,8 +27,6 @@
-
-
diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt
index 7524182..97ee1f6 100644
--- a/src/CMakeLists.txt
+++ b/src/CMakeLists.txt
@@ -87,9 +87,9 @@ qt_add_resources(GEN_QRC ${SOURCES_QRC})
include_directories(${CMAKE_CURRENT_SOURCE_DIR})
-add_definitions(-DQT_NO_KEYWORDS) # recent python versions use them :(
+#add_definitions(-DQT_NO_KEYWORDS) # recent python versions use them :(
-add_library(PythonQt SHARED ${SOURCES} ${GEN_MOC} ${GEN_QRC})
+add_library(PythonQt SHARED ${SOURCES} ${GEN_MOC} ${GEN_QRC} ${HEADERS})
if(PythonQt_Qt5)
qt_use_modules(PythonQt Core Gui Widgets)
else()
diff --git a/src/PythonQt.cpp b/src/PythonQt.cpp
index d0ec843..15cb5ee 100644
--- a/src/PythonQt.cpp
+++ b/src/PythonQt.cpp
@@ -166,7 +166,11 @@ PythonQt::PythonQt(int flags, const QByteArray& pythonQtModuleName)
_p->_PythonQtObjectPtr_metaId = qRegisterMetaType("PythonQtObjectPtr");
if ((flags & PythonAlreadyInitialized) == 0) {
+#ifdef PY3K
+ Py_SetProgramName(const_cast(L"PythonQt"));
+#else
Py_SetProgramName(const_cast("PythonQt"));
+#endif
if (flags & IgnoreSiteModule) {
// this prevents the automatic importing of Python site files
Py_NoSiteFlag = 1;
@@ -496,7 +500,11 @@ PyObject* PythonQtPrivate::dummyTuple() {
static PyObject* dummyTuple = NULL;
if (dummyTuple==NULL) {
dummyTuple = PyTuple_New(1);
+#ifdef PY3K
+ PyTuple_SET_ITEM(dummyTuple, 0, PyUnicode_FromString("dummy"));
+#else
PyTuple_SET_ITEM(dummyTuple, 0 , PyString_FromString("dummy"));
+#endif
}
return dummyTuple;
}
@@ -526,7 +534,11 @@ PythonQtInstanceWrapper* PythonQtPrivate::createNewPythonQtInstanceWrapper(QObje
PythonQtClassWrapper* PythonQtPrivate::createNewPythonQtClassWrapper(PythonQtClassInfo* info, PyObject* parentModule) {
PythonQtClassWrapper* result;
+#ifdef PY3K
+ PyObject* className = PyUnicode_FromString(info->className());
+#else
PyObject* className = PyString_FromString(info->className());
+#endif
PyObject* baseClasses = PyTuple_New(1);
PyTuple_SET_ITEM(baseClasses, 0, (PyObject*)&PythonQtInstanceWrapper_Type);
@@ -561,10 +573,18 @@ PyObject* PythonQtPrivate::createEnumValueInstance(PyObject* enumType, unsigned
PyObject* PythonQtPrivate::createNewPythonQtEnumWrapper(const char* enumName, PyObject* parentObject) {
PyObject* result;
+#ifdef PY3K
+ PyObject* className = PyUnicode_FromString(enumName);
+#else
PyObject* className = PyString_FromString(enumName);
+#endif
PyObject* baseClasses = PyTuple_New(1);
+#ifdef PY3K
+ PyTuple_SET_ITEM(baseClasses, 0, (PyObject*)&PyLong_Type);
+#else
PyTuple_SET_ITEM(baseClasses, 0, (PyObject*)&PyInt_Type);
+#endif
PyObject* module = PyObject_GetAttrString(parentObject, "__module__");
PyObject* typeDict = PyDict_New();
@@ -703,11 +723,21 @@ QVariant PythonQt::evalCode(PyObject* object, PyObject* pycode) {
globals = dict;
} else {
dict = PyObject_GetAttrString(object, "__dict__");
- globals = PyObject_GetAttrString(PyImport_ImportModule(PyString_AS_STRING(PyObject_GetAttrString(object, "__module__"))),"__dict__");
+ globals = PyObject_GetAttrString(PyImport_ImportModule(
+#ifdef PY3K
+ PyUnicode_AsUTF8(
+#else
+ PyString_AS_STRING(
+#endif
+ PyObject_GetAttrString(object, "__module__"))),"__dict__");
}
PyObject* r = NULL;
if (dict) {
+#ifdef PY3K
+ r = PyEval_EvalCode(pycode, globals, dict);
+#else
r = PyEval_EvalCode((PyCodeObject*)pycode, globals , dict);
+#endif
}
if (r) {
result = PythonQtConv::PyObjToQVariant(r);
@@ -894,7 +924,11 @@ QStringList PythonQt::introspectObject(PyObject* object, ObjectType type)
} else {
PyObject* doc = PyObject_GetAttrString(object, "__doc__");
if (doc) {
+#ifdef PY3K
+ results << PyUnicode_AsUTF8(doc);
+#else
results << PyString_AsString(doc);
+#endif
Py_DECREF(doc);
}
}
@@ -922,7 +956,11 @@ QStringList PythonQt::introspectObject(PyObject* object, ObjectType type)
value = PyObject_GetAttr(object, key);
}
if (!value) continue;
+#ifdef PY3K
+ keystr = PyUnicode_AsUTF8(key);
+#else
keystr = PyString_AsString(key);
+#endif
static const QString underscoreStr("__tmp");
if (!keystr.startsWith(underscoreStr)) {
switch (type) {
@@ -930,18 +968,25 @@ QStringList PythonQt::introspectObject(PyObject* object, ObjectType type)
results << keystr;
break;
case Class:
+#ifdef PY3K
+ if(PyType_Check(value)) {
+#else
if (value->ob_type == &PyClass_Type || value->ob_type == &PyType_Type) {
+#endif
results << keystr;
}
break;
case Variable:
- if (value->ob_type != &PyClass_Type
- && value->ob_type != &PyCFunction_Type
- && value->ob_type != &PyFunction_Type
- && value->ob_type != &PyMethod_Type
- && value->ob_type != &PyModule_Type
- && value->ob_type != &PyType_Type
- && value->ob_type != &PythonQtSlotFunction_Type
+ if (
+#ifndef PY3K
+ value->ob_type != &PyClass_Type &&
+#endif
+ value->ob_type != &PyCFunction_Type &&
+ value->ob_type != &PyFunction_Type &&
+ value->ob_type != &PyMethod_Type &&
+ value->ob_type != &PyModule_Type &&
+ value->ob_type != &PyType_Type &&
+ value->ob_type != &PythonQtSlotFunction_Type
) {
results << keystr;
}
@@ -1282,8 +1327,12 @@ int custom_system_exit_exception_handler()
// return exitcode;
PyErr_Fetch(&exception, &value, &tb);
+#ifdef PY3K
+ std::cout << std::endl;
+#else
if (Py_FlushLine())
PyErr_Clear();
+#endif
fflush(stdout);
if (value == NULL || value == Py_None)
goto done;
@@ -1299,8 +1348,13 @@ int custom_system_exit_exception_handler()
/* If we failed to dig out the 'code' attribute,
just let the else clause below print the error. */
}
+#ifdef PY3K
+ if (PyLong_Check(value))
+ exitcode = (int)PyLong_AsLong(value);
+#else
if (PyInt_Check(value))
exitcode = (int)PyInt_AsLong(value);
+#endif
else {
PyObject *sys_stderr = PySys_GetObject(const_cast("stderr"));
if (sys_stderr != NULL && sys_stderr != Py_None) {
@@ -1437,13 +1491,32 @@ static PyMethodDef PythonQtMethods[] = {
{NULL, NULL, 0, NULL}
};
+#ifdef PY3K
+static PyModuleDef PythonQtModule = {
+ PyModuleDef_HEAD_INIT,
+ "",
+ NULL,
+ -1,
+ PythonQtMethods,
+ NULL,
+ NULL,
+ NULL,
+ NULL
+};
+#endif
+
void PythonQt::initPythonQtModule(bool redirectStdOut, const QByteArray& pythonQtModuleName)
{
QByteArray name = "PythonQt";
if (!pythonQtModuleName.isEmpty()) {
name = pythonQtModuleName;
}
+#ifdef PY3K
+ PythonQtModule.m_name = name.constData();
+ _p->_pythonQtModule = PyModule_Create(&PythonQtModule);
+#else
_p->_pythonQtModule = Py_InitModule(name.constData(), PythonQtMethods);
+#endif
_p->_pythonQtModuleName = name;
if (redirectStdOut) {
@@ -1469,7 +1542,11 @@ void PythonQt::initPythonQtModule(bool redirectStdOut, const QByteArray& pythonQ
PyObject *module_names = PyTuple_New(old_size+1);
for(Py_ssize_t i = 0; i < old_size; i++)
PyTuple_SetItem(module_names, i, PyTuple_GetItem(old_module_names, i));
+#ifdef PY3K
+ PyTuple_SetItem(module_names, old_size, PyUnicode_FromString(name.constData()));
+#else
PyTuple_SetItem(module_names, old_size, PyString_FromString(name.constData()));
+#endif
PyModule_AddObject(sys.object(),"builtin_module_names",module_names);
Py_DecRef(old_module_names);
}
@@ -1512,7 +1589,11 @@ QString PythonQt::getReturnTypeOfWrappedMethodHelper(const PythonQtObjectPtr& va
QString type;
+#ifdef PY3K
+ if (PyType_Check(methodObject)) {
+#else
if (methodObject->ob_type == &PyClass_Type || methodObject->ob_type == &PyType_Type) {
+#endif
// the methodObject is not a method, but the name of a type/class. This means
// a constructor is called. Return the context.
type = context;
@@ -1525,8 +1606,13 @@ QString PythonQt::getReturnTypeOfWrappedMethodHelper(const PythonQtObjectPtr& va
} else {
PyObject* classNameObject = PyObject_GetAttrString(variableObject, "__name__");
if (classNameObject) {
+#ifdef PY3K
+ Q_ASSERT(PyUnicode_Check(classNameObject));
+ className = PyUnicode_AsUTF8(classNameObject);
+#else
Q_ASSERT(PyString_Check(classNameObject));
className = PyString_AsString(classNameObject);
+#endif
Py_DECREF(classNameObject);
}
}
@@ -1559,11 +1645,20 @@ QString PythonQt::getReturnTypeOfWrappedMethodHelper(const PythonQtObjectPtr& va
PythonQtClassInfo* typeInfo = _p->_knownClassInfos.value(type.toLatin1().constData());
if (typeInfo && typeInfo->pythonQtClassWrapper()) {
PyObject* s = PyObject_GetAttrString(typeInfo->pythonQtClassWrapper(), "__module__");
+#ifdef PY3K
+ Q_ASSERT(PyUnicode_Check(s));
+ type = QString(PyUnicode_AsUTF8(s));
+#else
Q_ASSERT(PyString_Check(s));
type = QString(PyString_AsString(s)) + "." + type;
+#endif
Py_DECREF(s);
s = PyObject_GetAttrString(typeInfo->pythonQtClassWrapper(), "__name__");
+#ifdef PY3K
+ Q_ASSERT(PyUnicode_Check(s));
+#else
Q_ASSERT(PyString_Check(s));
+#endif
Py_DECREF(s);
}
}
@@ -1668,7 +1763,11 @@ PyObject* PythonQt::helpCalled(PythonQtClassInfo* info)
Q_EMIT pythonHelpRequest(QByteArray(info->className()));
return Py_BuildValue("");
} else {
+#ifdef PY3K
+ return PyUnicode_FromString(info->help().toLatin1().data());
+#else
return PyString_FromString(info->help().toLatin1().data());
+#endif
}
}
@@ -1743,8 +1842,11 @@ bool PythonQtPrivate::isMethodDescriptor(PyObject* object) const
if (PyObject_HasAttrString(object, "__get__") &&
!PyObject_HasAttrString(object, "__set__") &&
!PyMethod_Check(object) &&
- !PyFunction_Check(object) &&
- !PyClass_Check(object)) {
+ !PyFunction_Check(object)
+#ifndef PY3K
+ && !PyClass_Check(object)
+#endif
+ ) {
return true;
}
return false;
@@ -1760,7 +1862,11 @@ QString PythonQtPrivate::getSignature(PyObject* object)
bool decrefMethod = false;
+#ifdef PY3K
+ if (PyType_Check(object)) {
+#else
if (object->ob_type == &PyClass_Type || object->ob_type == &PyType_Type) {
+#endif
method = (PyMethodObject*)PyObject_GetAttrString(object, "__init__");
decrefMethod = true;
} else if (object->ob_type == &PyFunction_Type) {
@@ -1775,14 +1881,23 @@ QString PythonQtPrivate::getSignature(PyObject* object)
QString docstr;
PyObject* doc = PyObject_GetAttrString(object, "__doc__");
if (doc) {
+#ifdef PY3K
+ docstr = PyUnicode_AsUTF8(doc);
+#else
docstr = PyString_AsString(doc);
+#endif
Py_DECREF(doc);
}
PyObject* s = PyObject_GetAttrString(object, "__name__");
if (s) {
+#ifdef PY3K
+ Q_ASSERT(PyUnicode_Check(s));
+ signature = PyUnicode_AsUTF8(s);
+#else
Q_ASSERT(PyString_Check(s));
signature = PyString_AsString(s);
+#endif
if (docstr.startsWith(signature + "(")) {
signature = docstr;
} else {
@@ -1800,15 +1915,25 @@ QString PythonQtPrivate::getSignature(PyObject* object)
QString funcName;
PyObject* s = PyObject_GetAttrString((PyObject*)func, "__name__");
if (s) {
+#ifdef PY3K
+ Q_ASSERT(PyUnicode_Check(s));
+ funcName = PyUnicode_AsUTF8(s);
+#else
Q_ASSERT(PyString_Check(s));
funcName = PyString_AsString(s);
+#endif
Py_DECREF(s);
}
if (method && funcName == "__init__") {
PyObject* s = PyObject_GetAttrString(object, "__name__");
if (s) {
+#ifdef PY3K
+ Q_ASSERT(PyUnicode_Check(s));
+ funcName = PyUnicode_AsUTF8(s);
+#else
Q_ASSERT(PyString_Check(s));
funcName = PyString_AsString(s);
+#endif
Py_DECREF(s);
}
}
@@ -1826,19 +1951,34 @@ QString PythonQtPrivate::getSignature(PyObject* object)
Q_ASSERT(PyTuple_Check(code->co_varnames));
for (int i=0; ico_varnames, i);
+#ifdef PY3K
+ Q_ASSERT(PyUnicode_Check(name));
+ arguments << PyUnicode_AsUTF8(name);
+#else
Q_ASSERT(PyString_Check(name));
arguments << PyString_AsString(name);
+#endif
}
if (code->co_flags & CO_VARARGS) {
PyObject* s = PyTuple_GetItem(code->co_varnames, nargs);
+#ifdef PY3K
+ Q_ASSERT(PyUnicode_Check(s));
+ varargs = PyUnicode_AsUTF8(s);
+#else
Q_ASSERT(PyString_Check(s));
varargs = PyString_AsString(s);
+#endif
nargs += 1;
}
if (code->co_flags & CO_VARKEYWORDS) {
PyObject* s = PyTuple_GetItem(code->co_varnames, nargs);
+#ifdef PY3K
+ Q_ASSERT(PyUnicode_Check(s));
+ varkeywords = PyUnicode_AsUTF8(s);
+#else
Q_ASSERT(PyString_Check(s));
varkeywords = PyString_AsString(s);
+#endif
}
}
@@ -1848,8 +1988,13 @@ QString PythonQtPrivate::getSignature(PyObject* object)
for (Py_ssize_t i=0; i_base.as_number.nb_multiply = (binaryfunc)PythonQtInstanceWrapper_mul;
}
if (typeSlots & PythonQt::Type_Divide) {
+#ifndef PY3K
wrap->_base.as_number.nb_divide = (binaryfunc)PythonQtInstanceWrapper_div;
+#endif
wrap->_base.as_number.nb_true_divide = (binaryfunc)PythonQtInstanceWrapper_div;
}
if (typeSlots & PythonQt::Type_And) {
@@ -188,7 +190,9 @@ static void initializeSlots(PythonQtClassWrapper* wrap)
wrap->_base.as_number.nb_multiply = (binaryfunc)PythonQtInstanceWrapper_imul;
}
if (typeSlots & PythonQt::Type_InplaceDivide) {
+#ifndef PY3K
wrap->_base.as_number.nb_inplace_divide = (binaryfunc)PythonQtInstanceWrapper_idiv;
+#endif
wrap->_base.as_number.nb_inplace_true_divide = (binaryfunc)PythonQtInstanceWrapper_idiv;
}
if (typeSlots & PythonQt::Type_InplaceAnd) {
@@ -213,7 +217,11 @@ static void initializeSlots(PythonQtClassWrapper* wrap)
wrap->_base.as_number.nb_invert = (unaryfunc)PythonQtInstanceWrapper_invert;
}
if (typeSlots & PythonQt::Type_NonZero) {
+#ifdef PY3K
+ wrap->_base.as_number.nb_bool = (inquiry)PythonQtInstanceWrapper_nonzero;
+#else
wrap->_base.as_number.nb_nonzero = (inquiry)PythonQtInstanceWrapper_nonzero;
+#endif
}
}
}
@@ -252,10 +260,10 @@ static int PythonQtClassWrapper_init(PythonQtClassWrapper* self, PyObject* args,
// ...
// class MyWidget(MyWidgetBase):
// ...
- while( superType && superType->ob_type != &PythonQtClassWrapper_Type )
+ while( superType && Py_TYPE(superType) != &PythonQtClassWrapper_Type )
superType = superType->tp_base;
- if (!superType || (superType->ob_type != &PythonQtClassWrapper_Type)) {
+ if (!superType || (Py_TYPE(superType) != &PythonQtClassWrapper_Type)) {
PyErr_Format(PyExc_TypeError, "type %s is not derived from PythonQtClassWrapper", ((PyTypeObject*)self)->tp_name);
return -1;
}
@@ -269,7 +277,11 @@ static int PythonQtClassWrapper_init(PythonQtClassWrapper* self, PyObject* args,
static PyObject *PythonQtClassWrapper_classname(PythonQtClassWrapper* type)
{
+#ifdef PY3K
+ return PyUnicode_FromString((QString("Class_") + type->classInfo()->className()).toLatin1().data());
+#else
return PyString_FromString((QString("Class_") + type->classInfo()->className()).toLatin1().data());
+#endif
}
static PyObject *PythonQtClassWrapper_help(PythonQtClassWrapper* type)
@@ -325,7 +337,11 @@ static PyObject *PythonQtClassWrapper_getattro(PyObject *obj, PyObject *name)
const char *attributeName;
PythonQtClassWrapper *wrapper = (PythonQtClassWrapper *)obj;
+#ifdef PY3K
+ if ((attributeName = PyUnicode_AsUTF8(name)) == NULL) {
+#else
if ((attributeName = PyString_AsString(name)) == NULL) {
+#endif
return NULL;
}
if (obj == (PyObject*)&PythonQtInstanceWrapper_Type) {
@@ -352,7 +368,11 @@ static PyObject *PythonQtClassWrapper_getattro(PyObject *obj, PyObject *name)
}
}
if (wrapper->classInfo()->constructors()) {
+#ifdef PY3K
+ PyObject* initName = PyUnicode_FromString("__init__");
+#else
PyObject* initName = PyString_FromString("__init__");
+#endif
PyObject* func = PyType_Type.tp_getattro(obj, initName);
Py_DECREF(initName);
PyDict_SetItemString(dict, "__init__", func);
@@ -369,6 +389,9 @@ static PyObject *PythonQtClassWrapper_getattro(PyObject *obj, PyObject *name)
}
// look in Python to support derived Python classes
+#ifdef PY3K
+ return PyObject_GenericGetAttr(obj, name);
+#else
PyObject* superAttr = PyType_Type.tp_getattro(obj, name);
if (superAttr) {
return superAttr;
@@ -403,6 +426,7 @@ static PyObject *PythonQtClassWrapper_getattro(PyObject *obj, PyObject *name)
QString error = QString(wrapper->classInfo()->className()) + " has no attribute named '" + QString(attributeName) + "'";
PyErr_SetString(PyExc_AttributeError, error.toLatin1().data());
return NULL;
+#endif
}
static int PythonQtClassWrapper_setattro(PyObject *obj,PyObject *name,PyObject *value)
@@ -435,8 +459,7 @@ static PyObject * PythonQtClassWrapper_repr(PyObject * obj)
*/
PyTypeObject PythonQtClassWrapper_Type = {
- PyObject_HEAD_INIT(NULL)
- 0, /*ob_size*/
+ PyVarObject_HEAD_INIT(NULL, 0)
"PythonQt.PythonQtClassWrapper", /*tp_name*/
sizeof(PythonQtClassWrapper), /*tp_basicsize*/
0, /*tp_itemsize*/
diff --git a/src/PythonQtConversion.cpp b/src/PythonQtConversion.cpp
index bb01083..6adbb59 100644
--- a/src/PythonQtConversion.cpp
+++ b/src/PythonQtConversion.cpp
@@ -45,6 +45,10 @@
#include
#include
+#if PY_MAJOR_VERSION >= 3
+#define PY3K
+#endif
+
PythonQtValueStorage PythonQtConv::global_valueStorage;
PythonQtValueStorage PythonQtConv::global_ptrStorage;
PythonQtValueStorageWithCleanup PythonQtConv::global_variantStorage;
@@ -78,7 +82,11 @@ PyObject* PythonQtConv::ConvertQtValueToPython(const PythonQtMethodInfo::Paramet
// a char ptr will probably be a null terminated string, so we support that:
char* charPtr = *((char**)data);
if (charPtr) {
+#ifdef PY3K
+ return PyUnicode_FromString(charPtr);
+#else
return PyString_FromString(charPtr);
+#endif
} else {
Py_INCREF(Py_None);
return Py_None;
@@ -129,27 +137,27 @@ PyObject* PythonQtConv::ConvertQtValueToPythonInternal(int type, const void* dat
Py_INCREF(Py_None);
return Py_None;
case QMetaType::Char:
- return PyInt_FromLong(*((char*)data));
+ return PyLong_FromLong(*((char*)data));
case QMetaType::UChar:
- return PyInt_FromLong(*((unsigned char*)data));
+ return PyLong_FromLong(*((unsigned char*)data));
case QMetaType::Short:
- return PyInt_FromLong(*((short*)data));
+ return PyLong_FromLong(*((short*)data));
case QMetaType::UShort:
- return PyInt_FromLong(*((unsigned short*)data));
+ return PyLong_FromLong(*((unsigned short*)data));
case QMetaType::Long:
- return PyInt_FromLong(*((long*)data));
+ return PyLong_FromLong(*((long*)data));
case QMetaType::ULong:
// does not fit into simple int of python
return PyLong_FromUnsignedLong(*((unsigned long*)data));
case QMetaType::Bool:
return PythonQtConv::GetPyBool(*((bool*)data));
case QMetaType::Int:
- return PyInt_FromLong(*((int*)data));
+ return PyLong_FromLong(*((int*)data));
case QMetaType::UInt:
// does not fit into simple int of python
return PyLong_FromUnsignedLong(*((unsigned int*)data));
case QMetaType::QChar:
- return PyInt_FromLong(*((short*)data));
+ return PyLong_FromLong(*((short*)data));
case QMetaType::Float:
return PyFloat_FromDouble(*((float*)data));
case QMetaType::Double:
@@ -293,7 +301,7 @@ void* PythonQtConv::handlePythonToQtAutoConversion(int typeId, PyObject* obj, vo
if (typeId == cursorId) {
static PyObject* qtCursorShapeEnum = PythonQtClassInfo::findEnumWrapper("Qt::CursorShape", NULL);
if ((PyObject*)obj->ob_type == qtCursorShapeEnum) {
- Qt::CursorShape val = (Qt::CursorShape)PyInt_AS_LONG(obj);
+ Qt::CursorShape val = (Qt::CursorShape)PyLong_AsLong(obj);
if (!ptr) {
PythonQtValueStorage_ADD_VALUE(global_variantStorage, QVariant, QCursor(), ptr);
ptr = (void*)((QVariant*)ptr)->constData();
@@ -305,7 +313,7 @@ void* PythonQtConv::handlePythonToQtAutoConversion(int typeId, PyObject* obj, vo
// brushes can be created from QColor and from Qt::GlobalColor (and from brushes, but that's the default)
static PyObject* qtColorClass = PythonQt::priv()->getClassInfo("QColor")->pythonQtClassWrapper();
if ((PyObject*)obj->ob_type == qtGlobalColorEnum) {
- Qt::GlobalColor val = (Qt::GlobalColor)PyInt_AS_LONG(obj);
+ Qt::GlobalColor val = (Qt::GlobalColor)PyLong_AsLong(obj);
if (!ptr) {
PythonQtValueStorage_ADD_VALUE(global_variantStorage, QVariant, QPen(), ptr);
ptr = (void*)((QVariant*)ptr)->constData();
@@ -324,7 +332,7 @@ void* PythonQtConv::handlePythonToQtAutoConversion(int typeId, PyObject* obj, vo
// brushes can be created from QColor and from Qt::GlobalColor (and from brushes, but that's the default)
static PyObject* qtColorClass = PythonQt::priv()->getClassInfo("QColor")->pythonQtClassWrapper();
if ((PyObject*)obj->ob_type == qtGlobalColorEnum) {
- Qt::GlobalColor val = (Qt::GlobalColor)PyInt_AS_LONG(obj);
+ Qt::GlobalColor val = (Qt::GlobalColor)PyLong_AsLong(obj);
if (!ptr) {
PythonQtValueStorage_ADD_VALUE(global_variantStorage, QVariant, QBrush(), ptr);
ptr = (void*)((QVariant*)ptr)->constData();
@@ -342,7 +350,7 @@ void* PythonQtConv::handlePythonToQtAutoConversion(int typeId, PyObject* obj, vo
} else if (typeId == colorId) {
// colors can be created from Qt::GlobalColor (and from colors, but that's the default)
if ((PyObject*)obj->ob_type == qtGlobalColorEnum) {
- Qt::GlobalColor val = (Qt::GlobalColor)PyInt_AS_LONG(obj);
+ Qt::GlobalColor val = (Qt::GlobalColor)PyLong_AsLong(obj);
if (!ptr) {
PythonQtValueStorage_ADD_VALUE(global_variantStorage, QVariant, QColor(), ptr);
ptr = (void*)((QVariant*)ptr)->constData();
@@ -393,10 +401,18 @@ void* PythonQtConv::ConvertPythonToQt(const PythonQtMethodInfo::ParameterInfo& i
// a pointer
if (info.typeId == QMetaType::Char || info.typeId == QMetaType::UChar)
{
+#ifdef PY3K
+ if (PyUnicode_Check(obj)) {
+ QByteArray bytes(PyUnicode_AsUTF8(obj));
+ void* ptr2 = NULL;
+ PythonQtValueStorage_ADD_VALUE_IF_NEEDED(NULL,global_variantStorage, QVariant, QVariant(bytes), ptr2);
+ PythonQtValueStorage_ADD_VALUE_IF_NEEDED(alreadyAllocatedCPPObject,global_ptrStorage, void*, (((QByteArray*)((QVariant*)ptr2)->constData())->data()), ptr);
+#else
if (obj->ob_type == &PyString_Type) {
// take direct reference to string data
const char* data = PyString_AS_STRING(obj);
PythonQtValueStorage_ADD_VALUE_IF_NEEDED(alreadyAllocatedCPPObject,global_ptrStorage, void*, (void*)data, ptr);
+#endif
} else {
// convert to string
QString str = PyObjGetString(obj, strict, ok);
@@ -601,7 +617,7 @@ void* PythonQtConv::ConvertPythonToQt(const PythonQtMethodInfo::ParameterInfo& i
ok = false;
if ((PyObject*)obj->ob_type == info.enumWrapper) {
// we have a exact enum type match:
- val = PyInt_AS_LONG(obj);
+ val = PyLong_AsLong(obj);
ok = true;
} else if (!strict) {
// we try to get any integer, when not being strict. If we are strict, integers are not wanted because
@@ -681,8 +697,10 @@ QStringList PythonQtConv::PyObjToStringList(PyObject* val, bool strict, bool& ok
ok = false;
// if we are strict, we do not want to convert a string to a stringlist
// (strings in python are detected to be sequences)
- if (strict &&
- (val->ob_type == &PyString_Type ||
+ if (strict && (
+#ifndef PY3K
+ val->ob_type == &PyString_Type ||
+#endif
PyUnicode_Check(val))) {
ok = false;
return v;
@@ -703,7 +721,13 @@ QString PythonQtConv::PyObjGetRepresentation(PyObject* val)
QString r;
PyObject* str = PyObject_Repr(val);
if (str) {
+#ifdef PY3K
+ Py_UCS4 *x = PyUnicode_AsUCS4Copy(str);
+ r = QString::fromUcs4(x, PyUnicode_GetLength(str));
+ PyMem_Free(x);
+#else
r = QString(PyString_AS_STRING(str));
+#endif
Py_DECREF(str);
}
return r;
@@ -712,19 +736,34 @@ QString PythonQtConv::PyObjGetRepresentation(PyObject* val)
QString PythonQtConv::PyObjGetString(PyObject* val, bool strict, bool& ok) {
QString r;
ok = true;
- if (val->ob_type == &PyString_Type) {
+#ifndef PY3K
+ if (Py_TYPE(val) == &PyString_Type) {
r = QString(PyString_AS_STRING(val));
- } else if (PyUnicode_Check(val)) {
+ } else
+#endif
+ if (PyUnicode_Check(val)) {
+#ifdef PY3K
+ Py_UCS4 *x = PyUnicode_AsUCS4Copy(val);
+ r = QString::fromUcs4(x, PyUnicode_GetLength(val));
+ PyMem_Free(x);
+#else
PyObject *ptmp = PyUnicode_AsUTF8String(val);
if(ptmp) {
r = QString::fromUtf8(PyString_AS_STRING(ptmp));
Py_DECREF(ptmp);
}
+#endif
} else if (!strict) {
// EXTRA: could also use _Unicode, but why should we?
PyObject* str = PyObject_Str(val);
if (str) {
+#ifdef PY3K
+ Py_UCS4 *x = PyUnicode_AsUCS4Copy(str);
+ r = QString::fromUcs4(x, PyUnicode_GetLength(str));
+ PyMem_Free(x);
+#else
r = QString(PyString_AS_STRING(str));
+#endif
Py_DECREF(str);
} else {
ok = false;
@@ -739,9 +778,14 @@ QByteArray PythonQtConv::PyObjGetBytes(PyObject* val, bool /*strict*/, bool& ok)
// TODO: support buffer objects in general
QByteArray r;
ok = true;
- if (val->ob_type == &PyString_Type) {
+#ifdef PY3K
+ if (PyBytes_Check(val)) {
+ r = QByteArray(PyBytes_AS_STRING(val), PyBytes_GET_SIZE(val));
+#else
+ if (Py_TYPE(val) == &PyString_Type) {
long size = PyString_GET_SIZE(val);
r = QByteArray(PyString_AS_STRING(val), size);
+#endif
} else {
ok = false;
}
@@ -769,17 +813,25 @@ bool PythonQtConv::PyObjGetBool(PyObject* val, bool strict, bool &ok) {
int PythonQtConv::PyObjGetInt(PyObject* val, bool strict, bool &ok) {
int d = 0;
ok = true;
+#ifndef PY3K
if (val->ob_type == &PyInt_Type) {
d = PyInt_AS_LONG(val);
+ } else
+#endif
+ if (Py_TYPE(val) == &PyLong_Type) {
+ // handle error on overflow!
+ d = PyLong_AsLong(val);
} else if (!strict) {
+#ifndef PY3K
if (PyObject_TypeCheck(val, &PyInt_Type)) {
// support for derived int classes, e.g. for our enums
d = PyInt_AS_LONG(val);
- } else if (val->ob_type == &PyFloat_Type) {
- d = floor(PyFloat_AS_DOUBLE(val));
- } else if (val->ob_type == &PyLong_Type) {
- // handle error on overflow!
+ } else
+#endif
+ if (PyObject_TypeCheck(val, &PyLong_Type)) {
d = PyLong_AsLong(val);
+ } else if (Py_TYPE(val) == &PyFloat_Type) {
+ d = floor(PyFloat_AS_DOUBLE(val));
} else if (val == Py_False) {
d = 0;
} else if (val == Py_True) {
@@ -787,7 +839,7 @@ int PythonQtConv::PyObjGetInt(PyObject* val, bool strict, bool &ok) {
} else {
PyErr_Clear();
// PyInt_AsLong will try conversion to an int if the object is not an int:
- d = PyInt_AsLong(val);
+ d = PyLong_AsLong(val);
if (PyErr_Occurred()) {
ok = false;
PyErr_Clear();
@@ -802,15 +854,23 @@ int PythonQtConv::PyObjGetInt(PyObject* val, bool strict, bool &ok) {
qint64 PythonQtConv::PyObjGetLongLong(PyObject* val, bool strict, bool &ok) {
qint64 d = 0;
ok = true;
+#ifndef PY3K
if (val->ob_type == &PyInt_Type) {
d = PyInt_AS_LONG(val);
- } else if (val->ob_type == &PyLong_Type) {
+ } else
+#endif
+ if (Py_TYPE(val) == &PyLong_Type) {
d = PyLong_AsLongLong(val);
} else if (!strict) {
+#ifndef PY3K
if (PyObject_TypeCheck(val, &PyInt_Type)) {
// support for derived int classes, e.g. for our enums
d = PyInt_AS_LONG(val);
- } else if (val->ob_type == &PyFloat_Type) {
+ } else
+#endif
+ if (PyObject_TypeCheck(val, &PyLong_Type)) {
+ d = PyLong_AsLong(val);
+ } else if (Py_TYPE(val) == &PyFloat_Type) {
d = floor(PyFloat_AS_DOUBLE(val));
} else if (val == Py_False) {
d = 0;
@@ -834,15 +894,23 @@ qint64 PythonQtConv::PyObjGetLongLong(PyObject* val, bool strict, bool &ok) {
quint64 PythonQtConv::PyObjGetULongLong(PyObject* val, bool strict, bool &ok) {
quint64 d = 0;
ok = true;
- if (PyObject_TypeCheck(val, &PyInt_Type)) {
+#ifndef PY3K
+ if (Py_TYPE(val) == &PyInt_Type) {
d = PyInt_AS_LONG(val);
- } else if (val->ob_type == &PyLong_Type) {
+ } else
+#endif
+ if (Py_TYPE(val) == &PyLong_Type) {
d = PyLong_AsLongLong(val);
} else if (!strict) {
+#ifndef PY3K
if (PyObject_TypeCheck(val, &PyInt_Type)) {
// support for derived int classes, e.g. for our enums
d = PyInt_AS_LONG(val);
- } else if (val->ob_type == &PyFloat_Type) {
+ } else
+#endif
+ if (PyObject_TypeCheck(val, &PyLong_Type)) {
+ d = PyLong_AsLong(val);
+ } else if (Py_TYPE(val) == &PyFloat_Type) {
d = floor(PyFloat_AS_DOUBLE(val));
} else if (val == Py_False) {
d = 0;
@@ -869,9 +937,12 @@ double PythonQtConv::PyObjGetDouble(PyObject* val, bool strict, bool &ok) {
if (val->ob_type == &PyFloat_Type) {
d = PyFloat_AS_DOUBLE(val);
} else if (!strict) {
+#ifndef PY3K
if (PyObject_TypeCheck(val, &PyInt_Type)) {
d = PyInt_AS_LONG(val);
- } else if (val->ob_type == &PyLong_Type) {
+ } else
+#endif
+ if (PyLong_Check(val)) {
d = PyLong_AsLong(val);
} else if (val == Py_False) {
d = 0;
@@ -899,15 +970,23 @@ QVariant PythonQtConv::PyObjToQVariant(PyObject* val, int type)
if (type==-1) {
// no special type requested
+#ifdef PY3K
+ if (PyBytes_Check(val)) {
+ type = QVariant::ByteArray;
+ } else if (PyUnicode_Check(val)) {
+#else
if (val->ob_type==&PyString_Type || val->ob_type==&PyUnicode_Type) {
+#endif
type = QVariant::String;
} else if (val == Py_False || val == Py_True) {
type = QVariant::Bool;
+#ifndef PY3K
} else if (PyObject_TypeCheck(val, &PyInt_Type)) {
type = QVariant::Int;
- } else if (val->ob_type==&PyLong_Type) {
+#endif
+ } else if (PyLong_Check(val)) {
type = QVariant::LongLong;
- } else if (val->ob_type==&PyFloat_Type) {
+ } else if (PyFloat_Check(val)) {
type = QVariant::Double;
} else if (PyObject_TypeCheck(val, &PythonQtInstanceWrapper_Type)) {
PythonQtInstanceWrapper* wrap = (PythonQtInstanceWrapper*)val;
@@ -928,9 +1007,9 @@ QVariant PythonQtConv::PyObjToQVariant(PyObject* val, int type)
v = qVariantFromValue(myObject);
}
return v;
- } else if (val->ob_type==&PyDict_Type) {
+ } else if (PyDict_Check(val)) {
type = QVariant::Map;
- } else if (val->ob_type==&PyList_Type || val->ob_type==&PyTuple_Type || PySequence_Check(val)) {
+ } else if (PyList_Check(val) || PyTuple_Check(val) || PySequence_Check(val)) {
type = QVariant::List;
} else if (val == Py_None) {
// none is invalid
@@ -1100,7 +1179,11 @@ QVariant PythonQtConv::PyObjToQVariant(PyObject* val, int type)
PyObject* PythonQtConv::QStringToPyObject(const QString& str)
{
if (str.isNull()) {
+#ifdef PY3K
+ return PyUnicode_New(0, 0);
+#else
return PyString_FromString("");
+#endif
} else {
return PyUnicode_DecodeUTF16((const char*)str.utf16(), str.length()*2, NULL, NULL);
}
diff --git a/src/PythonQtImporter.cpp b/src/PythonQtImporter.cpp
index 2fc2459..61d69f2 100644
--- a/src/PythonQtImporter.cpp
+++ b/src/PythonQtImporter.cpp
@@ -51,6 +51,10 @@
#include
#include
+#if PY_MAJOR_VERSION >= 3
+#define PY3K
+#endif
+
#define IS_SOURCE 0x0
#define IS_BYTECODE 0x1
#define IS_PACKAGE 0x2
@@ -159,7 +163,7 @@ PythonQtImporter_dealloc(PythonQtImporter *self)
// free the stored path
if (self->_path) delete self->_path;
// free ourself
- self->ob_type->tp_free((PyObject *)self);
+ Py_TYPE(self)->tp_free((PyObject *)self);
}
@@ -230,7 +234,11 @@ PythonQtImporter_load_module(PyObject *obj, PyObject *args)
QString subname = info.moduleName;
int err;
+#ifdef PY3K
+ fullpath = PyUnicode_FromFormat("%s%c%s",
+#else
fullpath = PyString_FromFormat("%s%c%s",
+#endif
self->_path->toLatin1().constData(),
SEP,
subname.toLatin1().constData());
@@ -400,8 +408,7 @@ Create a new PythonQtImporter instance. 'path' must be a valid path on disk/or i
#define DEFERRED_ADDRESS(ADDR) 0
PyTypeObject PythonQtImporter_Type = {
- PyObject_HEAD_INIT(DEFERRED_ADDRESS(&PyType_Type))
- 0,
+ PyVarObject_HEAD_INIT(DEFERRED_ADDRESS(&PyType_Type), 0)
"PythonQtImport.PythonQtImporter",
sizeof(PythonQtImporter),
0, /* tp_itemsize */
@@ -766,6 +773,20 @@ PyObject* PythonQtImport::getCodeFromPyc(const QString& file)
PyDoc_STRVAR(mlabimport_doc,
"Imports python files into PythonQt, completely replaces internal python import");
+#ifdef PY3K
+static struct PyModuleDef PythonQtImport_def = {
+ PyModuleDef_HEAD_INIT,
+ "PythonQtImport", /* m_name */
+ mlabimport_doc, /* m_doc */
+ -1, /* m_size */
+ NULL, /* m_methods */
+ NULL, /* m_reload */
+ NULL, /* m_traverse */
+ NULL, /* m_clear */
+ NULL /* m_free */
+};
+#endif
+
void PythonQtImport::init()
{
static bool first = true;
@@ -794,8 +815,12 @@ void PythonQtImport::init()
mlab_searchorder[4] = tmp;
}
+#ifdef PY3K
+ mod = PyModule_Create(&PythonQtImport_def);
+#else
mod = Py_InitModule4("PythonQtImport", NULL, mlabimport_doc,
NULL, PYTHON_API_VERSION);
+#endif
PythonQtImportError = PyErr_NewException(const_cast("PythonQtImport.PythonQtImportError"),
PyExc_ImportError, NULL);
diff --git a/src/PythonQtInstanceWrapper.cpp b/src/PythonQtInstanceWrapper.cpp
index 3ca7bd0..45983f1 100644
--- a/src/PythonQtInstanceWrapper.cpp
+++ b/src/PythonQtInstanceWrapper.cpp
@@ -48,10 +48,14 @@
#include "PythonQtConversion.h"
#include "PythonQtClassWrapper.h"
+#if PY_MAJOR_VERSION >= 3
+#define PY3K
+#endif
+
PythonQtClassInfo* PythonQtInstanceWrapperStruct::classInfo()
{
// take the class info from our type object
- return ((PythonQtClassWrapper*)ob_type)->_classInfo;
+ return ((PythonQtClassWrapper*)Py_TYPE(this))->_classInfo;
}
static void PythonQtInstanceWrapper_deleteObject(PythonQtInstanceWrapper* self, bool force = false) {
@@ -112,7 +116,7 @@ static void PythonQtInstanceWrapper_dealloc(PythonQtInstanceWrapper* self)
{
PythonQtInstanceWrapper_deleteObject(self);
self->_obj.~QPointer();
- self->ob_type->tp_free((PyObject*)self);
+ Py_TYPE(self)->tp_free((PyObject*)self);
}
static PyObject* PythonQtInstanceWrapper_new(PyTypeObject *type, PyObject * /*args*/, PyObject * /*kwds*/)
@@ -286,7 +290,11 @@ static PyObject *PythonQtInstanceWrapper_richcompare(PythonQtInstanceWrapper* wr
static PyObject *PythonQtInstanceWrapper_classname(PythonQtInstanceWrapper* obj)
{
- return PyString_FromString(obj->ob_type->tp_name);
+#ifdef PY3K
+ return PyUnicode_FromString(Py_TYPE(obj)->tp_name);
+#else
+ return PyString_FromString(Py_TYPE(obj)->tp_name);
+#endif
}
PyObject *PythonQtInstanceWrapper_inherits(PythonQtInstanceWrapper* obj, PyObject *args)
@@ -333,7 +341,11 @@ static PyObject *PythonQtInstanceWrapper_getattro(PyObject *obj,PyObject *name)
const char *attributeName;
PythonQtInstanceWrapper *wrapper = (PythonQtInstanceWrapper *)obj;
+#ifdef PY3K
+ if ((attributeName = PyUnicode_AsUTF8(name)) == NULL) {
+#else
if ((attributeName = PyString_AsString(name)) == NULL) {
+#endif
return NULL;
}
@@ -455,7 +467,11 @@ static PyObject *PythonQtInstanceWrapper_getattro(PyObject *obj,PyObject *name)
}
// look for the internal methods (className(), help())
+#ifdef PY3K
+ PyObject* internalMethod = PyObject_GenericGetAttr(obj, name);
+#else
PyObject* internalMethod = Py_FindMethod( PythonQtInstanceWrapper_methods, obj, (char*)attributeName);
+#endif
if (internalMethod) {
return internalMethod;
}
@@ -483,7 +499,11 @@ static int PythonQtInstanceWrapper_setattro(PyObject *obj,PyObject *name,PyObjec
const char *attributeName;
PythonQtInstanceWrapper *wrapper = (PythonQtInstanceWrapper *)obj;
+#ifdef PY3K
+ if ((attributeName = PyUnicode_AsUTF8(name)) == NULL)
+#else
if ((attributeName = PyString_AsString(name)) == NULL)
+#endif
return -1;
PythonQtMemberInfo member = wrapper->classInfo()->member(attributeName);
@@ -619,9 +639,17 @@ static PyObject * PythonQtInstanceWrapper_str(PyObject * obj)
if (wrapper->classInfo()->metaTypeId()==QVariant::ByteArray) {
QByteArray* b = (QByteArray*) wrapper->_wrappedPtr;
if (b->data()) {
+#ifdef PY3K
+ return PyUnicode_FromStringAndSize(b->data(), b->size());
+#else
return PyString_FromStringAndSize(b->data(), b->size());
+#endif
} else {
+#ifdef PY3K
+ return PyUnicode_New(0, 0);
+#else
return PyString_FromString("");
+#endif
}
}
@@ -629,16 +657,32 @@ static PyObject * PythonQtInstanceWrapper_str(PyObject * obj)
QObject *qobj = wrapper->_obj;
QString str = getStringFromObject(wrapper);
if (!str.isEmpty()) {
+#ifdef PY3K
+ return PyUnicode_FromFormat("%s", str.toLatin1().constData());
+#else
return PyString_FromFormat("%s", str.toLatin1().constData());
+#endif
}
if (wrapper->_wrappedPtr) {
if (wrapper->_obj) {
- return PyString_FromFormat("%s (C++ Object %p wrapped by %s %p))", typeName, wrapper->_wrappedPtr, wrapper->_obj->metaObject()->className(), qobj);
+#ifdef PY3K
+ return PyUnicode_FromFormat("%s (C++ Object %p wrapped by %s %p)", typeName, wrapper->_wrappedPtr, wrapper->_obj->metaObject()->className(), qobj);
+#else
+ return PyString_FromFormat("%s (C++ Object %p wrapped by %s %p)", typeName, wrapper->_wrappedPtr, wrapper->_obj->metaObject()->className(), qobj);
+#endif
} else {
+#ifdef PY3K
+ return PyUnicode_FromFormat("%s (C++ Object %p)", typeName, wrapper->_wrappedPtr);
+#else
return PyString_FromFormat("%s (C++ Object %p)", typeName, wrapper->_wrappedPtr);
+#endif
}
} else {
+#ifdef PY3K
+ return PyUnicode_FromFormat("%s (QObject %p)", typeName, qobj);
+#else
return PyString_FromFormat("%s (QObject %p)", typeName, qobj);
+#endif
}
}
@@ -651,19 +695,39 @@ static PyObject * PythonQtInstanceWrapper_repr(PyObject * obj)
QString str = getStringFromObject(wrapper);
if (!str.isEmpty()) {
if (str.startsWith(typeName)) {
+#ifdef PY3K
+ return PyUnicode_FromFormat("%s", str.toLatin1().constData());
+#else
return PyString_FromFormat("%s", str.toLatin1().constData());
+#endif
} else {
+#ifdef PY3K
+ return PyUnicode_FromFormat("%s (%s, at: %p)", typeName, str.toLatin1().constData(), wrapper->_wrappedPtr ? wrapper->_wrappedPtr : qobj);
+#else
return PyString_FromFormat("%s (%s, at: %p)", typeName, str.toLatin1().constData(), wrapper->_wrappedPtr ? wrapper->_wrappedPtr : qobj);
+#endif
}
}
if (wrapper->_wrappedPtr) {
if (wrapper->_obj) {
+#ifdef PY3K
+ return PyUnicode_FromFormat("%s (C++ object at: %p wrapped by %s at: %p)", typeName, wrapper->_wrappedPtr, wrapper->_obj->metaObject()->className(), qobj);
+#else
return PyString_FromFormat("%s (C++ object at: %p wrapped by %s at: %p)", typeName, wrapper->_wrappedPtr, wrapper->_obj->metaObject()->className(), qobj);
+#endif
} else {
+#ifdef PY3K
+ return PyUnicode_FromFormat("%s (C++ object at: %p)", typeName, wrapper->_wrappedPtr);
+#else
return PyString_FromFormat("%s (C++ object at: %p)", typeName, wrapper->_wrappedPtr);
+#endif
}
} else {
+#ifdef PY3K
+ return PyUnicode_FromFormat("%s (%s at: %p)", typeName, wrapper->classInfo()->className(), qobj);
+#else
return PyString_FromFormat("%s (%s at: %p)", typeName, wrapper->classInfo()->className(), qobj);
+#endif
}
}
@@ -691,30 +755,38 @@ static PyNumberMethods PythonQtInstanceWrapper_as_number = {
0, /* nb_add */
0, /* nb_subtract */
0, /* nb_multiply */
+#ifndef PY3K
0, /* nb_divide */
+#endif
0, /* nb_remainder */
0, /* nb_divmod */
0, /* nb_power */
0, /* nb_negative */
0, /* nb_positive */
0, /* nb_absolute */
- PythonQtInstanceWrapper_builtin_nonzero, /* nb_nonzero */
+ PythonQtInstanceWrapper_builtin_nonzero, /* nb_nonzero / nb_bool in Py3K */
0, /* nb_invert */
0, /* nb_lshift */
0, /* nb_rshift */
0, /* nb_and */
0, /* nb_xor */
0, /* nb_or */
+#ifndef PY3K
0, /* nb_coerce */
+#endif
0, /* nb_int */
- 0, /* nb_long */
+ 0, /* nb_long / nb_reserved in Py3K */
0, /* nb_float */
+#ifndef PY3K
0, /* nb_oct */
0, /* nb_hex */
+#endif
0, /* nb_inplace_add */
0, /* nb_inplace_subtract */
0, /* nb_inplace_multiply */
+#ifndef PY3K
0, /* nb_inplace_divide */
+#endif
0, /* nb_inplace_remainder */
0, /* nb_inplace_power */
0, /* nb_inplace_lshift */
@@ -726,11 +798,13 @@ static PyNumberMethods PythonQtInstanceWrapper_as_number = {
0, /* nb_true_divide */
0, /* nb_inplace_floor_divide */
0, /* nb_inplace_true_divide */
+#ifdef PY3K
+ 0, /* nb_index in Py3K */
+#endif
};
PyTypeObject PythonQtInstanceWrapper_Type = {
- PyObject_HEAD_INIT(&PythonQtClassWrapper_Type)
- 0, /*ob_size*/
+ PyVarObject_HEAD_INIT(&PythonQtClassWrapper_Type, 0)
"PythonQt.PythonQtInstanceWrapper", /*tp_name*/
sizeof(PythonQtInstanceWrapper), /*tp_basicsize*/
0, /*tp_itemsize*/
@@ -749,7 +823,7 @@ PyTypeObject PythonQtInstanceWrapper_Type = {
PythonQtInstanceWrapper_getattro, /*tp_getattro*/
PythonQtInstanceWrapper_setattro, /*tp_setattro*/
0, /*tp_as_buffer*/
- Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_CHECKTYPES, /*tp_flags*/
+ Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE /*| Py_TPFLAGS_CHECKTYPES FIXME Py_TPFLAGS_CHECKTYPES removal */, /*tp_flags*/
"PythonQtInstanceWrapper object", /* tp_doc */
0, /* tp_traverse */
0, /* tp_clear */
diff --git a/src/PythonQtPythonInclude.h b/src/PythonQtPythonInclude.h
index e443324..bab5890 100644
--- a/src/PythonQtPythonInclude.h
+++ b/src/PythonQtPythonInclude.h
@@ -38,6 +38,12 @@
#undef _POSIX_THREADS
#undef _XOPEN_SOURCE
+// Undefine Qt keywords that conflict with Python headers
+#ifdef slots
+#undef slots
+#define PYTHONQT_RESTORE_KEYWORDS
+#endif
+
// If PYTHONQT_USE_RELEASE_PYTHON_FALLBACK is enabled, try to link
// release Python DLL if it is available by undefining _DEBUG while
// including Python.h
@@ -53,4 +59,14 @@
#include
#endif
+// get Qt keywords back
+#ifdef PYTHONQT_RESTORE_KEYWORDS
+#define slots Q_SLOTS
+#undef PYTHONQT_RESTORE_KEYWORDS
+#endif
+
+#if PY_MAJOR_VERSION >= 3
+#define PY3K
+#endif
+
#endif
diff --git a/src/PythonQtSignal.cpp b/src/PythonQtSignal.cpp
index d77b839..4cc39ec 100644
--- a/src/PythonQtSignal.cpp
+++ b/src/PythonQtSignal.cpp
@@ -110,10 +110,18 @@ static PyObject *
meth_get__name__(PythonQtSignalFunctionObject *m, void * /*closure*/)
{
#if( QT_VERSION >= QT_VERSION_CHECK(5,0,0) )
+#ifdef PY3K
+ return PyUnicode_FromString(m->m_ml->metaMethod()->methodSignature());
+#else
return PyString_FromString(m->m_ml->metaMethod()->methodSignature());
+#endif
+#else
+#ifdef PY3K
+ return PyUnicode_FromString(m->m_ml->metaMethod()->signature());
#else
return PyString_FromString(m->m_ml->metaMethod()->signature());
#endif
+#endif
}
static int
@@ -137,11 +145,13 @@ static PyObject *
meth_get__self__(PythonQtSignalFunctionObject *m, void * /*closure*/)
{
PyObject *self;
+#ifndef PY3K
if (PyEval_GetRestricted()) {
PyErr_SetString(PyExc_RuntimeError,
"method.__self__ not accessible in restricted mode");
return NULL;
}
+#endif
self = m->m_self;
if (self == NULL)
self = Py_None;
@@ -266,11 +276,19 @@ meth_repr(PythonQtSignalFunctionObject *f)
{
if (f->m_self->ob_type == &PythonQtClassWrapper_Type) {
PythonQtClassWrapper* self = (PythonQtClassWrapper*) f->m_self;
+#ifdef PY3K
+ return PyUnicode_FromFormat("",
+#else
return PyString_FromFormat("",
+#endif
f->m_ml->slotName().data(),
self->classInfo()->className());
} else {
+#ifdef PY3K
+ return PyUnicode_FromFormat("",
+#else
return PyString_FromFormat("",
+#endif
f->m_ml->slotName().data(),
f->m_self->ob_type->tp_name,
f->m_self);
@@ -314,10 +332,32 @@ meth_hash(PythonQtSignalFunctionObject *a)
return x;
}
+// for python 3.x
+static PyObject*
+meth_richcompare(PythonQtSignalFunctionObject *a, PythonQtSignalFunctionObject *b, int op)
+{
+ int x = meth_compare(a, b);
+ bool r;
+ if (op == Py_LT)
+ r = x < 0;
+ else if (op == Py_LE)
+ r = x < 1;
+ else if (op == Py_EQ)
+ r = x == 0;
+ else if (op == Py_NE)
+ r = x != 0;
+ else if (op == Py_GE)
+ r = x > -1;
+ else if (op == Py_GT)
+ r = x > 0;
+ if (r)
+ Py_RETURN_TRUE;
+ else
+ Py_RETURN_FALSE;
+}
PyTypeObject PythonQtSignalFunction_Type = {
- PyObject_HEAD_INIT(&PyType_Type)
- 0,
+ PyVarObject_HEAD_INIT(&PyType_Type, 0)
"builtin_qt_signal",
sizeof(PythonQtSignalFunctionObject),
0,
@@ -325,7 +365,11 @@ PyTypeObject PythonQtSignalFunction_Type = {
0, /* tp_print */
0, /* tp_getattr */
0, /* tp_setattr */
+#ifdef PY3K
+ 0,
+#else
(cmpfunc)meth_compare, /* tp_compare */
+#endif
(reprfunc)meth_repr, /* tp_repr */
0, /* tp_as_number */
0, /* tp_as_sequence */
@@ -341,7 +385,7 @@ PyTypeObject PythonQtSignalFunction_Type = {
0, /* tp_doc */
(traverseproc)meth_traverse, /* tp_traverse */
0, /* tp_clear */
- 0, /* tp_richcompare */
+ (richcmpfunc)meth_richcompare, /* tp_richcompare */
0, /* tp_weaklistoffset */
0, /* tp_iter */
0, /* tp_iternext */
diff --git a/src/PythonQtSignalReceiver.cpp b/src/PythonQtSignalReceiver.cpp
index 004e15a..789930c 100644
--- a/src/PythonQtSignalReceiver.cpp
+++ b/src/PythonQtSignalReceiver.cpp
@@ -138,7 +138,11 @@ PyObject* PythonQtSignalTarget::call(PyObject* callable, const PythonQtMethodInf
bool PythonQtSignalTarget::isSame( int signalId, PyObject* callable ) const
{
+#ifdef PY3K
+ return PyObject_RichCompareBool(callable, _callable, Py_EQ) && signalId == _signalId;
+#else
return PyObject_Compare(callable, _callable) == 0 && signalId==_signalId;
+#endif
}
//------------------------------------------------------------------------------
diff --git a/src/PythonQtSlot.cpp b/src/PythonQtSlot.cpp
index ad67685..fc3d82f 100644
--- a/src/PythonQtSlot.cpp
+++ b/src/PythonQtSlot.cpp
@@ -52,6 +52,10 @@
#include
+#if PY_MAJOR_VERSION >= 3
+#define PY3K
+#endif
+
#define PYTHONQT_MAX_ARGS 32
@@ -192,7 +196,11 @@ bool PythonQtCallSlot(PythonQtClassInfo* classInfo, QObject* objectToCall, PyObj
hadException = true;
QByteArray what("std::exception: ");
what += e.what();
+#ifdef PY3K
+ PyErr_SetString(PyExc_RuntimeError, what.constData());
+#else
PyErr_SetString(PyExc_StandardError, what.constData());
+#endif
}
}
@@ -419,10 +427,18 @@ static PyObject *
meth_get__name__(PythonQtSlotFunctionObject *m, void * /*closure*/)
{
#if( QT_VERSION >= QT_VERSION_CHECK(5,0,0) )
+#ifdef PY3K
+ return PyUnicode_FromString(m->m_ml->metaMethod()->methodSignature());
+#else
return PyString_FromString(m->m_ml->metaMethod()->methodSignature());
+#endif
+#else
+#ifdef PY3K
+ return PyUnicode_FromString(m->m_ml->metaMethod()->signature());
#else
return PyString_FromString(m->m_ml->metaMethod()->signature());
#endif
+#endif
}
static int
@@ -446,11 +462,13 @@ static PyObject *
meth_get__self__(PythonQtSlotFunctionObject *m, void * /*closure*/)
{
PyObject *self;
+#ifndef PY3K
if (PyEval_GetRestricted()) {
PyErr_SetString(PyExc_RuntimeError,
"method.__self__ not accessible in restricted mode");
return NULL;
}
+#endif
self = m->m_self;
if (self == NULL)
self = Py_None;
@@ -505,7 +523,11 @@ PyObject *PythonQtMemberFunction_parameterTypes(PythonQtSlotInfo* theInfo)
QList types = info->metaMethod()->parameterTypes();
PyObject* tuple = PyTuple_New(types.count());
for (int i = 0; inextInfo();
PyTuple_SET_ITEM(result, j, tuple);
@@ -527,7 +549,11 @@ PyObject *PythonQtMemberFunction_parameterNames(PythonQtSlotInfo* theInfo)
QList names = info->metaMethod()->parameterNames();
PyObject* tuple = PyTuple_New(names.count());
for (int i = 0; inextInfo();
PyTuple_SET_ITEM(result, j, tuple);
@@ -547,7 +573,11 @@ PyObject *PythonQtMemberFunction_typeName(PythonQtSlotInfo* theInfo)
PyObject* result = PyTuple_New(count);
for (int j = 0;jmetaMethod()->typeName();
+#ifdef PY3K
+ PyTuple_SET_ITEM(result, j, PyUnicode_FromString(name.constData()));
+#else
PyTuple_SET_ITEM(result, j, PyString_FromString(name.constData()));
+#endif
info = info->nextInfo();
}
return result;
@@ -571,11 +601,19 @@ meth_repr(PythonQtSlotFunctionObject *f)
{
if (f->m_self->ob_type == &PythonQtClassWrapper_Type) {
PythonQtClassWrapper* self = (PythonQtClassWrapper*) f->m_self;
+#ifdef PY3K
+ return PyUnicode_FromFormat("",
+#else
return PyString_FromFormat("",
+#endif
f->m_ml->slotName().data(),
self->classInfo()->className());
} else {
+#ifdef PY3K
+ return PyUnicode_FromFormat("",
+#endif
f->m_ml->slotName().data(),
f->m_self->ob_type->tp_name,
f->m_self);
@@ -619,10 +657,33 @@ meth_hash(PythonQtSlotFunctionObject *a)
return x;
}
+// for python 3.x
+static PyObject*
+meth_richcompare(PythonQtSlotFunctionObject *a, PythonQtSlotFunctionObject *b, int op)
+{
+ int x = meth_compare(a, b);
+ bool r;
+ if (op == Py_LT)
+ r = x < 0;
+ else if (op == Py_LE)
+ r = x < 1;
+ else if (op == Py_EQ)
+ r = x == 0;
+ else if (op == Py_NE)
+ r = x != 0;
+ else if (op == Py_GE)
+ r = x > -1;
+ else if (op == Py_GT)
+ r = x > 0;
+ if (r)
+ Py_RETURN_TRUE;
+ else
+ Py_RETURN_FALSE;
+}
+
PyTypeObject PythonQtSlotFunction_Type = {
- PyObject_HEAD_INIT(&PyType_Type)
- 0,
+ PyVarObject_HEAD_INIT(&PyType_Type, 0)
"builtin_qt_slot",
sizeof(PythonQtSlotFunctionObject),
0,
@@ -630,7 +691,11 @@ PyTypeObject PythonQtSlotFunction_Type = {
0, /* tp_print */
0, /* tp_getattr */
0, /* tp_setattr */
+#ifdef PY3K
+ 0,
+#else
(cmpfunc)meth_compare, /* tp_compare */
+#endif
(reprfunc)meth_repr, /* tp_repr */
0, /* tp_as_number */
0, /* tp_as_sequence */
@@ -645,7 +710,7 @@ PyTypeObject PythonQtSlotFunction_Type = {
0, /* tp_doc */
(traverseproc)meth_traverse, /* tp_traverse */
0, /* tp_clear */
- 0, /* tp_richcompare */
+ (richcmpfunc)meth_richcompare, /* tp_richcompare */
0, /* tp_weaklistoffset */
0, /* tp_iter */
0, /* tp_iternext */
diff --git a/src/PythonQtStdDecorators.cpp b/src/PythonQtStdDecorators.cpp
index edf9800..a25a8a3 100644
--- a/src/PythonQtStdDecorators.cpp
+++ b/src/PythonQtStdDecorators.cpp
@@ -181,8 +181,13 @@ QObject* PythonQtStdDecorators::findChild(QObject* parent, PyObject* type, const
meta = ((PythonQtClassWrapper*)type)->classInfo()->metaObject();
} else if (PyObject_TypeCheck(type, &PythonQtInstanceWrapper_Type)) {
meta = ((PythonQtInstanceWrapper*)type)->classInfo()->metaObject();
+#ifdef PY3K
+ } else if (PyUnicode_Check(type)) {
+ typeName = PyUnicode_AsUTF8(type);
+#else
} else if (PyString_Check(type)) {
typeName = PyString_AsString(type);
+#endif
}
if (!typeName && !meta)
@@ -200,8 +205,13 @@ QList PythonQtStdDecorators::findChildren(QObject* parent, PyObject* t
meta = ((PythonQtClassWrapper*)type)->classInfo()->metaObject();
} else if (PyObject_TypeCheck(type, &PythonQtInstanceWrapper_Type)) {
meta = ((PythonQtInstanceWrapper*)type)->classInfo()->metaObject();
+#ifdef PY3K
+ } else if (PyUnicode_Check(type)) {
+ typeName = PyUnicode_AsUTF8(type);
+#else
} else if (PyString_Check(type)) {
typeName = PyString_AsString(type);
+#endif
}
QList list;
@@ -223,8 +233,13 @@ QList PythonQtStdDecorators::findChildren(QObject* parent, PyObject* t
meta = ((PythonQtClassWrapper*)type)->classInfo()->metaObject();
} else if (PyObject_TypeCheck(type, &PythonQtInstanceWrapper_Type)) {
meta = ((PythonQtInstanceWrapper*)type)->classInfo()->metaObject();
+#ifdef PY3K
+ } else if (PyUnicode_Check(type)) {
+ typeName = PyUnicode_AsUTF8(type);
+#else
} else if (PyString_Check(type)) {
typeName = PyString_AsString(type);
+#endif
}
QList list;
@@ -324,4 +339,4 @@ int PythonQtStdDecorators::findChildren(QObject* parent, const char* typeName, c
const QMetaObject* PythonQtStdDecorators::metaObject( QObject* obj )
{
return obj->metaObject();
-}
\ No newline at end of file
+}
diff --git a/src/PythonQtStdIn.cpp b/src/PythonQtStdIn.cpp
index 07d844d..bd8f652 100644
--- a/src/PythonQtStdIn.cpp
+++ b/src/PythonQtStdIn.cpp
@@ -76,8 +76,7 @@ static PyMemberDef PythonQtStdInRedirect_members[] = {
};
PyTypeObject PythonQtStdInRedirectType = {
- PyObject_HEAD_INIT(NULL)
- 0, /*ob_size*/
+ PyVarObject_HEAD_INIT(NULL, 0)
"PythonQtStdInRedirect", /*tp_name*/
sizeof(PythonQtStdInRedirect), /*tp_basicsize*/
0, /*tp_itemsize*/
diff --git a/src/PythonQtStdOut.cpp b/src/PythonQtStdOut.cpp
index 4604541..60b5f4e 100644
--- a/src/PythonQtStdOut.cpp
+++ b/src/PythonQtStdOut.cpp
@@ -60,6 +60,11 @@ static PyObject *PythonQtStdOutRedirect_write(PyObject *self, PyObject *args)
if (PyTuple_GET_SIZE(args)>=1) {
PyObject* obj = PyTuple_GET_ITEM(args,0);
if (PyUnicode_Check(obj)) {
+#ifdef PY3K
+ Py_UCS4 *x = PyUnicode_AsUCS4Copy(obj);
+ output = QString::fromUcs4(x, PyUnicode_GetLength(obj));
+ PyMem_Free(x);
+#else
PyObject *tmp = PyUnicode_AsUTF8String(obj);
if(tmp) {
output = QString::fromUtf8(PyString_AS_STRING(tmp));
@@ -67,6 +72,7 @@ static PyObject *PythonQtStdOutRedirect_write(PyObject *self, PyObject *args)
} else {
return NULL;
}
+#endif
} else {
char *string;
if (!PyArg_ParseTuple(args, "s", &string)) {
@@ -117,8 +123,7 @@ static PyMemberDef PythonQtStdOutRedirect_members[] = {
};
PyTypeObject PythonQtStdOutRedirectType = {
- PyObject_HEAD_INIT(NULL)
- 0, /*ob_size*/
+ PyVarObject_HEAD_INIT(NULL, 0)
"PythonQtStdOutRedirect", /*tp_name*/
sizeof(PythonQtStdOutRedirect), /*tp_basicsize*/
0, /*tp_itemsize*/