Changes to compile and run with python3 (WIP)

This commit is contained in:
Silarn
2018-08-20 18:49:15 -05:00
parent 4900135130
commit 08bcebe19c
6 changed files with 77 additions and 39 deletions
+1 -1
View File
@@ -14,7 +14,7 @@ LIST(APPEND CMAKE_PREFIX_PATH ${QT_ROOT}/lib/cmake)
FILE(GLOB_RECURSE PYTHON_ROOT ${DEPENDENCIES_DIR}/Python*/pyconfig.h.in)
GET_FILENAME_COMPONENT(PYTHON_ROOT ${PYTHON_ROOT} DIRECTORY)
FILE(GLOB_RECURSE SIP_ROOT ${DEPENDENCIES_DIR}/sip*/siplib/sip.h)
FILE(GLOB_RECURSE SIP_ROOT ${DEPENDENCIES_DIR}/sip-*/siplib/sip.h)
GET_FILENAME_COMPONENT(SIP_ROOT ${SIP_ROOT} DIRECTORY)
# need to install python
+1
View File
@@ -13,6 +13,7 @@ FILE(GLOB ${PROJ_NAME}_HDRS *.h)
SET(CMAKE_INCLUDE_CURRENT_DIR ON)
SET(CMAKE_AUTOMOC ON)
SET(CMAKE_AUTOUIC ON)
ADD_DEFINITIONS(-DQT_NO_KEYWORDS)
FIND_PACKAGE(Qt5Widgets REQUIRED)
#QT5_WRAP_UI(${PROJ_NAME}_UIHDRS ${${PROJ_NAME}_FORMS})
FIND_PACKAGE(Qt5LinguistTools)
+1 -1
View File
@@ -202,7 +202,7 @@ public:
virtual QIcon icon() const;
virtual void setParentWidget(QWidget *parent);
public slots:
public Q_SLOTS:
virtual void display() const;
};
+45 -36
View File
@@ -48,7 +48,7 @@ private:
private:
std::map<QString, boost::python::object> m_PythonObjects;
const MOBase::IOrganizer *m_MOInfo;
char *m_PythonHome;
wchar_t *m_PythonHome;
};
@@ -69,13 +69,14 @@ using namespace MOBase;
namespace bpy = boost::python;
static sipWrapperType sipWrapper_Type;
struct QString_to_python_str
{
static PyObject *convert(const QString &str) {
// It's safer to explicitly convert to unicode as if we don't, this can return either str or unicode without it being easy to know which to expect
bpy::object pyStr = bpy::object(str.toUtf8().constData());
if (PyString_Check(pyStr.ptr()))
if (SIPBytes_Check(pyStr.ptr()))
pyStr = pyStr.attr("decode")("utf-8");
return bpy::incref(pyStr.ptr());
}
@@ -97,14 +98,14 @@ struct QString_from_python_str
}
static void *convertible(PyObject *objPtr) {
return PyString_Check(objPtr) || PyUnicode_Check(objPtr) ? objPtr : nullptr;
return SIPBytes_Check(objPtr) || PyUnicode_Check(objPtr) ? objPtr : nullptr;
}
static void construct(PyObject *objPtr, bpy::converter::rvalue_from_python_stage1_data *data) {
// Ensure the string uses 8-bit characters
PyObject *strPtr = PyUnicode_Check(objPtr) ? PyUnicode_AsUTF8String(objPtr) : objPtr;
// Extract the character data from the python string
const char* value = PyString_AsString(strPtr);
const char* value = SIPBytes_AsString(strPtr);
// Deallocate local copy if one was made
if (strPtr != objPtr)
Py_DecRef(strPtr);
@@ -225,7 +226,7 @@ struct QVariant_to_python_obj
{
static PyObject *convert(const QVariant &var) {
switch (var.type()) {
case QVariant::Int: return PyLong_FromLong(var.toInt());
case QVariant::Int: return SIPLong_FromLong(var.toInt());
case QVariant::UInt: return PyLong_FromUnsignedLong(var.toUInt());
case QVariant::Bool: return PyBool_FromLong(var.toBool());
case QVariant::String: return bpy::incref(bpy::object(var.toString()).ptr());
@@ -251,7 +252,7 @@ struct QVariant_from_python_obj
}
static void *convertible(PyObject *objPtr) {
if (!PyString_Check(objPtr) && !PyInt_Check(objPtr) &&
if (!SIPBytes_Check(objPtr) && !PyLong_Check(objPtr) &&
!PyBool_Check(objPtr) && !PyList_Check(objPtr)) {
return nullptr;
}
@@ -268,17 +269,17 @@ struct QVariant_from_python_obj
}
static void construct(PyObject *objPtr, bpy::converter::rvalue_from_python_stage1_data *data) {
// PyBools will also return true for PyInt_Check but not the other way around, so the order
// PyBools will also return true for SIPLong_Check but not the other way around, so the order
// here is relevant
if (PyList_Check(objPtr)) {
constructVariant(bpy::extract<QVariantList>(objPtr)(), data);
} else if (PyDict_Check(objPtr)) {
constructVariant(bpy::extract<QVariantMap>(objPtr)(), data);
} else if (PyString_Check(objPtr) || PyUnicode_Check(objPtr)) {
} else if (SIPBytes_Check(objPtr) || PyUnicode_Check(objPtr)) {
constructVariant(bpy::extract<QString>(objPtr)(), data);
} else if (PyBool_Check(objPtr)) {
constructVariant(bpy::extract<bool>(objPtr)(), data);
} else if (PyInt_Check(objPtr)) {
} else if (SIPLong_Check(objPtr)) {
//QVariant doesn't have long. It has int or long long. Given that on m/s,
//long is 32 bits for 32- and 64- bit code...
constructVariant(bpy::extract<int>(objPtr)(), data);
@@ -399,11 +400,11 @@ struct QFlags_from_python_obj
}
static void* convertible(PyObject *objPtr) {
return PyInt_Check(objPtr) ? objPtr : nullptr;
return SIPLong_Check(objPtr) ? objPtr : nullptr;
}
static void construct(PyObject *objPtr, bpy::converter::rvalue_from_python_stage1_data *data) {
int intVersion = (int)PyInt_AsLong(objPtr);
int intVersion = (int)SIPLong_AsLong(objPtr);
T tVersion = (T)intVersion;
void *storage = ((bpy::converter::rvalue_from_python_storage<QFlags<T>> *)data)->storage.bytes;
new (storage) QFlags<T>(tVersion);
@@ -558,7 +559,22 @@ struct QClass_converters
static void *QClass_from_PyQt(PyObject *objPtr)
{
if (!PyObject_TypeCheck(objPtr, sipAPI()->api_simplewrapper_type)) {
// This would transfer responsibility for deconstructing the object to C++, but Boost assumes l-value converters (such as this) don't do that
// Instead, this should be called within the wrappers for functions which return deletable pointers.
//sipAPI()->api_transfer_to(objPtr, 0);
/*if (PyObject_TypeCheck(objPtr, sipAPI()->api_wrapper_type)) {
sipWrapper *wrapper;
wrapper = reinterpret_cast<sipWrapper*>(objPtr);
return wrapper->super.data;
} else if (PyObject_TypeCheck(objPtr, sipAPI()->api_simplewrapper_type)) {*/
sipSimpleWrapper *wrapper;
wrapper = reinterpret_cast<sipSimpleWrapper*>(objPtr);
return wrapper->data;
/*} else if (PyObject_TypeCheck(objPtr, sipAPI()->api_wrappertype_type)) {
sipWrapper *wrapper;
wrapper = reinterpret_cast<sipWrapper*>(objPtr);
return wrapper->super.data;
} else {
if (std::is_same_v<T, QStringList>)
{
// QStringLists aren't wrapped by PyQt - regular Python string/unicode lists are used instead
@@ -566,17 +582,13 @@ struct QClass_converters
if (extractor.check())
return new QStringList(extractor());
}
PyErr_SetString(PyExc_TypeError, "type not wrapped");
bpy::throw_error_already_set();
}
// This would transfer responsibility for deconstructing the object to C++, but Boost assumes l-value converters (such as this) don't do that
// Instead, this should be called within the wrappers for functions which return deletable pointers.
//sipAPI()->api_transfer_to(objPtr, 0);
sipSimpleWrapper *wrapper = reinterpret_cast<sipSimpleWrapper*>(objPtr);
return wrapper->data;
if (!std::is_same_v<T, QIcon>) {
PyErr_SetString(PyExc_TypeError, "type not wrapped");
bpy::throw_error_already_set();
}
}*/
}
QClass_converters()
{
bpy::converter::registry::insert(&QClass_from_PyQt, bpy::type_id<T>());
@@ -658,7 +670,7 @@ int getArgCount(PyObject *object) {
if (funcCode) {
PyObject *argCount = PyObject_GetAttrString(funcCode, "co_argcount");
if(argCount) {
result = PyInt_AsLong(argCount);
result = SIPLong_AsLong(argCount);
Py_DECREF(argCount);
}
Py_DECREF(funcCode);
@@ -1203,7 +1215,7 @@ BOOST_PYTHON_MODULE(mobase)
PythonRunner::PythonRunner(const MOBase::IOrganizer *moInfo)
: m_MOInfo(moInfo)
{
m_PythonHome = new char[MAX_PATH + 1];
m_PythonHome = new wchar_t[MAX_PATH + 1];
}
static const char *argv0 = "ModOrganizer.exe";
@@ -1215,16 +1227,17 @@ bool PythonRunner::initPython(const QString &pythonPath)
if (!pythonPath.isEmpty() && !QFile::exists(pythonPath + "/python.exe")) {
return false;
}
strncpy(m_PythonHome, pythonPath.toUtf8().constData(), MAX_PATH);
pythonPath.toWCharArray(m_PythonHome);
if (!pythonPath.isEmpty()) {
Py_SetPythonHome(m_PythonHome);
}
char argBuffer[MAX_PATH];
strcpy(argBuffer, argv0);
wchar_t argBuffer[MAX_PATH];
const size_t cSize = strlen(argv0) + 1;
mbstowcs(argBuffer, argv0, MAX_PATH);
Py_SetProgramName(argBuffer);
PyImport_AppendInittab("mobase", &initmobase);
PyImport_AppendInittab("mobase", &PyInit_mobase);
Py_OptimizeFlag = 2;
Py_NoSiteFlag = 1;
Py_InitializeEx(0);
@@ -1233,15 +1246,15 @@ bool PythonRunner::initPython(const QString &pythonPath)
return false;
}
PySys_SetArgv(0, (char**)&argBuffer);
PySys_SetArgv(0, (wchar_t**)&argBuffer);
bpy::object mainModule = bpy::import("__main__");
bpy::object mainNamespace = mainModule.attr("__dict__");
mainNamespace["sys"] = bpy::import("sys");
initPath(mainNamespace);
bpy::import("site");
mainNamespace["cStringIO"] = bpy::import("cStringIO");
bpy::exec("s_ErrIO = cStringIO.StringIO()\n"
mainNamespace["io"] = bpy::import("io");
bpy::exec("s_ErrIO = io.StringIO()\n"
"sys.stderr = s_ErrIO",
mainNamespace);
return true;
@@ -1277,11 +1290,7 @@ void PythonRunner::initPath(bpy::object &moduleNamespace)
{
static QString paths[] = {
m_MOInfo->pluginDataPath(),
QCoreApplication::applicationDirPath(),
QCoreApplication::applicationDirPath() + "/python27.zip",
QCoreApplication::applicationDirPath() + "/python27.zip/Lib",
QCoreApplication::applicationDirPath() + "/python27.zip/DLLs",
QCoreApplication::applicationDirPath() + "/python27.zip/Lib/site-packages",
QCoreApplication::applicationDirPath()
};
for (int i = 0; i < sizeof(paths) / sizeof(QString); ++i) {
+28
View File
@@ -7,7 +7,35 @@ static const sipAPIDef *sipAPI()
{
static const sipAPIDef *sipApi = nullptr;
if (sipApi == nullptr) {
#if defined(SIP_USE_PYCAPSULE)
sipApi = (const sipAPIDef *)PyCapsule_Import("sip._C_API", 0);
#else
PyObject *sip_module;
PyObject *sip_module_dict;
PyObject *c_api;
/* Import the SIP module. */
sip_module = PyImport_ImportModule("sip");
if (sip_module == NULL)
return NULL;
/* Get the module's dictionary. */
sip_module_dict = PyModule_GetDict(sip_module);
/* Get the "_C_API" attribute. */
c_api = PyDict_GetItemString(sip_module_dict, "_C_API");
if (c_api == NULL)
return NULL;
/* Sanity check that it is the right type. */
if (!PyCObject_Check(c_api))
return NULL;
/* Get the actual pointer from the object. */
sipApi = (const sipAPIDef *)PyCObject_AsVoidPtr(c_api);
#endif
}
return sipApi;
+1 -1
View File
@@ -105,7 +105,7 @@ private:
Q_DISABLE_COPY(ModRepositoryBridgeWrapper)
private slots:
private Q_SLOTS:
void filesAvailable(int modID, QVariant userData, const QList<ModRepositoryFileInfo> &resultData)
{