Index: CMakeLists_Dependencies.cmake
===================================================================
--- CMakeLists_Dependencies.cmake	(revision 23269)
+++ CMakeLists_Dependencies.cmake	(working copy)
@@ -144,8 +144,8 @@
 #	set(COMPILE_PYTHON ON)
 #endif()
 #
-find_package (Python2 REQUIRED COMPONENTS Interpreter Development)
-if (Python2_Development_FOUND)
+find_package (Python3 REQUIRED COMPONENTS Interpreter Development)
+if (Python3_Development_FOUND)
 	message("Python Library Found OK")
 	set(HAVE_PYTHON ON)
 	set(COMPILE_PYTHON ON)
Index: scribus/main_win32.cpp
===================================================================
--- scribus/main_win32.cpp	(revision 23269)
+++ scribus/main_win32.cpp	(working copy)
@@ -153,11 +153,13 @@
 	QString pythonHome = appPath + "/python";
 	if (!QDir(pythonHome).exists())
 		return; //assume a custom python
+	pythonHome = QFileInfo(pythonHome).canonicalFilePath();
 
 	QString tmp = "PYTHONHOME=" + QDir::toNativeSeparators(pythonHome);
 	_wputenv((const wchar_t*) tmp.utf16());
 
-	QString nativePath = QDir::toNativeSeparators(appPath);
+	QString nativePath = QFileInfo(appPath).canonicalFilePath();
+	nativePath = QDir::toNativeSeparators(nativePath);
 	tmp = "PYTHONPATH=";
 	tmp += nativePath;
 	tmp += "\\python;";
Index: scribus/plugins/scriptplugin/cmdannotations.cpp
===================================================================
--- scribus/plugins/scriptplugin/cmdannotations.cpp	(revision 23269)
+++ scribus/plugins/scriptplugin/cmdannotations.cpp	(working copy)
@@ -169,7 +169,7 @@
 		break;
 	}
 
-	PyObject *rstr = PyString_FromString(rv.toUtf8());
+	PyObject *rstr = PyUnicode_FromString(rv.toUtf8());
 	return rstr;
 }
 
@@ -211,8 +211,8 @@
 
 			getLinkData(drv, a.Ziel(), a.Action());
 			const char path[] = "path";
-			PyObject *pathkey = PyString_FromString(path);
-			PyObject *pathvalue = PyString_FromString(a.Extern().toUtf8());
+			PyObject *pathkey = PyUnicode_FromString(path);
+			PyObject *pathvalue = PyUnicode_FromString(a.Extern().toUtf8());
 			PyDict_SetItem(drv, pathkey, pathvalue);
 			add_text_to_dict(drv, item);
 			PyObject *rv = Py_BuildValue("(sO)", name3, drv);
@@ -221,8 +221,8 @@
 		if (atype == Annotation::Link && actype == Annotation::Action_URI)
 		{
 			const char uri[] = "uri";
-			PyObject *ukey = PyString_FromString(uri);
-			PyObject *uval = PyString_FromString(a.Extern().toUtf8());
+			PyObject *ukey = PyUnicode_FromString(uri);
+			PyObject *uval = PyUnicode_FromString(a.Extern().toUtf8());
 			PyDict_SetItem(drv, ukey, uval);
 			add_text_to_dict(drv, item);
 			char *name4= const_cast<char*>("Link URI");
@@ -295,12 +295,12 @@
 			};
 			if (icon >= 0 && icon < 9)
 			{
-				PyObject *iconkey = PyString_FromString("icon");
-				PyObject *iconvalue = PyString_FromString(icons[icon]);
+				PyObject *iconkey = PyUnicode_FromString("icon");
+				PyObject *iconvalue = PyUnicode_FromString(icons[icon]);
 				PyDict_SetItem(drv, iconkey, iconvalue);
 			}
 
-			PyObject *openkey = PyString_FromString("open");
+			PyObject *openkey = PyUnicode_FromString("open");
 			PyObject *open = Py_False;
 			if (a.IsAnOpen())
 				open = Py_True;
@@ -585,7 +585,7 @@
 			break;
 	}
 	
-	return PyString_FromString(m_doc->Items->at(i)->itemName().toUtf8());
+	return PyUnicode_FromString(m_doc->Items->at(i)->itemName().toUtf8());
 }
 
 
@@ -613,8 +613,8 @@
 	int x, y;
 
 	const char pagenum[] = "page";
-	PyObject *pagekey = PyString_FromString(pagenum);
-	PyObject *pagevalue = PyInt_FromLong((long)page);
+	PyObject *pagekey = PyUnicode_FromString(pagenum);
+	PyObject *pagevalue = PyLong_FromLong((long)page);
 	PyDict_SetItem(rv, pagekey, pagevalue);
 	
 	QStringList qsl = action.split(" ", QString::SkipEmptyParts);
@@ -621,15 +621,15 @@
 
 	x = qsl[0].toInt();
 	const char x2[] = "x";
-	PyObject *xkey = PyString_FromString(x2);
-	PyObject *xvalue = PyInt_FromLong((long)x);
+	PyObject *xkey = PyUnicode_FromString(x2);
+	PyObject *xvalue = PyLong_FromLong((long)x);
 	PyDict_SetItem(rv, xkey, xvalue);
 
 	int height =ScCore->primaryMainWindow()->doc->pageHeight();
 	y = height - qsl[1].toInt();
 	const char y2[] = "y";
-	PyObject *ykey = PyString_FromString(y2);
-	PyObject *yvalue = PyInt_FromLong((long)y);
+	PyObject *ykey = PyUnicode_FromString(y2);
+	PyObject *yvalue = PyLong_FromLong((long)y);
 	PyDict_SetItem(rv, ykey, yvalue);
 
 	return rv;
@@ -670,9 +670,9 @@
 static void add_text_to_dict(PyObject *drv, PageItem * item)
 {
 	const char text[] = "text";
-	PyObject *textkey = PyString_FromString(text);
+	PyObject *textkey = PyUnicode_FromString(text);
 	QString txt = item->itemText.text(0, item->itemText.length());
-	PyObject *textvalue = PyString_FromString(txt.toUtf8());
+	PyObject *textvalue = PyUnicode_FromString(txt.toUtf8());
 	PyDict_SetItem(drv, textkey, textvalue);
 
 	Annotation &a = item->annotation();
@@ -681,8 +681,8 @@
 	if (actype == Annotation::Action_JavaScript)
 	{
 		const char text[] = "javascript";
-		PyObject *jskey = PyString_FromString(text);
-		PyObject *jsvalue = PyString_FromString(item->annotation().Action().toUtf8());
+		PyObject *jskey = PyUnicode_FromString(text);
+		PyObject *jsvalue = PyUnicode_FromString(item->annotation().Action().toUtf8());
 		PyDict_SetItem(drv, jskey, jsvalue);
 	}
 
@@ -694,10 +694,10 @@
 						"Named", nullptr };
 
 	const char action[] = "action";
-	PyObject *akey = PyString_FromString(action);
+	PyObject *akey = PyUnicode_FromString(action);
 	if (actype > 10)
 		actype = 6;
-	PyObject *avalue = PyString_FromString(aactions[actype]);
+	PyObject *avalue = PyUnicode_FromString(aactions[actype]);
 	PyDict_SetItem(drv, akey, avalue);
 
 	int atype = a.Type();
@@ -704,7 +704,7 @@
 	if (atype == Annotation::Checkbox || atype == Annotation::RadioButton)
 	{
 		const char checked[] = "checked";
-		PyObject *checkkey = PyString_FromString(checked);
+		PyObject *checkkey = PyUnicode_FromString(checked);
 		PyObject *checkvalue = Py_False;
 		if (a.IsChk())
 			checkvalue = Py_True;
@@ -714,7 +714,7 @@
 	if (atype == Annotation::Combobox || atype == Annotation::Listbox)
 	{
 		const char editable[] = "editable";
-		PyObject *ekey = PyString_FromString(editable);
+		PyObject *ekey = PyUnicode_FromString(editable);
 
 		PyObject *edit = Py_False;
 		int result = Annotation::Flag_Edit & a.Flag();
Index: scribus/plugins/scriptplugin/cmdcell.cpp
===================================================================
--- scribus/plugins/scriptplugin/cmdcell.cpp	(revision 23269)
+++ scribus/plugins/scriptplugin/cmdcell.cpp	(working copy)
@@ -61,7 +61,7 @@
 		PyErr_SetString(PyExc_ValueError, QObject::tr("The cell %1,%2 does not exist in table", "python error").arg(row).arg(column).toLocal8Bit().constData());
 		return nullptr;
 	}
-	return PyString_FromString(table->cellAt(row, column).styleName().toUtf8());
+	return PyUnicode_FromString(table->cellAt(row, column).styleName().toUtf8());
 }
 
 PyObject *scribus_setcellstyle(PyObject* /* self */, PyObject* args)
@@ -108,7 +108,7 @@
 		PyErr_SetString(WrongFrameTypeError, QObject::tr("Cannot get cell row span from non-table item.","python error").toLocal8Bit().constData());
 		return nullptr;
 	}
-	return PyInt_FromLong(static_cast<long>(table->cellAt(row, column).rowSpan()));
+	return PyLong_FromLong(static_cast<long>(table->cellAt(row, column).rowSpan()));
 }
 
 PyObject *scribus_getcellcolumnspan(PyObject* /* self */, PyObject* args)
@@ -128,7 +128,7 @@
 		PyErr_SetString(WrongFrameTypeError, QObject::tr("Cannot get cell column span from non-table item.","python error").toLocal8Bit().constData());
 		return nullptr;
 	}
-	return PyInt_FromLong(static_cast<long>(table->cellAt(row, column).columnSpan()));
+	return PyLong_FromLong(static_cast<long>(table->cellAt(row, column).columnSpan()));
 }
 
 PyObject *scribus_getcellfillcolor(PyObject* /* self */, PyObject* args)
@@ -153,7 +153,7 @@
 		PyErr_SetString(PyExc_ValueError, QObject::tr("The cell %1,%2 does not exist in table", "python error").arg(row).arg(column).toLocal8Bit().constData());
 		return nullptr;
 	}
-	return PyString_FromString(table->cellAt(row, column).fillColor().toUtf8());
+	return PyUnicode_FromString(table->cellAt(row, column).fillColor().toUtf8());
 }
 
 PyObject *scribus_setcellfillcolor(PyObject* /* self */, PyObject* args)
Index: scribus/plugins/scriptplugin/cmdcolor.cpp
===================================================================
--- scribus/plugins/scriptplugin/cmdcolor.cpp	(revision 23269)
+++ scribus/plugins/scriptplugin/cmdcolor.cpp	(working copy)
@@ -22,7 +22,7 @@
 	l = PyList_New(edc.count());
 	for (it = edc.begin(); it != edc.end(); ++it)
 	{
-		PyList_SetItem(l, cc, PyString_FromString(it.key().toUtf8()));
+		PyList_SetItem(l, cc, PyUnicode_FromString(it.key().toUtf8()));
 		cc++;
 	}
 	return l;
Index: scribus/plugins/scriptplugin/cmddialog.cpp
===================================================================
--- scribus/plugins/scriptplugin/cmddialog.cpp	(revision 23269)
+++ scribus/plugins/scriptplugin/cmddialog.cpp	(working copy)
@@ -21,7 +21,7 @@
 	QApplication::changeOverrideCursor(QCursor(Qt::ArrowCursor));
 	bool ret = ScCore->primaryMainWindow()->slotFileNew();
 	QApplication::changeOverrideCursor(Qt::ArrowCursor);
-	return PyInt_FromLong(static_cast<long>(ret));
+	return PyLong_FromLong(static_cast<long>(ret));
 }
 
 PyObject *scribus_filedia(PyObject* /* self */, PyObject* args, PyObject* kw)
@@ -68,7 +68,7 @@
 										);
 //	QApplication::restoreOverrideCursor();
 	// FIXME: filename return unicode OK?
-	return PyString_FromString(fName.toUtf8());
+	return PyUnicode_FromString(fName.toUtf8());
 }
 
 PyObject *scribus_messdia(PyObject* /* self */, PyObject* args, PyObject* kw)
@@ -103,7 +103,7 @@
 	}
 	result = mb.exec();
 //	QApplication::restoreOverrideCursor();
-	return PyInt_FromLong(static_cast<long>(result));
+	return PyLong_FromLong(static_cast<long>(result));
 }
 
 PyObject *scribus_valdialog(PyObject* /* self */, PyObject* args)
@@ -120,7 +120,7 @@
 										QLineEdit::Normal,
 										QString::fromUtf8(value));
 //	QApplication::restoreOverrideCursor();
-	return PyString_FromString(txt.toUtf8());
+	return PyUnicode_FromString(txt.toUtf8());
 }
 
 PyObject *scribus_newstyledialog(PyObject*, PyObject* args)
@@ -143,7 +143,7 @@
 		st.create(p);
 		d->redefineStyles(st, false);
 		ScCore->primaryMainWindow()->styleMgr()->setDoc(d);
-		return PyString_FromString(s.toUtf8());
+		return PyUnicode_FromString(s.toUtf8());
 	}
 	Py_RETURN_NONE;
 }
Index: scribus/plugins/scriptplugin/cmddoc.cpp
===================================================================
--- scribus/plugins/scriptplugin/cmddoc.cpp	(revision 23269)
+++ scribus/plugins/scriptplugin/cmddoc.cpp	(working copy)
@@ -74,7 +74,7 @@
 								orientation, firstPageNr, "Custom", true, numPages);
 	ScCore->primaryMainWindow()->doc->setPageSetFirstPage(pagesType, firstPageOrder);
 
-	return PyInt_FromLong(static_cast<long>(ret));
+	return PyLong_FromLong(static_cast<long>(ret));
 }
 
 PyObject *scribus_newdoc(PyObject* /* self */, PyObject* args)
@@ -109,7 +109,7 @@
 	btr = value2pts(btr, unit);
 	bool ret = ScCore->primaryMainWindow()->doFileNew(b, h, tpr, lr, rr, btr, 0, 1, false, ds, unit, fsl, ori, fNr, "Custom", true);
 	//	qApp->processEvents();
-	return PyInt_FromLong(static_cast<long>(ret));
+	return PyLong_FromLong(static_cast<long>(ret));
 }
 
 PyObject *scribus_setmargins(PyObject* /* self */, PyObject* args)
@@ -160,12 +160,12 @@
 	ScCore->primaryMainWindow()->doc->setModified(false);
 	bool ret = ScCore->primaryMainWindow()->slotFileClose();
 	qApp->processEvents();
-	return PyInt_FromLong(static_cast<long>(ret));
+	return PyLong_FromLong(static_cast<long>(ret));
 }
 
 PyObject *scribus_havedoc(PyObject* /* self */)
 {
-	return PyInt_FromLong(static_cast<long>(ScCore->primaryMainWindow()->HaveDoc));
+	return PyLong_FromLong(static_cast<long>(ScCore->primaryMainWindow()->HaveDoc));
 }
 
 PyObject *scribus_opendoc(PyObject* /* self */, PyObject* args)
@@ -199,9 +199,9 @@
 		return nullptr;
 	if (! ScCore->primaryMainWindow()->doc->hasName)
 	{
-		return PyString_FromString("");
+		return PyUnicode_FromString("");
 	}
-	return PyString_FromString(ScCore->primaryMainWindow()->doc->documentFileName().toUtf8());
+	return PyUnicode_FromString(ScCore->primaryMainWindow()->doc->documentFileName().toUtf8());
 }
 
 PyObject *scribus_savedocas(PyObject* /* self */, PyObject* args)
@@ -265,7 +265,7 @@
 {
 	if (!checkHaveDocument())
 		return nullptr;
-	return PyInt_FromLong(static_cast<long>(ScCore->primaryMainWindow()->doc->unitIndex()));
+	return PyLong_FromLong(static_cast<long>(ScCore->primaryMainWindow()->doc->unitIndex()));
 }
 
 PyObject *scribus_loadstylesfromfile(PyObject* /* self */, PyObject *args)
@@ -323,7 +323,7 @@
 	int n = 0;
 	for ( ; it != itEnd; ++it )
 	{
-		PyList_SET_ITEM(names, n++, PyString_FromString(it.key().toUtf8().data()) );
+		PyList_SET_ITEM(names, n++, PyUnicode_FromString(it.key().toUtf8().data()) );
 	}
 	return names;
 }
@@ -411,7 +411,7 @@
 		PyErr_SetString(PyExc_IndexError, QObject::tr("Page number out of range: '%1'.","python error").arg(e+1).toLocal8Bit().constData());
 		return nullptr;
 	}
-	return PyString_FromString(currentDoc->DocPages.at(e)->masterPageName().toUtf8());
+	return PyUnicode_FromString(currentDoc->DocPages.at(e)->masterPageName().toUtf8());
 }
 
 PyObject* scribus_applymasterpage(PyObject* /* self */, PyObject* args)
Index: scribus/plugins/scriptplugin/cmdgetprop.cpp
===================================================================
--- scribus/plugins/scriptplugin/cmdgetprop.cpp	(revision 23269)
+++ scribus/plugins/scriptplugin/cmdgetprop.cpp	(working copy)
@@ -44,7 +44,7 @@
 		result = "Multiple";
 	}
 
-	return PyString_FromString(result.toUtf8());
+	return PyUnicode_FromString(result.toUtf8());
 }
 
 PyObject *scribus_getfillcolor(PyObject* /* self */, PyObject* args)
@@ -57,7 +57,7 @@
 	PageItem *item = GetUniqueItem(QString::fromUtf8(Name));
 	if (item == nullptr)
 		return nullptr;
-	return PyString_FromString(item->fillColor().toUtf8());
+	return PyUnicode_FromString(item->fillColor().toUtf8());
 }
 
 PyObject *scribus_getfilltrans(PyObject* /* self */, PyObject* args)
@@ -83,7 +83,7 @@
 	PageItem *item = GetUniqueItem(QString::fromUtf8(Name));
 	if (item == nullptr)
 		return nullptr;
-	return PyInt_FromLong(static_cast<long>(item->fillBlendmode()));
+	return PyLong_FromLong(static_cast<long>(item->fillBlendmode()));
 }
 
 PyObject *scribus_getcustomlinestyle(PyObject* /* self */, PyObject* args)
@@ -96,7 +96,7 @@
 	PageItem *item = GetUniqueItem(QString::fromUtf8(Name));
 	if (item == nullptr)
 		return nullptr;
-	return PyString_FromString(item->customLineStyle().toUtf8());
+	return PyUnicode_FromString(item->customLineStyle().toUtf8());
 }
 
 PyObject *scribus_getlinecolor(PyObject* /* self */, PyObject* args)
@@ -109,7 +109,7 @@
 	PageItem *item = GetUniqueItem(QString::fromUtf8(Name));
 	if (item == nullptr)
 		return nullptr;
-	return PyString_FromString(item->lineColor().toUtf8());
+	return PyUnicode_FromString(item->lineColor().toUtf8());
 }
 
 PyObject *scribus_getlinetrans(PyObject* /* self */, PyObject* args)
@@ -135,7 +135,7 @@
 	PageItem *item = GetUniqueItem(QString::fromUtf8(Name));
 	if (item == nullptr)
 		return nullptr;
-	return PyInt_FromLong(static_cast<long>(item->lineBlendmode()));
+	return PyLong_FromLong(static_cast<long>(item->lineBlendmode()));
 }
 
 PyObject *scribus_getlinewidth(PyObject* /* self */, PyObject* args)
@@ -161,7 +161,7 @@
 	PageItem *item = GetUniqueItem(QString::fromUtf8(Name));
 	if (item == nullptr)
 		return nullptr;
-	return PyInt_FromLong(static_cast<long>(item->lineShade()));
+	return PyLong_FromLong(static_cast<long>(item->lineShade()));
 }
 
 PyObject *scribus_getlinejoin(PyObject* /* self */, PyObject* args)
@@ -174,7 +174,7 @@
 	PageItem *item = GetUniqueItem(QString::fromUtf8(Name));
 	if (item == nullptr)
 		return nullptr;
-	return PyInt_FromLong(static_cast<long>(item->PLineJoin));
+	return PyLong_FromLong(static_cast<long>(item->PLineJoin));
 }
 
 PyObject *scribus_getlinecap(PyObject* /* self */, PyObject* args)
@@ -187,7 +187,7 @@
 	PageItem *item = GetUniqueItem(QString::fromUtf8(Name));
 	if (item == nullptr)
 		return nullptr;
-	return PyInt_FromLong(static_cast<long>(item->PLineEnd));
+	return PyLong_FromLong(static_cast<long>(item->PLineEnd));
 }
 
 PyObject *scribus_getlinestyle(PyObject* /* self */, PyObject* args)
@@ -200,7 +200,7 @@
 	PageItem *item = GetUniqueItem(QString::fromUtf8(Name));
 	if (item == nullptr)
 		return nullptr;
-	return PyInt_FromLong(static_cast<long>(item->PLineArt));
+	return PyLong_FromLong(static_cast<long>(item->PLineArt));
 }
 
 PyObject *scribus_getfillshade(PyObject* /* self */, PyObject* args)
@@ -213,7 +213,7 @@
 	PageItem *item = GetUniqueItem(QString::fromUtf8(Name));
 	if (item == nullptr)
 		return nullptr;
-	return PyInt_FromLong(static_cast<long>(item->fillShade()));
+	return PyLong_FromLong(static_cast<long>(item->fillShade()));
 }
 
 PyObject *scribus_getcornerrad(PyObject* /* self */, PyObject* args)
@@ -226,7 +226,7 @@
 	PageItem *item = GetUniqueItem(QString::fromUtf8(Name));
 	if (item == nullptr)
 		return nullptr;
-	return PyInt_FromLong(static_cast<long>(item->cornerRadius()));
+	return PyLong_FromLong(static_cast<long>(item->cornerRadius()));
 }
 
 PyObject *scribus_getimgoffset(PyObject* /* self */, PyObject* args)
@@ -265,7 +265,7 @@
 	PageItem *item = GetUniqueItem(QString::fromUtf8(Name));
 	if (item == nullptr)
 		return nullptr;
-	return PyString_FromString(item->Pfile.toUtf8());
+	return PyUnicode_FromString(item->Pfile.toUtf8());
 }
 
 PyObject *scribus_getposi(PyObject* /* self */, PyObject* args)
@@ -358,13 +358,13 @@
 			{
 				if (currentDoc->Items->at(lam)->itemType() == typ)
 				{
-					PyList_SetItem(l, counter2, PyString_FromString(currentDoc->Items->at(lam)->itemName().toUtf8()));
+					PyList_SetItem(l, counter2, PyUnicode_FromString(currentDoc->Items->at(lam)->itemName().toUtf8()));
 					counter2++;
 				}
 			}
 			else
 			{
-				PyList_SetItem(l, counter2, PyString_FromString(currentDoc->Items->at(lam)->itemName().toUtf8()));
+				PyList_SetItem(l, counter2, PyUnicode_FromString(currentDoc->Items->at(lam)->itemName().toUtf8()));
 				counter2++;
 			}
 		}
@@ -431,7 +431,7 @@
 
 	const ScImage& pixm = item->pixm;
 	if (pixm.width() == 0 || pixm.height() == 0)
-		return PyInt_FromLong(static_cast<long>(-1));
+		return PyLong_FromLong(static_cast<long>(-1));
 
 	const ImageInfoRecord& iir = pixm.imgInfo;
 	int cspace = iir.colorspace;
@@ -442,7 +442,7 @@
 	Duotone = 3,
 	Monochrome = 4
 	*/
-	return PyInt_FromLong(static_cast<long>(cspace));
+	return PyLong_FromLong(static_cast<long>(cspace));
 }
 
 
Index: scribus/plugins/scriptplugin/cmdgetsetprop.cpp
===================================================================
--- scribus/plugins/scriptplugin/cmdgetsetprop.cpp	(revision 23269)
+++ scribus/plugins/scriptplugin/cmdgetsetprop.cpp	(working copy)
@@ -15,16 +15,16 @@
 
 QObject* getQObjectFromPyArg(PyObject* arg)
 {
-	if (PyString_Check(arg))
+	if (PyUnicode_Check(arg))
 		// It's a string. Look for a pageItem by that name. Do NOT accept a
 		// selection.
-		return getPageItemByName(QString::fromUtf8(PyString_AsString(arg)));
-	if (PyCObject_Check(arg))
+		return getPageItemByName(PyUnicode_asQString(arg));
+	if (PyCapsule_CheckExact(arg))
 	{
 		// It's a PyCObject, ie a wrapped pointer. Check it's not nullptr
 		// and return it.
 		// FIXME: Try to check that its a pointer to a QObject instance
-		QObject* tempObject = (QObject*)PyCObject_AsVoidPtr(arg);
+		QObject* tempObject = (QObject*) PyCapsule_GetPointer(arg, nullptr);
 		if (!tempObject)
 		{
 			PyErr_SetString(PyExc_TypeError, "INTERNAL: Passed nullptr PyCObject");
@@ -40,7 +40,7 @@
 
 PyObject* wrapQObject(QObject* obj)
 {
-	return PyCObject_FromVoidPtr((void*)obj, nullptr);
+	return PyCapsule_New((void*) obj, nullptr, nullptr);
 }
 
 
@@ -78,13 +78,13 @@
 	objArg = nullptr; // no need to decref, it's borrowed
 
 	// Look up the property and retrive its type information
-	const char* type = getpropertytype( (QObject*)obj, propertyname, includesuper);
+	const char* type = getpropertytype( (QObject*) obj, propertyname, includesuper);
 	if (type == nullptr)
 	{
 		PyErr_SetString(PyExc_KeyError, QObject::tr("Property not found").toLocal8Bit().constData());
 		return nullptr;
 	}
-	return PyString_FromString(type);
+	return PyUnicode_FromString(type);
 }
 
 PyObject* convert_QStringList_to_PyListObject(QStringList& origlist)
@@ -94,7 +94,7 @@
 		return nullptr;
 
 	for ( QStringList::Iterator it = origlist.begin(); it != origlist.end(); ++it )
-		if (PyList_Append(resultList, PyString_FromString((*it).toUtf8().data())) == -1)
+		if (PyList_Append(resultList, PyUnicode_FromString((*it).toUtf8().data())) == -1)
 			return nullptr;
 
 	return resultList;
@@ -283,9 +283,12 @@
 		resultobj = PyBool_FromLong(prop.toBool());
 	// STRING TYPES
 	else if (prop.type() == QVariant::ByteArray)
-		resultobj = PyString_FromString(prop.toByteArray().data());
+	{
+		QByteArray ba = prop.toByteArray();
+		resultobj = PyBytes_FromStringAndSize(ba.data(), ba.size());
+	}
 	else if (prop.type() == QVariant::String)
-		resultobj = PyString_FromString(prop.toString().toUtf8().data());
+		resultobj = PyUnicode_FromString(prop.toString().toUtf8().data());
 	// HIGHER ORDER TYPES
 	else if (prop.type() == QVariant::Point)
 	{
@@ -372,10 +375,10 @@
 			success = obj->setProperty(propertyName, 0);
 		else if (PyObject_IsTrue(objValue) == 1)
 			success = obj->setProperty(propertyName, 1);
-		else if (PyInt_Check(objValue))
-			success = obj->setProperty(propertyName, PyInt_AsLong(objValue) == 0);
 		else if (PyLong_Check(objValue))
 			success = obj->setProperty(propertyName, PyLong_AsLong(objValue) == 0);
+		else if (PyLong_Check(objValue))
+			success = obj->setProperty(propertyName, PyLong_AsLong(objValue) == 0);
 		else
 			matched = false;
 	}
@@ -382,10 +385,10 @@
 	else if (propertyType == "int")
 	{
 		matched = true;
-		if (PyInt_Check(objValue))
-			success = obj->setProperty(propertyName, (int)PyInt_AsLong(objValue));
+		if (PyLong_Check(objValue))
+			success = obj->setProperty(propertyName, (int) PyLong_AsLong(objValue));
 		else if (PyLong_Check(objValue))
-			success = obj->setProperty(propertyName, (int)PyLong_AsLong(objValue));
+			success = obj->setProperty(propertyName, (int) PyLong_AsLong(objValue));
 		else
 			matched = false;
 	}
@@ -402,8 +405,8 @@
 	else if (propertyType == "QString")
 	{
 		matched = true;
-		if (PyString_Check(objValue))
-			success = obj->setProperty(propertyName, QString::fromUtf8(PyString_AsString(objValue)));
+		if (PyBytes_Check(objValue))
+			success = obj->setProperty(propertyName, QString::fromUtf8(PyBytes_AsString(objValue)));
 		else if (PyUnicode_Check(objValue))
 		{
 			// Get a pointer to the internal buffer of the Py_Unicode object, which is UCS2 formatted
@@ -417,11 +420,11 @@
 	else if (propertyType == "QCString")
 	{
 		matched = true;
-		if (PyString_Check(objValue))
+		if (PyBytes_Check(objValue))
 		{
 			// FIXME: should raise an exception instead of mangling the string when
 			// out of charset chars present.
-			QString utfString = QString::fromUtf8(PyString_AsString(objValue));
+			QString utfString = QString::fromUtf8(PyBytes_AsString(objValue));
 			success = obj->setProperty(propertyName, utfString.toLatin1());
 		}
 		else if (PyUnicode_Check(objValue))
@@ -454,7 +457,7 @@
 		if (!objRepr)
 			return nullptr;
 		// Extract the repr() string
-		QString reprString = QString::fromUtf8(PyString_AsString(objRepr));
+		QString reprString = PyUnicode_asQString(objRepr);
 		Py_DECREF(objRepr);
 
 		// And return an error
Index: scribus/plugins/scriptplugin/cmdmani.cpp
===================================================================
--- scribus/plugins/scriptplugin/cmdmani.cpp	(revision 23269)
+++ scribus/plugins/scriptplugin/cmdmani.cpp	(working copy)
@@ -350,7 +350,7 @@
 
 PyObject *scribus_groupobj(PyObject* /* self */, PyObject* args)
 {
-	char *Name = const_cast<char*>("");
+	const char *Name = const_cast<char*>("");
 	PyObject *il = nullptr;
 	if (!PyArg_ParseTuple(args, "|O", &il))
 		return nullptr;
@@ -361,8 +361,8 @@
 		PyErr_SetString(PyExc_TypeError, QObject::tr("Need selection or argument list of items to group", "python error").toLocal8Bit().constData());
 		return nullptr;
 	}
-	Selection *tempSelection=nullptr;
-	Selection *finalSelection=nullptr;
+	Selection *tempSelection = nullptr;
+	Selection *finalSelection = nullptr;
 	//uint ap = ScCore->primaryMainWindow()->doc->currentPage()->pageNr();
 	// If we were passed a list of items to group...
 	if (il != nullptr)
@@ -374,7 +374,7 @@
 			// FIXME: We might need to explicitly get this string as utf8
 			// but as sysdefaultencoding is utf8 it should be a no-op to do
 			// so anyway.
-			Name = PyString_AsString(PyList_GetItem(il, i));
+			Name = PyUnicode_AsUTF8(PyList_GetItem(il, i));
 			PageItem *ic = GetUniqueItem(QString::fromUtf8(Name));
 			if (ic == nullptr)
 			{
@@ -383,10 +383,10 @@
 			}
 			tempSelection->addItem (ic, true);
 		}
-		finalSelection=tempSelection;
+		finalSelection = tempSelection;
 	}
 	else
-		finalSelection=ScCore->primaryMainWindow()->doc->m_Selection;
+		finalSelection = ScCore->primaryMainWindow()->doc->m_Selection;
 	if (finalSelection->count() < 2)
 	{
 		// We can't very well group only one item
@@ -400,7 +400,7 @@
 	finalSelection=nullptr;
 	delete tempSelection;
 	
-	return (group ? PyString_FromString(group->itemName().toUtf8()) : nullptr);
+	return (group ? PyUnicode_FromString(group->itemName().toUtf8()) : nullptr);
 }
 
 PyObject *scribus_ungroupobj(PyObject* /* self */, PyObject* args)
@@ -460,10 +460,11 @@
 		return nullptr;
 	if (!checkHaveDocument())
 		return nullptr;
-	if ((i < static_cast<int>(ScCore->primaryMainWindow()->doc->m_Selection->count())) && (i > -1))
-		return PyString_FromString(ScCore->primaryMainWindow()->doc->m_Selection->itemAt(i)->itemName().toUtf8());
+	Selection * selection = ScCore->primaryMainWindow()->doc->m_Selection;
+	if ((i < selection->count()) && (i > -1))
+		return PyUnicode_FromString(selection->itemAt(i)->itemName().toUtf8());
 	// FIXME: Should probably return None if no selection?
-	return PyString_FromString("");
+	return PyUnicode_FromString("");
 }
 
 PyObject *scribus_selcount(PyObject* /* self */)
@@ -470,7 +471,7 @@
 {
 	if (!checkHaveDocument())
 		return nullptr;
-	return PyInt_FromLong(static_cast<long>(ScCore->primaryMainWindow()->doc->m_Selection->count()));
+	return PyLong_FromLong(static_cast<long>(ScCore->primaryMainWindow()->doc->m_Selection->count()));
 }
 
 PyObject *scribus_selectobj(PyObject* /* self */, PyObject* args)
@@ -507,8 +508,8 @@
 		return nullptr;
 	item->toggleLock();
 	if (item->locked())
-		return PyInt_FromLong(1);
-	return PyInt_FromLong(0);
+		return PyLong_FromLong(1);
+	return PyLong_FromLong(0);
 }
 
 PyObject *scribus_islocked(PyObject* /* self */, PyObject* args)
Index: scribus/plugins/scriptplugin/cmdmisc.cpp
===================================================================
--- scribus/plugins/scriptplugin/cmdmisc.cpp	(revision 23269)
+++ scribus/plugins/scriptplugin/cmdmisc.cpp	(working copy)
@@ -47,7 +47,7 @@
 	{
 		if (it.current().usable())
 		{
-			PyList_SetItem(l, cc, PyString_FromString(it.currentKey().toUtf8()));
+			PyList_SetItem(l, cc, PyUnicode_FromString(it.currentKey().toUtf8()));
 			cc++;
 		}
 	}
@@ -110,8 +110,7 @@
 		// User specified no format, so use the historical default of PPM format.
 		format =  const_cast<char*>("PPM");
 	QPixmap pm = FontSample(PrefsManager::instance().appPrefs.fontPrefs.AvailFonts[QString::fromUtf8(Name)], Size, ts, Qt::white);
-	// If the user specified an empty filename, return the image data as
-	// a string. Otherwise, save it to disk.
+	// If the user specified an empty filename, return the image data as bytes. Otherwise, save it to disk.
 	if (QString::fromUtf8(FileName).isEmpty())
 	{
 		QByteArray buffer_string = "";
@@ -126,7 +125,7 @@
 		int bufferSize = buffer.size();
 		buffer.close();
 		// Now make a Python string from the data we generated
-		PyObject* stringPython = PyString_FromStringAndSize(buffer_string,bufferSize);
+		PyObject* stringPython = PyBytes_FromStringAndSize(buffer_string, bufferSize);
 		// Return even if the result is nullptr (error) since an exception will have been
 		// set in that case.
 		return stringPython;
@@ -150,10 +149,10 @@
 {
 	if (!checkHaveDocument())
 		return nullptr;
-	PyObject *l;
-	l = PyList_New(ScCore->primaryMainWindow()->doc->Layers.count());
-	for (int lam=0; lam < ScCore->primaryMainWindow()->doc->Layers.count(); lam++)
-		PyList_SetItem(l, lam, PyString_FromString(ScCore->primaryMainWindow()->doc->Layers[lam].Name.toUtf8()));
+	ScribusDoc* doc = ScCore->primaryMainWindow()->doc;
+	PyObject *l = PyList_New(doc->Layers.count());
+	for (int i = 0; i < doc->Layers.count(); i++)
+		PyList_SetItem(l, i, PyUnicode_FromString(doc->Layers[i].Name.toUtf8()));
 	return l;
 }
 
@@ -184,7 +183,7 @@
 {
 	if (!checkHaveDocument())
 		return nullptr;
-	return PyString_FromString(ScCore->primaryMainWindow()->doc->activeLayerName().toUtf8());
+	return PyUnicode_FromString(ScCore->primaryMainWindow()->doc->activeLayerName().toUtf8());
 }
 
 PyObject *scribus_senttolayer(PyObject* /* self */, PyObject* args)
@@ -474,7 +473,7 @@
 		PyErr_SetString(NotFoundError, QObject::tr("Layer not found.","python error").toLocal8Bit().constData());
 		return nullptr;
 	}
-	return PyInt_FromLong(static_cast<long>(i));
+	return PyLong_FromLong(static_cast<long>(i));
 }
 
 PyObject *scribus_glayerprint(PyObject* /* self */, PyObject* args)
@@ -505,7 +504,7 @@
 		PyErr_SetString(NotFoundError, QObject::tr("Layer not found.","python error").toLocal8Bit().constData());
 		return nullptr;
 	}
-	return PyInt_FromLong(static_cast<long>(i));
+	return PyLong_FromLong(static_cast<long>(i));
 }
 
 PyObject *scribus_glayerlock(PyObject* /* self */, PyObject* args)
@@ -536,7 +535,7 @@
 		PyErr_SetString(NotFoundError, QObject::tr("Layer not found.","python error").toLocal8Bit().constData());
 		return nullptr;
 	}
-	return PyInt_FromLong(static_cast<long>(i));
+	return PyLong_FromLong(static_cast<long>(i));
 }
 
 PyObject *scribus_glayeroutline(PyObject* /* self */, PyObject* args)
@@ -567,7 +566,7 @@
 		PyErr_SetString(NotFoundError, QObject::tr("Layer not found.","python error").toLocal8Bit().constData());
 		return nullptr;
 	}
-	return PyInt_FromLong(static_cast<long>(i));
+	return PyLong_FromLong(static_cast<long>(i));
 }
 
 PyObject *scribus_glayerflow(PyObject* /* self */, PyObject* args)
@@ -598,7 +597,7 @@
 		PyErr_SetString(NotFoundError, QObject::tr("Layer not found.","python error").toLocal8Bit().constData());
 		return nullptr;
 	}
-	return PyInt_FromLong(static_cast<long>(i));
+	return PyLong_FromLong(static_cast<long>(i));
 }
 
 PyObject *scribus_glayerblend(PyObject* /* self */, PyObject* args)
@@ -629,7 +628,7 @@
 		PyErr_SetString(NotFoundError, QObject::tr("Layer not found.","python error").toLocal8Bit().constData());
 		return nullptr;
 	}
-	return PyInt_FromLong(static_cast<long>(i));
+	return PyLong_FromLong(static_cast<long>(i));
 }
 
 PyObject *scribus_glayertrans(PyObject* /* self */, PyObject* args)
@@ -735,7 +734,7 @@
 
 PyObject *scribus_getlanguage(PyObject* /* self */)
 {
-	return PyString_FromString(ScCore->getGuiLanguage().toUtf8());
+	return PyUnicode_FromString(ScCore->getGuiLanguage().toUtf8());
 }
 
 /*! 04.01.2007 : Joachim Neu : Moves item selection to front. */
Index: scribus/plugins/scriptplugin/cmdobj.cpp
===================================================================
--- scribus/plugins/scriptplugin/cmdobj.cpp	(revision 23269)
+++ scribus/plugins/scriptplugin/cmdobj.cpp	(working copy)
@@ -31,19 +31,20 @@
 //		PyErr_SetString(NameExistsError, QObject::tr("An object with the requested name already exists.","python error"));
 //		return nullptr;
 //	}
-	int i = ScCore->primaryMainWindow()->doc->itemAdd(PageItem::Polygon, PageItem::Rectangle,
-								pageUnitXToDocX(x), pageUnitYToDocY(y),
-								ValueToPoint(w), ValueToPoint(h),
-								ScCore->primaryMainWindow()->doc->itemToolPrefs().shapeLineWidth,
-								ScCore->primaryMainWindow()->doc->itemToolPrefs().shapeFillColor, ScCore->primaryMainWindow()->doc->itemToolPrefs().shapeLineColor);
+	ScribusDoc* doc = ScCore->primaryMainWindow()->doc;
+	int i = doc->itemAdd(PageItem::Polygon, PageItem::Rectangle,
+						pageUnitXToDocX(x), pageUnitYToDocY(y),
+						ValueToPoint(w), ValueToPoint(h),
+						doc->itemToolPrefs().shapeLineWidth,
+						doc->itemToolPrefs().shapeFillColor, doc->itemToolPrefs().shapeLineColor);
 //	ScCore->primaryMainWindow()->doc->setRedrawBounding(ScCore->primaryMainWindow()->doc->Items->at(i));
 	if (strlen(Name) > 0)
 	{
 		QString objName = QString::fromUtf8(Name);
 		if (!ItemExists(objName))
-			ScCore->primaryMainWindow()->doc->Items->at(i)->setItemName(objName);
+			doc->Items->at(i)->setItemName(objName);
 	}
-	return PyString_FromString(ScCore->primaryMainWindow()->doc->Items->at(i)->itemName().toUtf8());
+	return PyUnicode_FromString(doc->Items->at(i)->itemName().toUtf8());
 }
 
 
@@ -69,7 +70,7 @@
 		if (!ItemExists(objName))
 			ScCore->primaryMainWindow()->doc->Items->at(i)->setItemName(objName);
 	}
-	return PyString_FromString(ScCore->primaryMainWindow()->doc->Items->at(i)->itemName().toUtf8());
+	return PyUnicode_FromString(ScCore->primaryMainWindow()->doc->Items->at(i)->itemName().toUtf8());
 }
 
 
@@ -94,7 +95,7 @@
 		if (!ItemExists(objName))
 			ScCore->primaryMainWindow()->doc->Items->at(i)->setItemName(objName);
 	}
-	return PyString_FromString(ScCore->primaryMainWindow()->doc->Items->at(i)->itemName().toUtf8());
+	return PyUnicode_FromString(ScCore->primaryMainWindow()->doc->Items->at(i)->itemName().toUtf8());
 }
 
 
@@ -119,7 +120,7 @@
 		if (!ItemExists(objName))
 			ScCore->primaryMainWindow()->doc->Items->at(i)->setItemName(objName);
 	}
-	return PyString_FromString(ScCore->primaryMainWindow()->doc->Items->at(i)->itemName().toUtf8());
+	return PyUnicode_FromString(ScCore->primaryMainWindow()->doc->Items->at(i)->itemName().toUtf8());
 }
 
 PyObject *scribus_newtable(PyObject* /* self */, PyObject* args)
@@ -155,7 +156,7 @@
 		if (!ItemExists(objName))
 			ScCore->primaryMainWindow()->doc->Items->at(i)->setItemName(objName);
 	}
-	return PyString_FromString(table->itemName().toUtf8());
+	return PyUnicode_FromString(table->itemName().toUtf8());
 }
 
 PyObject *scribus_newline(PyObject* /* self */, PyObject* args)
@@ -215,7 +216,7 @@
 		if (!ItemExists(objName))
 			ScCore->primaryMainWindow()->doc->Items->at(i)->setItemName(objName);
 	}
-	return PyString_FromString(it->itemName().toUtf8());
+	return PyUnicode_FromString(it->itemName().toUtf8());
 }
 
 
@@ -292,7 +293,7 @@
 		if (!ItemExists(objName))
 			ScCore->primaryMainWindow()->doc->Items->at(ic)->setItemName(objName);
 	}
-	return PyString_FromString(it->itemName().toUtf8());
+	return PyUnicode_FromString(it->itemName().toUtf8());
 }
 
 
@@ -374,7 +375,7 @@
 		if (!ItemExists(objName))
 			ScCore->primaryMainWindow()->doc->Items->at(ic)->setItemName(objName);
 	}
-	return PyString_FromString(it->itemName().toUtf8());
+	return PyUnicode_FromString(it->itemName().toUtf8());
 }
 
 PyObject *scribus_bezierline(PyObject* /* self */, PyObject* args)
@@ -465,7 +466,7 @@
 		if (!ItemExists(objName))
 			ScCore->primaryMainWindow()->doc->Items->at(ic)->setItemName(objName);
 	}
-	return PyString_FromString(it->itemName().toUtf8());
+	return PyUnicode_FromString(it->itemName().toUtf8());
 }
 
 
@@ -506,7 +507,7 @@
 		if (!ItemExists(objName))
 			i->setItemName(objName);
 	}
-	return PyString_FromString(i->itemName().toUtf8());
+	return PyUnicode_FromString(i->itemName().toUtf8());
 }
 
 
@@ -605,13 +606,13 @@
 		int selectionStart = item->itemText.startOfSelection();
 		const ParagraphStyle& currentStyle = item->itemText.paragraphStyle(selectionStart);
 		if (currentStyle.hasParent())
-			return PyString_FromString(currentStyle.parentStyle()->name().toUtf8());
+			return PyUnicode_FromString(currentStyle.parentStyle()->name().toUtf8());
 	}
 	else
 	{
 		const ParagraphStyle& itemDefaultStyle = item->itemText.defaultStyle();
 		if (itemDefaultStyle.hasParent())
-			return PyString_FromString(itemDefaultStyle.parentStyle()->name().toUtf8());
+			return PyUnicode_FromString(itemDefaultStyle.parentStyle()->name().toUtf8());
 	}
 	Py_RETURN_NONE;
 };
@@ -798,7 +799,7 @@
 	styleList = PyList_New(0);
 	for (int i = 0; i < paragraphStyles.count(); ++i)
 	{
-		if (PyList_Append(styleList, PyString_FromString(paragraphStyles[i].name().toUtf8())))
+		if (PyList_Append(styleList, PyUnicode_FromString(paragraphStyles[i].name().toUtf8())))
 		{
 			// An exception will have already been set by PyList_Append apparently.
 			return nullptr;
@@ -817,7 +818,7 @@
 	charStyleList = PyList_New(0);
 	for (int i = 0; i < charStyles.count(); ++i)
 	{
-		if (PyList_Append(charStyleList, PyString_FromString(charStyles[i].name().toUtf8())))
+		if (PyList_Append(charStyleList, PyUnicode_FromString(charStyles[i].name().toUtf8())))
 		{
 			// An exception will have already been set by PyList_Append apparently.
 			return nullptr;
Index: scribus/plugins/scriptplugin/cmdpage.cpp
===================================================================
--- scribus/plugins/scriptplugin/cmdpage.cpp	(revision 23269)
+++ scribus/plugins/scriptplugin/cmdpage.cpp	(working copy)
@@ -18,7 +18,7 @@
 {
 	if (!checkHaveDocument())
 		return nullptr;
-	return PyInt_FromLong(static_cast<long>(ScCore->primaryMainWindow()->doc->currentPageNumber() + 1));
+	return PyLong_FromLong(static_cast<long>(ScCore->primaryMainWindow()->doc->currentPageNumber() + 1));
 }
 
 PyObject *scribus_redraw(PyObject* /* self */)
@@ -45,7 +45,7 @@
 		PyErr_SetString(PyExc_IndexError, QObject::tr("Page number out of range.","python error").toLocal8Bit().constData());
 		return nullptr;
 	}
-	return PyInt_FromLong(static_cast<long>(ScCore->primaryMainWindow()->doc->locationOfPage(e)));
+	return PyLong_FromLong(static_cast<long>(ScCore->primaryMainWindow()->doc->locationOfPage(e)));
 }
 
 PyObject *scribus_savepageeps(PyObject* /* self */, PyObject* args)
@@ -167,7 +167,7 @@
 {
 	if (!checkHaveDocument())
 		return nullptr;
-	return PyInt_FromLong(static_cast<long>(ScCore->primaryMainWindow()->doc->Pages->count()));
+	return PyLong_FromLong(static_cast<long>(ScCore->primaryMainWindow()->doc->Pages->count()));
 }
 
 PyObject *scribus_pagedimension(PyObject* /* self */)
Index: scribus/plugins/scriptplugin/cmdsetprop.cpp
===================================================================
--- scribus/plugins/scriptplugin/cmdsetprop.cpp	(revision 23269)
+++ scribus/plugins/scriptplugin/cmdsetprop.cpp	(working copy)
@@ -447,7 +447,7 @@
 		}
 		ObjectAttribute blank;
 		PyObject *val;
-		char* data;
+		const char* data;
 
 		val = PyDict_GetItemString(tmp, "Name");
 		if (!val) {
@@ -454,10 +454,10 @@
 			PyErr_SetString(PyExc_TypeError, "attribute does not have 'Name' key.");
 			return nullptr;
 		}
-		data = PyString_AsString(val);
+		data = PyUnicode_AsUTF8(val);
 		if (!data)
 			return nullptr;
-		blank.name = QString(data);
+		blank.name = QString::fromUtf8(data);
 
 		val = PyDict_GetItemString(tmp, "Type");
 		if (!val) {
@@ -464,10 +464,10 @@
 			PyErr_SetString(PyExc_TypeError, "attribute does not have 'Type' key.");
 			return nullptr;
 		}
-		data = PyString_AsString(val);
+		data = PyUnicode_AsUTF8(val);
 		if (!data)
 			return nullptr;
-		blank.type = QString(data);
+		blank.type = QString::fromUtf8(data);
 
 		val = PyDict_GetItemString(tmp, "Value");
 		if (!val) {
@@ -474,10 +474,10 @@
 			PyErr_SetString(PyExc_TypeError, "attribute does not have 'Value' key.");
 			return nullptr;
 		}
-		data = PyString_AsString(val);
+		data = PyUnicode_AsUTF8(val);
 		if (!data)
 			return nullptr;
-		blank.value = QString(data);
+		blank.value = QString::fromUtf8(data);
 
 		val = PyDict_GetItemString(tmp, "Parameter");
 		if (!val) {
@@ -484,10 +484,10 @@
 			PyErr_SetString(PyExc_TypeError, "attribute does not have 'Parameter' key.");
 			return nullptr;
 		}
-		data = PyString_AsString(val);
+		data = PyUnicode_AsUTF8(val);
 		if (!data)
 			return nullptr;
-		blank.parameter = QString(data);
+		blank.parameter = QString::fromUtf8(data);
 
 		val = PyDict_GetItemString(tmp, "Relationship");
 		if (!val) {
@@ -494,10 +494,10 @@
 			PyErr_SetString(PyExc_TypeError, "attribute does not have 'Relationship' key.");
 			return nullptr;
 		}
-		data = PyString_AsString(val);
+		data = PyUnicode_AsUTF8(val);
 		if (!data)
 			return nullptr;
-		blank.relationship = QString(data);
+		blank.relationship = QString::fromUtf8(data);
 
 		val = PyDict_GetItemString(tmp, "RelationshipTo");
 		if (!val) {
@@ -504,10 +504,10 @@
 			PyErr_SetString(PyExc_TypeError, "attribute does not have 'RelationshipTo' key.");
 			return nullptr;
 		}
-		data = PyString_AsString(val);
+		data = PyUnicode_AsUTF8(val);
 		if (!data)
 			return nullptr;
-		blank.relationshipto = QString(data);
+		blank.relationshipto = QString::fromUtf8(data);
 
 		val = PyDict_GetItemString(tmp, "AutoAddTo");
 		if (!val) {
@@ -514,10 +514,10 @@
 			PyErr_SetString(PyExc_TypeError, "attribute does not have 'AutoAddTo' key.");
 			return nullptr;
 		}
-		data = PyString_AsString(val);
+		data = PyUnicode_AsUTF8(val);
 		if (!data)
 			return nullptr;
-		blank.autoaddto = QString(data);
+		blank.autoaddto = QString::fromUtf8(data);
 
 		attributes.append(blank);
 	}
Index: scribus/plugins/scriptplugin/cmdstyle.cpp
===================================================================
--- scribus/plugins/scriptplugin/cmdstyle.cpp	(revision 23269)
+++ scribus/plugins/scriptplugin/cmdstyle.cpp	(working copy)
@@ -344,31 +344,31 @@
 
 		val = PyDict_GetItemString(line, "Color");
 		if (val)
-			sl.Color = PyString_AsString(val);
+			sl.Color = PyUnicode_asQString(val);
 		else 
 			sl.Color = currentDoc->itemToolPrefs().lineColor;
 
 		val = PyDict_GetItemString(line, "Dash");
 		if (val)
-			sl.Dash = PyInt_AsLong(val);
+			sl.Dash = PyLong_AsLong(val);
 		else 
 			sl.Dash = Qt::SolidLine;
 
 		val = PyDict_GetItemString(line, "LineEnd");
 		if (val)
-			sl.LineEnd = PyInt_AsLong(val);
+			sl.LineEnd = PyLong_AsLong(val);
 		else 
 			sl.LineEnd = Qt::FlatCap;
 
 		val = PyDict_GetItemString(line, "LineJoin");
 		if (val)
-			sl.LineJoin = PyInt_AsLong(val);
+			sl.LineJoin = PyLong_AsLong(val);
 		else 
 			sl.LineJoin = Qt::MiterJoin;
 
 		val = PyDict_GetItemString(line, "Shade");
 		if (val)
-			sl.Shade = PyInt_AsLong(val);
+			sl.Shade = PyLong_AsLong(val);
 		else 
 			sl.Shade = currentDoc->itemToolPrefs().lineColorShade;
 
@@ -380,7 +380,7 @@
 
 		val = PyDict_GetItemString(line, "Shortcut");
 		if (val)
-			ml.shortcut = PyString_AsString(val);
+			ml.shortcut = PyUnicode_asQString(val);
 		else 
 			ml.shortcut = "";
 
Index: scribus/plugins/scriptplugin/cmdtable.cpp
===================================================================
--- scribus/plugins/scriptplugin/cmdtable.cpp	(revision 23269)
+++ scribus/plugins/scriptplugin/cmdtable.cpp	(working copy)
@@ -28,7 +28,7 @@
 		PyErr_SetString(WrongFrameTypeError, QObject::tr("Cannot get table row count of non-table item.","python error").toLocal8Bit().constData());
 		return nullptr;
 	}
-	return PyInt_FromLong(static_cast<long>(table->rows()));
+	return PyLong_FromLong(static_cast<long>(table->rows()));
 }
 
 PyObject *scribus_gettablecolumns(PyObject* /* self */, PyObject* args)
@@ -48,7 +48,7 @@
 		PyErr_SetString(WrongFrameTypeError, QObject::tr("Cannot get table column count of non-table item.","python error").toLocal8Bit().constData());
 		return nullptr;
 	}
-	return PyInt_FromLong(static_cast<long>(table->columns()));
+	return PyLong_FromLong(static_cast<long>(table->columns()));
 }
 
 PyObject *scribus_inserttablerows(PyObject* /* self */, PyObject* args)
@@ -338,7 +338,7 @@
 		PyErr_SetString(WrongFrameTypeError, QObject::tr("Cannot get table style on a non-table item.","python error").toLocal8Bit().constData());
 		return nullptr;
 	}
-	return PyString_FromString(table->styleName().toUtf8());
+	return PyUnicode_FromString(table->styleName().toUtf8());
 }
 
 PyObject *scribus_settablestyle(PyObject* /* self */, PyObject* args)
@@ -378,7 +378,7 @@
 		PyErr_SetString(WrongFrameTypeError, QObject::tr("Cannot get table fill color on a non-table item.","python error").toLocal8Bit().constData());
 		return nullptr;
 	}
-	return PyString_FromString(table->fillColor().toUtf8());
+	return PyUnicode_FromString(table->fillColor().toUtf8());
 }
 
 PyObject *scribus_settablefillcolor(PyObject* /* self */, PyObject* args)
Index: scribus/plugins/scriptplugin/cmdtext.cpp
===================================================================
--- scribus/plugins/scriptplugin/cmdtext.cpp	(revision 23269)
+++ scribus/plugins/scriptplugin/cmdtext.cpp	(working copy)
@@ -92,10 +92,10 @@
 	{
 		for (int i = 0; i < item->itemText.length(); i++)
 			if (item->itemText.selected(i))
-				return PyString_FromString(item->itemText.charStyle(i).font().scName().toUtf8());
+				return PyUnicode_FromString(item->itemText.charStyle(i).font().scName().toUtf8());
 		return nullptr;
 	}
-	return PyString_FromString(item->currentCharStyle().font().scName().toUtf8());
+	return PyUnicode_FromString(item->currentCharStyle().font().scName().toUtf8());
 }
 
 PyObject *scribus_gettextcolor(PyObject* /* self */, PyObject* args)
@@ -118,11 +118,11 @@
 		for (int i = 0; i < item->itemText.length(); ++i)
 		{
 			if (item->itemText.selected(i))
-				return PyString_FromString(item->itemText.charStyle(i).fillColor().toUtf8());
+				return PyUnicode_FromString(item->itemText.charStyle(i).fillColor().toUtf8());
 		}
         return nullptr;
 	}
-    return PyString_FromString(item->currentCharStyle().fillColor().toUtf8());
+    return PyUnicode_FromString(item->currentCharStyle().fillColor().toUtf8());
 }
 
 PyObject *scribus_gettextshade(PyObject* /* self */, PyObject* args)
@@ -145,11 +145,11 @@
 		for (int i = 0; i < item->itemText.length(); ++i)
 		{
 			if (item->itemText.selected(i))
-				return PyInt_FromLong(item->itemText.charStyle(i).fillShade());
+				return PyLong_FromLong(item->itemText.charStyle(i).fillShade());
 		}
 		return nullptr;
 	}
-	return PyInt_FromLong(item->currentCharStyle().fillShade());
+	return PyLong_FromLong(item->currentCharStyle().fillShade());
 }
 
 PyObject *scribus_gettextsize(PyObject* /* self */, PyObject* args)
@@ -167,7 +167,7 @@
 		PyErr_SetString(WrongFrameTypeError, QObject::tr("Cannot get text size of non-text frame.","python error").toLocal8Bit().constData());
 		return nullptr;
 	}
-	return PyInt_FromLong(static_cast<long>(item->itemText.length()));
+	return PyLong_FromLong(static_cast<long>(item->itemText.length()));
 }
 
 PyObject *scribus_gettextlines(PyObject* /* self */, PyObject* args)
@@ -185,7 +185,7 @@
 		PyErr_SetString(WrongFrameTypeError, QObject::tr("Cannot get number of lines of non-text frame.","python error").toLocal8Bit().constData());
 		return nullptr;
 	}
-	return PyInt_FromLong(static_cast<long>(item->textLayout.lines()));
+	return PyLong_FromLong(static_cast<long>(item->textLayout.lines()));
 }
 
 PyObject *scribus_gettextverticalalignment(PyObject* /* self */, PyObject* args)
@@ -203,7 +203,7 @@
 		PyErr_SetString(WrongFrameTypeError, QObject::tr("Cannot get vertical alignment of non-text frame.", "python error").toLocal8Bit().constData());
 		return nullptr;
 	}
-	return PyInt_FromLong(static_cast<long>(item->verticalAlignment()));
+	return PyLong_FromLong(static_cast<long>(item->verticalAlignment()));
 }
 
 PyObject *scribus_getcolumns(PyObject* /* self */, PyObject* args)
@@ -221,7 +221,7 @@
 		PyErr_SetString(WrongFrameTypeError, QObject::tr("Cannot get column count of non-text frame.","python error").toLocal8Bit().constData());
 		return nullptr;
 	}
-	return PyInt_FromLong(static_cast<long>(item->m_columns));
+	return PyLong_FromLong(static_cast<long>(item->m_columns));
 }
 
 PyObject *scribus_getcolumngap(PyObject* /* self */, PyObject* args)
@@ -261,10 +261,10 @@
 	{
 		for (int i = 0; i < item->itemText.length(); i++)
 			if (item->itemText.selected(i))
-				return PyString_FromString(item->itemText.charStyle(i).fontFeatures().toUtf8());
+				return PyUnicode_FromString(item->itemText.charStyle(i).fontFeatures().toUtf8());
 		return nullptr;
 	}
-	return PyString_FromString(item->currentCharStyle().fontFeatures().toUtf8());
+	return PyUnicode_FromString(item->currentCharStyle().fontFeatures().toUtf8());
 }
 
 PyObject *scribus_getlinespace(PyObject* /* self */, PyObject* args)
@@ -335,7 +335,7 @@
 			text += item->itemText.text(i);
 		}
 	}
-	return PyString_FromString(text.toUtf8());
+	return PyUnicode_FromString(text.toUtf8());
 }
 
 PyObject *scribus_gettext(PyObject* /* self */, PyObject* args)
@@ -368,7 +368,7 @@
 			text += item->itemText.text(i);
 		}
 	} // for
-	return PyString_FromString(text.toUtf8());
+	return PyUnicode_FromString(text.toUtf8());
 }
 
 PyObject *scribus_setboxtext(PyObject* /* self */, PyObject* args)
@@ -1235,17 +1235,17 @@
 	}
 	// no overrun
 	if (nolinks)
-		return PyInt_FromLong(maxchars - firstFrame);
+		return PyLong_FromLong(maxchars - firstFrame);
 
 	if (maxchars > chars)
-		return PyInt_FromLong(0);
+		return PyLong_FromLong(0);
 	// number of overrunning letters
-	return PyInt_FromLong(static_cast<long>(chars - maxchars));
+	return PyLong_FromLong(static_cast<long>(chars - maxchars));
 	 */
 	// refresh overflow information
 	item->invalidateLayout();
 	item->layout();
-	return PyInt_FromLong(static_cast<long>(item->frameOverflows()));
+	return PyLong_FromLong(static_cast<long>(item->frameOverflows()));
 }
 
 /*
Index: scribus/plugins/scriptplugin/cmdutil.cpp
===================================================================
--- scribus/plugins/scriptplugin/cmdutil.cpp	(revision 23269)
+++ scribus/plugins/scriptplugin/cmdutil.cpp	(working copy)
@@ -241,3 +241,11 @@
 	return border;
 }
 
+QString PyUnicode_asQString(PyObject* arg)
+{
+	const char* utf8Str = PyUnicode_AsUTF8(arg);
+	if (!utf8Str)
+		return QString();
+	return QString::fromUtf8(utf8Str);
+}
+
Index: scribus/plugins/scriptplugin/cmdutil.h
===================================================================
--- scribus/plugins/scriptplugin/cmdutil.h	(revision 23269)
+++ scribus/plugins/scriptplugin/cmdutil.h	(working copy)
@@ -29,6 +29,7 @@
 
 PageItem *GetItem(const QString& Name);
 void ReplaceColor(const QString& col, const QString& rep);
+
 /*!
  * @brief Returns named PageItem, or selection if name '', or exception and NULL if no item.
  *
@@ -60,6 +61,7 @@
  * @brief Returns a list of the names of all selected PageItems
  */
 QStringList getSelectedItemsByName();
+
 /*!
  * @brief Replaces the current selection by selecting all the items named in the passed QStringList
  *
@@ -68,8 +70,14 @@
  */
 bool setSelectedItemsByName(QStringList& itemNames);
 
-/// Helper method to parse a border from a list of tuples.
+/*!
+ * @brief Helper method to parse a border from a list of tuples.
+ */
 TableBorder parseBorder(PyObject* borderLines, bool* ok);
 
+/*!
+ * @brief Helper method to convert a PyUnicode object to a QString
+ */
+QString PyUnicode_asQString(PyObject* arg);
 
 #endif
Index: scribus/plugins/scriptplugin/cmdvar.h
===================================================================
--- scribus/plugins/scriptplugin/cmdvar.h	(revision 23269)
+++ scribus/plugins/scriptplugin/cmdvar.h	(working copy)
@@ -18,6 +18,11 @@
 	#undef _POSIX_C_SOURCE
 #endif
 
+#if defined(_MSC_VER)
+#pragma push_macro("slots")
+#undef slots
+#endif
+
 #if defined(HAVE_BOOST_PYTHON)
 #include <boost/python.hpp>
 #else
@@ -24,6 +29,10 @@
 #include <Python.h>
 #endif
 
+#if defined(_MSC_VER)
+#pragma pop_macro("slots")
+#endif
+
 #ifndef Py_RETURN_NONE
 	#define Py_RETURN_NONE return Py_INCREF(Py_None), Py_None
 #endif
@@ -52,6 +61,8 @@
 /** @brief Initialize the 'scribus' Python module in the currently active interpreter */
 extern "C" void initscribus(ScribusMainWindow *pl);
 
+extern "C" PyObject* PyInit_scribus(void);
+
 /* Exceptions */
 /*! Common scribus Exception */
 extern PyObject* ScribusException;
Index: scribus/plugins/scriptplugin/objimageexport.cpp
===================================================================
--- scribus/plugins/scriptplugin/objimageexport.cpp	(revision 23269)
+++ scribus/plugins/scriptplugin/objimageexport.cpp	(working copy)
@@ -34,7 +34,7 @@
 	Py_XDECREF(self->name);
 	Py_XDECREF(self->type);
 	Py_XDECREF(self->allTypes);
-	self->ob_type->tp_free((PyObject *)self);
+	Py_TYPE(self)->tp_free((PyObject *)self);
 }
 
 static PyObject * ImageExport_new(PyTypeObject *type, PyObject * /*args*/, PyObject * /*kwds*/)
@@ -45,8 +45,8 @@
 	ImageExport *self;
 	self = (ImageExport *)type->tp_alloc(type, 0);
 	if (self != nullptr) {
-		self->name = PyString_FromString("ImageExport.png");
-		self->type = PyString_FromString("PNG");
+		self->name = PyUnicode_FromString("ImageExport.png");
+		self->type = PyUnicode_FromString("PNG");
 		self->allTypes = PyList_New(0);
 		self->dpi = 72;
 		self->scale = 100;
@@ -77,11 +77,11 @@
 
 static int ImageExport_setName(ImageExport *self, PyObject *value, void * /*closure*/)
 {
-	if (!PyString_Check(value)) {
+	if (!PyUnicode_Check(value)) {
 		PyErr_SetString(PyExc_TypeError, QObject::tr("The filename must be a string.", "python error").toLocal8Bit().constData());
 		return -1;
 	}
-	if (PyString_Size(value) < 1)
+	if (PyUnicode_GET_LENGTH(value) < 1)
 	{
 		PyErr_SetString(PyExc_TypeError, QObject::tr("The filename should not be empty string.", "python error").toLocal8Bit().constData());
 		return -1;
@@ -104,7 +104,7 @@
 		PyErr_SetString(PyExc_TypeError, QObject::tr("Cannot delete image type settings.", "python error").toLocal8Bit().constData());
 		return -1;
 	}
-	if (!PyString_Check(value)) {
+	if (!PyUnicode_Check(value)) {
 		PyErr_SetString(PyExc_TypeError, QObject::tr("The image type must be a string.", "python error").toLocal8Bit().constData());
 		return -1;
 	}
@@ -122,7 +122,7 @@
 	l = PyList_New(list.count());
 	for (QList<QByteArray>::Iterator it = list.begin(); it != list.end(); ++it)
 	{
-		PyList_SetItem(l, pos, PyString_FromString(QString((*it)).toLatin1().constData()));
+		PyList_SetItem(l, pos, PyUnicode_FromString(QString((*it)).toLatin1().constData()));
 		++pos;
 	}
 	return l;
@@ -160,7 +160,9 @@
 	int dpi = qRound(100.0 / 2.54 * self->dpi);
 	im.setDotsPerMeterY(dpi);
 	im.setDotsPerMeterX(dpi);
-	if (!im.save(PyString_AsString(self->name), PyString_AsString(self->type)))
+
+	QString imgFileName = PyUnicode_asQString(self->name);
+	if (!im.save(imgFileName, PyUnicode_AsUTF8(self->type)))
 	{
 		PyErr_SetString(ScribusException, QObject::tr("Failed to export image", "python error").toLocal8Bit().constData());
 		return nullptr;
@@ -194,7 +196,9 @@
 	int dpi = qRound(100.0 / 2.54 * self->dpi);
 	im.setDotsPerMeterY(dpi);
 	im.setDotsPerMeterX(dpi);
-	if (!im.save(value, PyString_AsString(self->type)))
+
+	QString outputFileName = QString::fromUtf8(value);
+	if (!im.save(outputFileName, PyUnicode_AsUTF8(self->type)))
 	{
 		PyErr_SetString(ScribusException, QObject::tr("Failed to export image", "python error").toLocal8Bit().constData());
 		return nullptr;
@@ -212,8 +216,7 @@
 };
 
 PyTypeObject ImageExport_Type = {
-	PyObject_HEAD_INIT(nullptr)   // PyObject_VAR_HEAD
-	0,
+	PyVarObject_HEAD_INIT(nullptr, 0)   // PyObject_VAR_HEAD
 	const_cast<char*>("scribus.ImageExport"), // char *tp_name; /* For printing, in format "<module>.<name>" */
 	sizeof(ImageExport),   // int tp_basicsize, /* For allocation */
 	0,  // int tp_itemsize; /* For allocation */
@@ -259,6 +262,8 @@
 	nullptr, //	 PyObject *tp_subclasses;
 	nullptr, //	 PyObject *tp_weaklist;
 	nullptr, //	 destructor tp_del;
+	0, //	 unsigned int tp_version_tag;
+	0, //	 destructor tp_finalize;
 
 #ifdef COUNT_ALLOCS
 	/* these must be last and never explicitly initialized */
Index: scribus/plugins/scriptplugin/objpdffile.cpp
===================================================================
--- scribus/plugins/scriptplugin/objpdffile.cpp	(revision 23269)
+++ scribus/plugins/scriptplugin/objpdffile.cpp	(working copy)
@@ -135,7 +135,7 @@
 	Py_XDECREF(self->info);
 	Py_XDECREF(self->rotateDeg);
 	Py_XDECREF(self->openAction);
-	self->ob_type->tp_free((PyObject *)self);
+	Py_TYPE(self)->tp_free((PyObject *)self);
 }
 
 static PyObject * PDFfile_new(PyTypeObject *type, PyObject * /*args*/, PyObject * /*kwds*/)
@@ -150,13 +150,13 @@
 	self = (PDFfile *)type->tp_alloc(type, 0);
 	if (self) {
 // set file attribute
-		self->file = PyString_FromString("");
+		self->file = PyUnicode_FromString("");
 		if (!self->file) {
 			Py_DECREF(self);
 			return nullptr;
 		}
 // set font embedding mode attribute
-		self->fontEmbedding = PyInt_FromLong(0);
+		self->fontEmbedding = PyLong_FromLong(0);
 		if (!self->fontEmbedding) {
 			Py_DECREF(self);
 			return nullptr;
@@ -201,13 +201,13 @@
 // set quality attribute
 		self->quality = 0;
 // set resolution attribute
-		self->resolution = PyInt_FromLong(300);
+		self->resolution = PyLong_FromLong(300);
 		if (!self->resolution){
 			Py_DECREF(self);
 			return nullptr;
 		}
 // set downsample attribute
-		self->downsample = PyInt_FromLong(0);
+		self->downsample = PyLong_FromLong(0);
 		if (!self->downsample){
 			Py_DECREF(self);
 			return nullptr;
@@ -239,13 +239,13 @@
 			return nullptr;
 		}
 // set owner attribute
-		self->owner = PyString_FromString("");
+		self->owner = PyUnicode_FromString("");
 		if (!self->owner){
 			Py_DECREF(self);
 			return nullptr;
 		}
 // set user attribute
-		self->user = PyString_FromString("");
+		self->user = PyUnicode_FromString("");
 		if (!self->user){
 			Py_DECREF(self);
 			return nullptr;
@@ -269,22 +269,22 @@
 		self->intents = 0; // int - 0 - ?
 		self->intenti = 0; // int - 0 - ?
 		self->noembicc = 0; // bool
-		self->solidpr = PyString_FromString("");
+		self->solidpr = PyUnicode_FromString("");
 		if (!self->solidpr){
 			Py_DECREF(self);
 			return nullptr;
 		}
-		self->imagepr = PyString_FromString("");
+		self->imagepr = PyUnicode_FromString("");
 		if (!self->imagepr){
 			Py_DECREF(self);
 			return nullptr;
 		}
-		self->printprofc = PyString_FromString("");
+		self->printprofc = PyUnicode_FromString("");
 		if (!self->printprofc){
 			Py_DECREF(self);
 			return nullptr;
 		}
-		self->info = PyString_FromString("");
+		self->info = PyUnicode_FromString("");
 		if (!self->info){
 			Py_DECREF(self);
 			return nullptr;
@@ -299,7 +299,7 @@
 		self->mirrorH = 0;
 		self->mirrorV = 0;
 		self->doClip = 0;
-		self->rotateDeg = PyInt_FromLong(0);
+		self->rotateDeg = PyLong_FromLong(0);
 		if (!self->rotateDeg){
 			Py_DECREF(self);
 			return nullptr;
@@ -313,7 +313,7 @@
 		self->hideToolBar = 0;
 		self->hideMenuBar = 0;
 		self->fitWindow = 0;
-		self->openAction = PyString_FromString("");
+		self->openAction = PyUnicode_FromString("");
 		if (!self->openAction){
 			Py_DECREF(self);
 			return nullptr;
@@ -336,10 +336,10 @@
 	QString tf = pdfOptions.fileName;
 	if (tf.isEmpty()) {
 		QFileInfo fi = QFileInfo(currentDoc->documentFileName());
-		tf = fi.path()+"/"+fi.baseName()+".pdf";
+		tf = fi.path() + "/" + fi.baseName() + ".pdf";
 	}
 	PyObject *file = nullptr;
-	file = PyString_FromString(tf.toLatin1());
+	file = PyUnicode_FromString(tf.toUtf8());
 	if (file){
 		Py_DECREF(self->file);
 		self->file = file;
@@ -349,7 +349,7 @@
 	}
 // font embedding mode
 	PyObject *embeddingMode = nullptr;
-	embeddingMode = PyInt_FromLong(pdfOptions.FontEmbedding);
+	embeddingMode = PyLong_FromLong(pdfOptions.FontEmbedding);
 	if (embeddingMode){
 		Py_DECREF(self->fontEmbedding);
 		self->fontEmbedding = embeddingMode;
@@ -375,7 +375,7 @@
 	{
 		const QString& fontName = tmpEm.at(i);
 		PyObject *tmp= nullptr;
-		tmp = PyString_FromString(fontName.toLatin1());
+		tmp = PyUnicode_FromString(fontName.toUtf8());
 		if (tmp) {
 			PyList_Append(self->fonts, tmp);
 // do i need Py_DECREF(tmp) here?
@@ -401,7 +401,7 @@
 	for (int fe = 0; fe < pdfOptions.SubsetList.count(); ++fe)
 	{
 		PyObject *tmp= nullptr;
-		tmp = PyString_FromString(pdfOptions.SubsetList[fe].toLatin1().data());
+		tmp = PyUnicode_FromString(pdfOptions.SubsetList[fe].toUtf8().data());
 		if (tmp) {
 			PyList_Append(self->subsetList, tmp);
 			Py_DECREF(tmp);
@@ -425,7 +425,7 @@
 	}
 	for (i = 0; i<num; ++i) {
 		PyObject *tmp;
-		tmp = PyInt_FromLong((long)i+1L);
+		tmp = PyLong_FromLong((long)i+1L);
 		if (tmp)
 			PyList_SetItem(pages, i, tmp);
 		else {
@@ -458,7 +458,7 @@
 	self->quality = pdfOptions.Quality;
 // default resolution
 	PyObject *resolution = nullptr;
-	resolution = PyInt_FromLong(300);
+	resolution = PyLong_FromLong(300);
 	if (resolution){
 		Py_DECREF(self->resolution);
 		self->resolution = resolution;
@@ -469,7 +469,7 @@
 // do not downsample images
 	int down = pdfOptions.RecalcPic ? pdfOptions.PicRes : 0;
 	PyObject *downsample = nullptr;
-	downsample = PyInt_FromLong(down);
+	downsample = PyLong_FromLong(down);
 	if (downsample){
 		Py_DECREF(self->downsample);
 		self->downsample = downsample;
@@ -549,7 +549,7 @@
 	self->lpival = lpival;
 // set owner's password
 	PyObject *owner = nullptr;
-	owner = PyString_FromString(pdfOptions.PassOwner.toLatin1());
+	owner = PyUnicode_FromString(pdfOptions.PassOwner.toUtf8());
 	if (owner){
 		Py_DECREF(self->owner);
 		self->owner = owner;
@@ -559,7 +559,7 @@
 	}
 // set user'a password
 	PyObject *user = nullptr;
-	user = PyString_FromString(pdfOptions.PassUser.toLatin1());
+	user = PyUnicode_FromString(pdfOptions.PassUser.toUtf8());
 	if (user){
 		Py_DECREF(self->user);
 		self->user = user;
@@ -589,7 +589,7 @@
 	if (!ScCore->InputProfiles.contains(tp))
 		tp = currentDoc->cmsSettings().DefaultSolidColorRGBProfile;
 	PyObject *solidpr = nullptr;
-	solidpr = PyString_FromString(tp.toLatin1());
+	solidpr = PyUnicode_FromString(tp.toUtf8());
 	if (solidpr){
 		Py_DECREF(self->solidpr);
 		self->solidpr = solidpr;
@@ -601,7 +601,7 @@
 	if (!ScCore->InputProfiles.contains(tp2))
 		tp2 = currentDoc->cmsSettings().DefaultSolidColorRGBProfile;
 	PyObject *imagepr = nullptr;
-	imagepr = PyString_FromString(tp2.toLatin1());
+	imagepr = PyUnicode_FromString(tp2.toUtf8());
 	if (imagepr){
 		Py_DECREF(self->imagepr);
 		self->imagepr = imagepr;
@@ -613,7 +613,7 @@
 	if (!ScCore->PDFXProfiles.contains(tp3))
 		tp3 = currentDoc->cmsSettings().DefaultPrinterProfile;
 	PyObject *printprofc = nullptr;
-	printprofc = PyString_FromString(tp3.toLatin1());
+	printprofc = PyUnicode_FromString(tp3.toUtf8());
 	if (printprofc){
 		Py_DECREF(self->printprofc);
 		self->printprofc = printprofc;
@@ -623,7 +623,7 @@
 	}
 	QString tinfo = pdfOptions.Info;
 	PyObject *info = nullptr;
-	info = PyString_FromString(tinfo.toLatin1());
+	info = PyUnicode_FromString(tinfo.toUtf8());
 	if (info){
 		Py_DECREF(self->info);
 		self->info = info;
@@ -642,7 +642,7 @@
 	self->mirrorV = pdfOptions.MirrorV; // bool
 	self->doClip = pdfOptions.doClip; // bool
 	PyObject *rotateDeg = nullptr;
-	rotateDeg = PyInt_FromLong(0);
+	rotateDeg = PyLong_FromLong(0);
 	if (rotateDeg){
 		Py_DECREF(self->rotateDeg);
 		self->rotateDeg = rotateDeg;
@@ -661,7 +661,7 @@
 	self->fitWindow = pdfOptions.fitWindow; // bool
 
 	PyObject *openAction = nullptr;
-	openAction = PyString_FromString(pdfOptions.openAction.toLatin1().data());
+	openAction = PyUnicode_FromString(pdfOptions.openAction.toUtf8().data());
 	if (openAction){
 		Py_DECREF(self->openAction);
 		self->openAction = openAction;
@@ -751,7 +751,7 @@
 		PyErr_SetString(PyExc_TypeError, "Cannot delete 'file' attribute.");
 		return -1;
 	}
-	if (!PyString_Check(value)) {
+	if (!PyUnicode_Check(value)) {
 		PyErr_SetString(PyExc_TypeError, "The 'file' attribute value must be string.");
 		return -1;
 	}
@@ -773,11 +773,11 @@
 		PyErr_SetString(PyExc_TypeError, "Cannot delete 'fontEmbedding' attribute.");
 		return -1;
 	}
-	if (!PyInt_Check(value)) {
+	if (!PyLong_Check(value)) {
 		PyErr_SetString(PyExc_TypeError, "'fontEmbedding' attribute value must be integer.");
 		return -1;
 	}
-	int n = PyInt_AsLong(value);
+	int n = PyLong_AsLong(value);
 	if (n < 0 || n > 2) {
 		PyErr_SetString(PyExc_ValueError, "'fontEmbedding' value must be an integer between 0 and 2");
 		return -1;
@@ -807,7 +807,7 @@
 	int n;
 	n = PyList_Size(value);
 	for (int i=0; i<n; ++i)
-		if (!PyString_Check(PyList_GetItem(value, i))) {
+		if (!PyUnicode_Check(PyList_GetItem(value, i))) {
 			PyErr_SetString(PyExc_TypeError, "The 'fonts' list must contain only strings.");
 			return -1;
 		}
@@ -840,7 +840,7 @@
 	int n;
 	n = PyList_Size(value);
 	for (int i=0; i<n; ++i)
-		if (!PyString_Check(PyList_GetItem(value, i))) {
+		if (!PyUnicode_Check(PyList_GetItem(value, i))) {
 			PyErr_SetString(PyExc_TypeError, "The 'subsetList' list must contain only strings.");
 			return -1;
 		}
@@ -873,11 +873,11 @@
 		// I did not check if tmp is nullptr
 		// how can PyList_GetItem fail in this case (my guess: short of available memory?)
 		// Also do I need Py_INCREF or Py_DECREF here?
-		if (!PyInt_Check(tmp)){
+		if (!PyLong_Check(tmp)){
 			PyErr_SetString(PyExc_TypeError, "'pages' list must contain only integers.");
 			return -1;
 		}
-		if (PyInt_AsLong(tmp) > static_cast<int>(ScCore->primaryMainWindow()->doc->Pages->count()) || PyInt_AsLong(tmp) < 1) {
+		if (PyLong_AsLong(tmp) > static_cast<int>(ScCore->primaryMainWindow()->doc->Pages->count()) || PyLong_AsLong(tmp) < 1) {
 			PyErr_SetString(PyExc_ValueError, "'pages' value out of range.");
 			return -1;
 		}
@@ -901,11 +901,11 @@
 		PyErr_SetString(PyExc_TypeError, "Cannot delete 'resolution' attribute.");
 		return -1;
 	}
-	if (!PyInt_Check(value)) {
+	if (!PyLong_Check(value)) {
 		PyErr_SetString(PyExc_TypeError, "'resolution' attribute value must be integer.");
 		return -1;
 	}
-	int n = PyInt_AsLong(value);
+	int n = PyLong_AsLong(value);
 	if (n<35 || n>4000) {
 		PyErr_SetString(PyExc_ValueError, "'resolution' value must be in interval from 35 to 4000");
 		return -1;
@@ -928,12 +928,12 @@
 		PyErr_SetString(PyExc_TypeError, "Cannot delete 'downsample' attribute.");
 		return -1;
 	}
-	if (!PyInt_Check(value)) {
+	if (!PyLong_Check(value)) {
 		PyErr_SetString(PyExc_TypeError, "'downsample' attribute value must be integer.");
 		return -1;
 	}
-	int n = PyInt_AsLong(value);
-	if (n!=0 && (n<35 || n>PyInt_AsLong(self->resolution))) {
+	int n = PyLong_AsLong(value);
+	if (n!=0 && (n < 35 || n > PyLong_AsLong(self->resolution))) {
 		PyErr_SetString(PyExc_TypeError, "'downsample' value must be 0 or in interval from 35 to value of 'resolution'");
 		return -1;
 	}
@@ -972,7 +972,7 @@
 			return -1;
 		}
 		for ( --j; j > -1; --j) {
-			if (!PyInt_Check(PyList_GetItem(tmp, j))) {
+			if (!PyLong_Check(PyList_GetItem(tmp, j))) {
 				PyErr_SetString(PyExc_TypeError, "innermost element of 'effval' must be integers.");
 				return -1;
 			}
@@ -1005,21 +1005,21 @@
 	for (int i=0; i<n; ++i) {
 		PyObject *tmp = PyList_GetItem(value, i);
 		if (!PyList_Check(tmp)) {
-			PyErr_SetString(PyExc_TypeError, "elemets of 'lpival' must be list of five integers.");
+			PyErr_SetString(PyExc_TypeError, "elements of 'lpival' must be list of five integers.");
 			return -1;
 		}
 		int j = PyList_Size(tmp);
 		if (j != 4) {
-			PyErr_SetString(PyExc_TypeError, "elemets of 'lpival' must have exactly four members.");
+			PyErr_SetString(PyExc_TypeError, "elements of 'lpival' must have exactly four members.");
 			return -1;
 		}
 		for ( --j; j > 0; --j) {
-			if (!PyInt_Check(PyList_GetItem(tmp, j))) {
+			if (!PyLong_Check(PyList_GetItem(tmp, j))) {
 				PyErr_SetString(PyExc_TypeError, "'lpival'elements must have structure [siii]");
 				return -1;
 			}
 		}
-		if (!PyString_Check(PyList_GetItem(tmp, 0))) {
+		if (!PyUnicode_Check(PyList_GetItem(tmp, 0))) {
 			PyErr_SetString(PyExc_TypeError, "'lpival'elements must have structure [siii]");
 			return -1;
 		}
@@ -1042,7 +1042,7 @@
 		PyErr_SetString(PyExc_TypeError, "Cannot delete 'owner' attribute.");
 		return -1;
 	}
-	if (!PyString_Check(value)) {
+	if (!PyUnicode_Check(value)) {
 		PyErr_SetString(PyExc_TypeError, "'owner' attribute value must be string.");
 		return -1;
 	}
@@ -1064,7 +1064,7 @@
 		PyErr_SetString(PyExc_TypeError, "Cannot delete 'user' attribute.");
 		return -1;
 	}
-	if (!PyString_Check(value)) {
+	if (!PyUnicode_Check(value)) {
 		PyErr_SetString(PyExc_TypeError, "'user' attribute value must be string.");
 		return -1;
 	}
@@ -1086,7 +1086,7 @@
 		PyErr_SetString(PyExc_TypeError, "Cannot delete 'solidpr' attribute.");
 		return -1;
 	}
-	if (!PyString_Check(value)) {
+	if (!PyUnicode_Check(value)) {
 		PyErr_SetString(PyExc_TypeError, "The 'solidpr' attribute value must be string.");
 		return -1;
 	}
@@ -1108,7 +1108,7 @@
 		PyErr_SetString(PyExc_TypeError, "Cannot delete 'imagepr' attribute.");
 		return -1;
 	}
-	if (!PyString_Check(value)) {
+	if (!PyUnicode_Check(value)) {
 		PyErr_SetString(PyExc_TypeError, "The 'imagepr' attribute value must be string.");
 		return -1;
 	}
@@ -1130,7 +1130,7 @@
 		PyErr_SetString(PyExc_TypeError, "Cannot delete 'printprofc' attribute.");
 		return -1;
 	}
-	if (!PyString_Check(value)) {
+	if (!PyUnicode_Check(value)) {
 		PyErr_SetString(PyExc_TypeError, "The 'printprofc' attribute value must be string.");
 		return -1;
 	}
@@ -1152,7 +1152,7 @@
 		PyErr_SetString(PyExc_TypeError, "Cannot delete 'info' attribute.");
 		return -1;
 	}
-	if (!PyString_Check(value)) {
+	if (!PyUnicode_Check(value)) {
 		PyErr_SetString(PyExc_TypeError, "The 'info' attribute value must be string.");
 		return -1;
 	}
@@ -1174,11 +1174,11 @@
 		PyErr_SetString(PyExc_TypeError, "Cannot delete 'rotateDeg' attribute.");
 		return -1;
 	}
-	if (!PyInt_Check(value)) {
+	if (!PyLong_Check(value)) {
 		PyErr_SetString(PyExc_TypeError, "'rotateDeg' attribute value must be integer.");
 		return -1;
 	}
-	int n = PyInt_AsLong(value);
+	int n = PyLong_AsLong(value);
 	if (n!=0 && n!=90 && n!=180 && n!=270) {
 		PyErr_SetString(PyExc_TypeError, "'rotateDeg' value must be 0 or 90 or 180 or 270");
 		return -1;
@@ -1201,7 +1201,7 @@
 		PyErr_SetString(PyExc_TypeError, "Cannot delete 'openAction' attribute.");
 		return -1;
 	}
-	if (!PyString_Check(value)) {
+	if (!PyUnicode_Check(value)) {
 		PyErr_SetString(PyExc_TypeError, "'openAction' attribute value must be string.");
 		return -1;
 	}
@@ -1275,10 +1275,10 @@
 // apply fonts attribute
 	pdfOptions.EmbedList.clear();
 	int n = PyList_Size(self->fonts);
-	for ( int i=0; i<n; ++i)
+	for (int i = 0; i < n; ++i)
 	{
 		QString tmpFon;
-		tmpFon = QString(PyString_AsString(PyList_GetItem(self->fonts, i)));
+		tmpFon = PyUnicode_asQString(PyList_GetItem(self->fonts, i));
 		pdfOptions.EmbedList.append(tmpFon);
 	}
 // apply SubsetList attribute
@@ -1287,11 +1287,11 @@
 	for (int i = 0; i < n; ++i)
 	{
 		QString tmpFon;
-		tmpFon = QString(PyString_AsString(PyList_GetItem(self->subsetList, i)));
+		tmpFon = PyUnicode_asQString(PyList_GetItem(self->subsetList, i));
 		pdfOptions.SubsetList.append(tmpFon);
 	}
 // apply font embedding mode
-	pdfOptions.FontEmbedding = (PDFOptions::PDFFontEmbedding) PyInt_AsLong(self->fontEmbedding);
+	pdfOptions.FontEmbedding = (PDFOptions::PDFFontEmbedding) PyLong_AsLong(self->fontEmbedding);
 	if (pdfOptions.Version == PDFOptions::PDFVersion_X1a ||
 	    pdfOptions.Version == PDFOptions::PDFVersion_X3 ||
 	    pdfOptions.Version == PDFOptions::PDFVersion_X4)
@@ -1326,13 +1326,13 @@
 	}
 // apply file attribute
 	QString fn;
-	fn = QString(PyString_AsString(self->file));
+	fn = PyUnicode_asQString(self->file);
 	pdfOptions.fileName = fn;
 // apply pages attribute
 	std::vector<int> pageNs;
-	int nn=PyList_Size(self->pages);
+	int nn = PyList_Size(self->pages);
 	for (int i = 0; i < nn; ++i) {
-		pageNs.push_back((int)PyInt_AsLong(PyList_GetItem(self->pages, i)));
+		pageNs.push_back((int) PyLong_AsLong(PyList_GetItem(self->pages, i)));
 	}
 // apply thumbnails attribute
 	pdfOptions.Thumbnails = self->thumbnails;
@@ -1358,11 +1358,11 @@
 	self->quality = minmaxi(self->quality, 0, 4);
 	pdfOptions.Quality = self->quality;
 // apply resolusion attribute
-	pdfOptions.Resolution = PyInt_AsLong(self->resolution);
+	pdfOptions.Resolution = PyLong_AsLong(self->resolution);
 // apply downsample attribute
-	pdfOptions.RecalcPic = PyInt_AsLong(self->downsample);
+	pdfOptions.RecalcPic = PyLong_AsLong(self->downsample);
 	if (pdfOptions.RecalcPic)
-		pdfOptions.PicRes = PyInt_AsLong(self->downsample);
+		pdfOptions.PicRes = PyLong_AsLong(self->downsample);
 	else
 		pdfOptions.PicRes = pdfOptions.Resolution;
 // apply bookmarks attribute
@@ -1379,13 +1379,13 @@
 		PyObject *ti = PyList_GetItem(self->effval, i);
 		if (!ti)
 			continue;
-		// Do I Need to check if every PyInt_AsLong and PyList_GetItem funtion succeed???
-		t.pageEffectDuration = PyInt_AsLong(PyList_GetItem(ti, 0));
-		t.pageViewDuration = PyInt_AsLong(PyList_GetItem(ti, 1));
-		t.effectType = PyInt_AsLong(PyList_GetItem(ti, 2));
-		t.Dm = PyInt_AsLong(PyList_GetItem(ti, 3));
-		t.M = PyInt_AsLong(PyList_GetItem(ti, 4));
-		t.Di = PyInt_AsLong(PyList_GetItem(ti, 5));
+		// Do I Need to check if every PyLong_AsLong and PyList_GetItem funtion succeed???
+		t.pageEffectDuration = PyLong_AsLong(PyList_GetItem(ti, 0));
+		t.pageViewDuration = PyLong_AsLong(PyList_GetItem(ti, 1));
+		t.effectType = PyLong_AsLong(PyList_GetItem(ti, 2));
+		t.Dm = PyLong_AsLong(PyList_GetItem(ti, 3));
+		t.M = PyLong_AsLong(PyList_GetItem(ti, 4));
+		t.Di = PyLong_AsLong(PyList_GetItem(ti, 5));
 		//	PresentVals.append(t);
 	}
 
@@ -1404,11 +1404,10 @@
 //			return nullptr;
 //		}
 //		pdfOptions.LPISettings[QString(s)]=lpi;
-		QString st;
-		st = QString(PyString_AsString(PyList_GetItem(t,0)));
-		lpi.Frequency = PyInt_AsLong(PyList_GetItem(t, 1));
-		lpi.Angle = PyInt_AsLong(PyList_GetItem(t, 2));
-		lpi.SpotFunc = PyInt_AsLong(PyList_GetItem(t, 3));
+		QString st = PyUnicode_asQString(PyList_GetItem(t, 0));
+		lpi.Frequency = PyLong_AsLong(PyList_GetItem(t, 1));
+		lpi.Angle = PyLong_AsLong(PyList_GetItem(t, 2));
+		lpi.SpotFunc = PyLong_AsLong(PyList_GetItem(t, 3));
 		pdfOptions.LPISettings[st] = lpi;
 	}
 
@@ -1432,8 +1431,8 @@
 		if (self->allowAnnots)
 			Perm += 32;
 		pdfOptions.Permissions = Perm;
-		pdfOptions.PassOwner = QString(PyString_AsString(self->owner));
-		pdfOptions.PassUser = QString(PyString_AsString(self->user));
+		pdfOptions.PassOwner = PyUnicode_asQString(self->owner);
+		pdfOptions.PassUser = PyUnicode_asQString(self->user);
 	}
 	if (self->outdst == 0)
 	{
@@ -1453,9 +1452,9 @@
 			self->intenti = minmaxi(self->intenti, 0, 3);
 			pdfOptions.Intent2 = self->intenti;
 			pdfOptions.EmbeddedI = self->noembicc;
-			pdfOptions.SolidProf = PyString_AsString(self->solidpr);
-			pdfOptions.ImageProf = PyString_AsString(self->imagepr);
-			pdfOptions.PrintProf = PyString_AsString(self->printprofc);
+			pdfOptions.SolidProf = PyUnicode_asQString(self->solidpr);
+			pdfOptions.ImageProf = PyUnicode_asQString(self->imagepr);
+			pdfOptions.PrintProf = PyUnicode_asQString(self->printprofc);
 			if (pdfOptions.Version == PDFOptions::PDFVersion_X1a ||
 				pdfOptions.Version == PDFOptions::PDFVersion_X3 ||
 				pdfOptions.Version == PDFOptions::PDFVersion_X4)
@@ -1469,7 +1468,7 @@
 					Components = 4;
 				if (profile.colorSpace() == ColorSpace_Cmy)
 					Components = 3;
-				pdfOptions.Info = PyString_AsString(self->info);
+				pdfOptions.Info = PyUnicode_asQString(self->info);
 				pdfOptions.Encrypt = false;
 				pdfOptions.PresentMode = false;
 			}
@@ -1512,7 +1511,7 @@
 	pdfOptions.MirrorH = self->mirrorH;
 	pdfOptions.MirrorV = self->mirrorV;
 	pdfOptions.doClip = self->doClip;
-	pdfOptions.RotateDeg = PyInt_AsLong(self->rotateDeg);
+	pdfOptions.RotateDeg = PyLong_AsLong(self->rotateDeg);
 	pdfOptions.isGrayscale = self->isGrayscale;
 	pdfOptions.PageLayout = minmaxi(self->pageLayout, 0, 3);
 	pdfOptions.displayBookmarks = self->displayBookmarks;
@@ -1522,7 +1521,7 @@
 	pdfOptions.hideToolBar = self->hideToolBar;
 	pdfOptions.hideMenuBar = self->hideMenuBar;
 	pdfOptions.fitWindow = self->fitWindow;
-	pdfOptions.openAction = QString(PyString_AsString(self->openAction));
+	pdfOptions.openAction = PyUnicode_asQString(self->openAction);
 	pdfOptions.firstUse = false;
 
 	QString errorMessage;
@@ -1548,8 +1547,7 @@
 };
 
 PyTypeObject PDFfile_Type = {
-	PyObject_HEAD_INIT(nullptr) // PyObject_VAR_HEAD
-	0,		      //
+	PyVarObject_HEAD_INIT(nullptr, 0) // PyObject_VAR_HEAD	      //
 	const_cast<char*>("scribus.PDFfile"), // char *tp_name; /* For printing, in format "<module>.<name>" */
 	sizeof(PDFfile),     // int tp_basicsize, /* For allocation */
 	0,		    // int tp_itemsize; /* For allocation */
@@ -1624,6 +1622,8 @@
 	nullptr, //     PyObject *tp_subclasses;
 	nullptr, //     PyObject *tp_weaklist;
 	nullptr, //     destructor tp_del;
+	0, //	 unsigned int tp_version_tag;
+	0, //	 destructor tp_finalize;
 
 #ifdef COUNT_ALLOCS
 	/* these must be last and never explicitly initialized */
Index: scribus/plugins/scriptplugin/objprinter.cpp
===================================================================
--- scribus/plugins/scriptplugin/objprinter.cpp	(revision 23269)
+++ scribus/plugins/scriptplugin/objprinter.cpp	(working copy)
@@ -59,7 +59,7 @@
 	Py_XDECREF(self->cmd);
 	Py_XDECREF(self->pages);
 	Py_XDECREF(self->separation);
-	self->ob_type->tp_free((PyObject *)self);
+	Py_TYPE(self)->tp_free((PyObject *)self);
 }
 
 static PyObject * Printer_new(PyTypeObject *type, PyObject * /*args*/, PyObject * /*kwds*/)
@@ -78,19 +78,19 @@
 			return nullptr;
 		}
 // set printer attribute
-		self->printer = PyString_FromString("");
+		self->printer = PyUnicode_FromString("");
 		if (self->printer == nullptr){
 			Py_DECREF(self);
 			return nullptr;
 		}
 // set file attribute
-		self->file = PyString_FromString("");
+		self->file = PyUnicode_FromString("");
 		if (self->file == nullptr){
 			Py_DECREF(self);
 			return nullptr;
 		}
 // set cmd attribute
-		self->cmd = PyString_FromString("");
+		self->cmd = PyUnicode_FromString("");
 		if (self->cmd == nullptr){
 			Py_DECREF(self);
 			return nullptr;
@@ -102,7 +102,7 @@
 			return nullptr;
 		}
 // set separation attribute
-		self->separation = PyString_FromString("No");
+		self->separation = PyUnicode_FromString("No");
 		if (self->separation == nullptr){
 			Py_DECREF(self);
 			return nullptr;
@@ -143,18 +143,18 @@
 		QString prn = printers[i];
 		if (prn.isEmpty())
 			continue;
-		PyObject *tmppr = PyString_FromString(prn.toLocal8Bit().constData());
+		PyObject *tmppr = PyUnicode_FromString(prn.toUtf8().constData());
 		if (tmppr){
 			PyList_Append(self->allPrinters, tmppr);
 			Py_DECREF(tmppr);
 		}
 	}
-	PyObject *tmp2 = PyString_FromString("File");
+	PyObject *tmp2 = PyUnicode_FromString("File");
 	PyList_Append(self->allPrinters, tmp2);
 	Py_DECREF(tmp2);
 // as defaut set to print into file
 	PyObject *printer = nullptr;
-	printer = PyString_FromString("File");
+	printer = PyUnicode_FromString("File");
 	if (printer){
 		Py_DECREF(self->printer);
 		self->printer = printer;
@@ -166,7 +166,7 @@
 		tf = fi.path()+"/"+fi.baseName()+".pdf";
 	}
 	PyObject *file = nullptr;
-	file = PyString_FromString(tf.toLatin1());
+	file = PyUnicode_FromString(tf.toUtf8());
 	if (file){
 		Py_DECREF(self->file);
 		self->file = file;
@@ -176,7 +176,7 @@
 	}
 // alternative printer commands default to ""
 	PyObject *cmd = nullptr;
-	cmd = PyString_FromString("");
+	cmd = PyUnicode_FromString("");
 	if (cmd){
 		Py_DECREF(self->cmd);
 		self->cmd = cmd;
@@ -192,13 +192,13 @@
 	}
 	for (int i = 0; i<num; i++) {
 		PyObject *tmp=nullptr;
-		tmp = PyInt_FromLong((long)i+1L); // instead of 1 put here first page number
+		tmp = PyLong_FromLong((long)i+1L); // instead of 1 put here first page number
 		if (tmp)
 			PyList_SetItem(self->pages, i, tmp);
 	}
 // do not print separation
 	PyObject *separation = nullptr;
-	separation = PyString_FromString("No");
+	separation = PyUnicode_FromString("No");
 	if (separation){
 		Py_DECREF(self->separation);
 		self->separation = separation;
@@ -257,7 +257,7 @@
 		PyErr_SetString(PyExc_TypeError, "Cannot delete 'printer' attribute.");
 		return -1;
 	}
-	if (!PyString_Check(value)) {
+	if (!PyUnicode_Check(value)) {
 		PyErr_SetString(PyExc_TypeError, "The 'printer' attribute value must be string.");
 		return -1;
 	}
@@ -288,7 +288,7 @@
 		PyErr_SetString(PyExc_TypeError, "Cannot delete 'file' attribute.");
 		return -1;
 	}
-	if (!PyString_Check(value)) {
+	if (!PyUnicode_Check(value)) {
 		PyErr_SetString(PyExc_TypeError, "The 'file' attribute value must be string.");
 		return -1;
 	}
@@ -310,7 +310,7 @@
 		PyErr_SetString(PyExc_TypeError, "Cannot delete 'cmd' attribute.");
 		return -1;
 	}
-	if (!PyString_Check(value)) {
+	if (!PyUnicode_Check(value)) {
 		PyErr_SetString(PyExc_TypeError, "The 'cmd' attribute value must be string.");
 		return -1;
 	}
@@ -339,11 +339,11 @@
 	int len = PyList_Size(value);
 	for (int i = 0; i<len; i++){
 		PyObject *tmp = PyList_GetItem(value, i);
-		if (!PyInt_Check(tmp)){
+		if (!PyLong_Check(tmp)){
 			PyErr_SetString(PyExc_TypeError, "'pages' attribute must be list containing only integers.");
 			return -1;
 		}
-		if (PyInt_AsLong(tmp) > static_cast<int>(ScCore->primaryMainWindow()->doc->Pages->count()) || PyInt_AsLong(tmp) < 1) {
+		if (PyLong_AsLong(tmp) > static_cast<int>(ScCore->primaryMainWindow()->doc->Pages->count()) || PyLong_AsLong(tmp) < 1) {
 			PyErr_SetString(PyExc_ValueError, "'pages' value out of range.");
 			return -1;
 		}
@@ -366,7 +366,7 @@
 		PyErr_SetString(PyExc_TypeError, "Cannot delete 'separation' attribute.");
 		return -1;
 	}
-	if (!PyString_Check(value)) {
+	if (!PyUnicode_Check(value)) {
 		PyErr_SetString(PyExc_TypeError, "The 'separation' attribute value must be string.");
 		return -1;
 	}
@@ -400,16 +400,16 @@
 	PSfile = false;
 
 //    ReOrderText(ScCore->primaryMainWindow()->doc, ScCore->primaryMainWindow()->view);
-	prn = QString(PyString_AsString(self->printer));
-	fna = QString(PyString_AsString(self->file));
-	fil = QString(PyString_AsString(self->printer)) == QString("File");
+	prn = PyUnicode_asQString(self->printer);
+	fna = PyUnicode_asQString(self->file);
+	fil = PyUnicode_asQString(self->printer) == QString("File");
 	std::vector<int> pageNs;
 	PrintOptions options;
 	for (int i = 0; i < PyList_Size(self->pages); ++i) {
-		options.pageNumbers.push_back((int)PyInt_AsLong(PyList_GetItem(self->pages, i)));
+		options.pageNumbers.push_back((int) PyLong_AsLong(PyList_GetItem(self->pages, i)));
 	}
 	int copyCount = (self->copies < 1) ? 1 : self->copies;
-	SepName = QString(PyString_AsString(self->separation));
+	SepName = PyUnicode_asQString(self->separation);
 	options.printer   = prn;
 	options.prnEngine = (PrintEngine) self->pslevel;
 	options.toFile    = fil;
@@ -427,7 +427,7 @@
 	options.bleeds.set(0, 0, 0, 0);
 	if (!PrinterUtil::checkPrintEngineSupport(options.printer, options.prnEngine, options.toFile))
 		options.prnEngine = PrinterUtil::getDefaultPrintEngine(options.printer, options.toFile);
-	printcomm = QString(PyString_AsString(self->cmd));
+	printcomm = PyUnicode_asQString(self->cmd);
 	QMap<QString, QMap<uint, FPointArray> > ReallyUsed;
 	ReallyUsed.clear();
 	ScCore->primaryMainWindow()->doc->getUsedFonts(ReallyUsed);
@@ -509,8 +509,7 @@
 };
 
 PyTypeObject Printer_Type = {
-	PyObject_HEAD_INIT(nullptr)   // PyObject_VAR_HEAD
-	0,			 //
+	PyVarObject_HEAD_INIT(nullptr, 0)   // PyObject_VAR_HEAD	 //
 	const_cast<char*>("scribus.Printer"), // char *tp_name; /* For printing, in format "<module>.<name>" */
 	sizeof(Printer),   // int tp_basicsize, /* For allocation */
 	0,		       // int tp_itemsize; /* For allocation */
@@ -585,6 +584,8 @@
 	nullptr, //     PyObject *tp_subclasses;
 	nullptr, //     PyObject *tp_weaklist;
 	nullptr, //     destructor tp_del;
+	0, //	 unsigned int tp_version_tag;
+	0, //	 destructor tp_finalize;
 
 #ifdef COUNT_ALLOCS
 	/* these must be last and never explicitly initialized */
Index: scribus/plugins/scriptplugin/scriptercore.cpp
===================================================================
--- scribus/plugins/scriptplugin/scriptercore.cpp	(revision 23269)
+++ scribus/plugins/scriptplugin/scriptercore.cpp	(working copy)
@@ -17,6 +17,7 @@
 #include <QPixmap>
 #include <cstdlib>
 
+#include "cmdutil.h"
 #include "runscriptdialog.h"
 #include "ui/helpbrowser.h"
 #include "ui/marksmanager.h"
@@ -256,7 +257,7 @@
 		global_state = PyThreadState_Get();
 		state = Py_NewInterpreter();
 		// Init the scripter module in the sub-interpreter
-		initscribus(ScCore->primaryMainWindow());
+		//initscribus(ScCore->primaryMainWindow());
 	}
 
 	// Make sure sys.argv[0] is the path to the script
@@ -263,13 +264,13 @@
 	arguments.prepend(na.data());
 	//convert arguments (QListString) to char** for Python bridge
 	/* typically arguments == ['path/to/script.py','--argument1','valueforarg1','--flag']*/
-	char **comm = new char*[arguments.size()];
+	wchar_t **comm = new wchar_t*[arguments.size()];
 	for (int i = 0; i < arguments.size(); i++)
 	{
-		QByteArray localStr = arguments.at(i).toLocal8Bit();
-		comm[i] = new char[localStr.size() + 1]; //+1 to allow adding '\0'. may be useless, don't know how to check.
-		comm[i][localStr.size()] = 0;
-		strncpy(comm[i], localStr.data(), localStr.size());
+		const QString& argStr = arguments.at(i);
+		comm[i] = new wchar_t[argStr.size() + 1]; //+1 to allow adding '\0'. may be useless, don't know how to check.
+		comm[i][argStr.size()] = 0;
+		argStr.toWCharArray(comm[i]);
 	}
 	PySys_SetArgv(arguments.size(), comm);
 
@@ -291,7 +292,7 @@
 		// Build the Python code to run the script
 		//QString cm = QString("from __future__ import division\n"); removed due #5252 PV
 		QString cm = QString("import sys\n");
-		cm        += QString("import cStringIO\n");
+		cm        += QString("import io\n");
 		/* Implementation of the help() in pydoc.py reads some OS variables
 		 * for output settings. I use ugly hack to stop freezing calling help()
 		 * in script. pv. */
@@ -299,7 +300,7 @@
 		cm        += QString("sys.path[0] = \"%1\"\n").arg(escapedAbsPath);
 		// Replace sys.stdin with a dummy StringIO that always returns
 		// "" for read
-		cm        += QString("sys.stdin = cStringIO.StringIO()\n");
+		cm        += QString("sys.stdin = io.StringIO()\n");
 		// tell the script if it's running in the main intepreter or a subinterpreter
 		cm        += QString("import scribus\n");
 		if (inMainInterpreter)
@@ -307,7 +308,7 @@
 		else
 			cm+= QString("scribus.mainInterpreter = False\n");
 		cm        += QString("try:\n");
-		cm        += QString("    execfile(\"%1\")\n").arg(escapedFileName);
+		cm        += QString("    exec(open(\"%1\", \"rb\").read())\n").arg(escapedFileName);
 		cm        += QString("except SystemExit:\n");
 		cm        += QString("    pass\n");
 		// Capture the text of any other exception that's raised by the interpreter
@@ -341,7 +342,7 @@
 			}
 			else if (ScCore->usingGUI())
 			{
-				QString errorMsg = PyString_AsString(errorMsgPyStr);
+				QString errorMsg = PyUnicode_asQString(errorMsgPyStr);
 				// Display a dialog to the user with the exception
 				QClipboard *cp = QApplication::clipboard();
 				cp->setText(errorMsg);
@@ -399,7 +400,7 @@
 	cm = "# -*- coding: utf8 -*- \n";
 	if (PyThreadState_Get() != nullptr)
 	{
-		initscribus(ScCore->primaryMainWindow());
+		//initscribus(ScCore->primaryMainWindow());
 		/* HACK: following loop handles all input line by line.
 		It *should* use I.C. because of docstrings etc. I.I. cannot
 		handle docstrings right.
@@ -408,8 +409,8 @@
 		works fine in plain Python. Not here. WTF? */
 		cm += (
 				"try:\n"
-				"    import cStringIO\n"
-				"    scribus._bu = cStringIO.StringIO()\n"
+				"    import io\n"
+				"    scribus._bu = io.StringIO()\n"
 				"    sys.stdout = scribus._bu\n"
 				"    sys.stderr = scribus._bu\n"
 				"    sys.argv = ['scribus']\n" // this is the PySys_SetArgv replacement
@@ -420,9 +421,9 @@
 				"    sys.stdout = sys.__stdout__\n"
 				"    sys.stderr = sys.__stderr__\n"
 				"except SystemExit:\n"
-				"    print 'Catched SystemExit - it is not good for Scribus'\n"
+				"    print ('Catched SystemExit - it is not good for Scribus')\n"
 				"except KeyboardInterrupt:\n"
-				"    print 'Catched KeyboardInterrupt - it is not good for Scribus'\n"
+				"    print ('Catched KeyboardInterrupt - it is not good for Scribus')\n"
 			  );
 	}
 	// Set up sys.argv
@@ -599,8 +600,8 @@
 		"import sys\n"
 		"import code\n"
 		"sys.path.insert(0, \"%1\")\n"
-		"import cStringIO\n"
-		"sys.stdin = cStringIO.StringIO()\n"
+		"import io\n"
+		"sys.stdin = io.StringIO()\n"
 		"scribus._ia = code.InteractiveConsole(globals())\n"
 		).arg(ScPaths::instance().scriptDir());
 	if (m_importAllNames)
Index: scribus/plugins/scriptplugin/scriptplugin.cpp
===================================================================
--- scribus/plugins/scriptplugin/scriptplugin.cpp	(revision 23269)
+++ scribus/plugins/scriptplugin/scriptplugin.cpp	(working copy)
@@ -166,20 +166,20 @@
 	if (QDir(pyHome).exists())
 	{
 		QString ph = QDir::toNativeSeparators(pyHome);
-		pythonHome = ph.toLocal8Bit();
-		Py_SetPythonHome(pythonHome.data());
+		pythonHome.resize(2 * ph.length() + 2);
+		memcpy(pythonHome.data(), ph.utf16(), 2 * ph.length() + 2);
+		Py_SetPythonHome((const wchar_t*) pythonHome.constData());
 	}
 #endif
-	Py_Initialize();
-	if (PyUnicode_SetDefaultEncoding("utf-8"))
-	{
-		qDebug("Failed to set default encoding to utf-8.\n");
-		PyErr_Clear();
-	}
 
 	scripterCore = new ScripterCore(ScCore->primaryMainWindow());
 	Q_CHECK_PTR(scripterCore);
-	initscribus(ScCore->primaryMainWindow());
+
+	PyImport_AppendInittab("scribus", &PyInit_scribus);
+	Py_Initialize();
+
+	//initscribus(ScCore->primaryMainWindow());
+	
 #ifdef HAVE_SCRIPTER2
 	scripter2_init();
 #endif
@@ -228,7 +228,7 @@
 /*static */PyObject *scribus_retval(PyObject* /*self*/, PyObject* args)
 {
 	char *Name = nullptr;
-	if (!PyArg_ParseTuple(args, (char*)"s", &Name))
+	if (!PyArg_ParseTuple(args, (char*) "s", &Name))
 		return nullptr;
 	// Because sysdefaultencoding is not utf-8, Python is returning utf-8 encoded
 	// 8-bit char* strings. Make sure Qt understands that the input is utf-8 not
@@ -236,12 +236,12 @@
 	/*RetString = QString::fromUtf8(Name);
 	RetVal = retV;*/
 	scripterCore->returnString = QString::fromUtf8(Name);
-	return PyInt_FromLong(0L);
+	return PyLong_FromLong(0L);
 }
 
 /*static */PyObject *scribus_getval(PyObject* /*self*/)
 {
-	return PyString_FromString(scripterCore->inValue.toUtf8().data());
+	return PyUnicode_FromString(scripterCore->inValue.toUtf8().data());
 }
 
 /*! \brief Translate a docstring. Small helper function for use with the
@@ -307,8 +307,8 @@
 	{const_cast<char*>("createRect"), scribus_newrect, METH_VARARGS, tr(scribus_newrect__doc__)},
 	{const_cast<char*>("createText"), scribus_newtext, METH_VARARGS, tr(scribus_newtext__doc__)},
 	{const_cast<char*>("createTable"), scribus_newtable, METH_VARARGS, tr(scribus_newtable__doc__)},
-	{const_cast<char*>("createParagraphStyle"), (PyCFunction)scribus_createparagraphstyle, METH_KEYWORDS, tr(scribus_createparagraphstyle__doc__)},
-	{const_cast<char*>("createCharStyle"), (PyCFunction)scribus_createcharstyle, METH_KEYWORDS, tr(scribus_createcharstyle__doc__)},
+	{const_cast<char*>("createParagraphStyle"), (PyCFunction)scribus_createparagraphstyle, METH_VARARGS|METH_KEYWORDS, tr(scribus_createparagraphstyle__doc__)},
+	{const_cast<char*>("createCharStyle"), (PyCFunction)scribus_createcharstyle, METH_VARARGS|METH_KEYWORDS, tr(scribus_createcharstyle__doc__)},
 	{const_cast<char*>("createCustomLineStyle"), scribus_createcustomlinestyle, METH_VARARGS, tr(scribus_createcustomlinestyle__doc__)},
 	{const_cast<char*>("currentPage"), (PyCFunction)scribus_actualpage, METH_NOARGS, tr(scribus_actualpage__doc__)},
 	{const_cast<char*>("defineColor"), scribus_newcolor, METH_VARARGS, tr(scribus_newcolor__doc__)},
@@ -453,7 +453,7 @@
 	{const_cast<char*>("redrawAll"), (PyCFunction)scribus_redraw, METH_NOARGS, tr(scribus_redraw__doc__)},
 	{const_cast<char*>("removeTableRows"), scribus_removetablerows, METH_VARARGS, tr(scribus_removetablerows__doc__)},
 	{const_cast<char*>("removeTableColumns"), scribus_removetablecolumns, METH_VARARGS, tr(scribus_removetablecolumns__doc__)},
-	{const_cast<char*>("renderFont"), (PyCFunction)scribus_renderfont, METH_KEYWORDS, tr(scribus_renderfont__doc__)},
+	{const_cast<char*>("renderFont"), (PyCFunction)scribus_renderfont, METH_VARARGS|METH_KEYWORDS, tr(scribus_renderfont__doc__)},
 	{const_cast<char*>("replaceColor"), scribus_replcolor, METH_VARARGS, tr(scribus_replcolor__doc__)},
 	{const_cast<char*>("resizeTableColumn"), scribus_resizetablecolumn, METH_VARARGS, tr(scribus_resizetablecolumn__doc__)},
 	{const_cast<char*>("resizeTableRow"), scribus_resizetablerow, METH_VARARGS, tr(scribus_resizetablerow__doc__)},
@@ -535,7 +535,7 @@
 	{const_cast<char*>("dehyphenateText"), scribus_dehyphenatetext, METH_VARARGS, tr(scribus_dehyphenatetext__doc__)},
 	{const_cast<char*>("scrollDocument"), scribus_scrolldocument, METH_VARARGS, tr(scribus_scrolldocument__doc__) },
 	{const_cast<char*>("setScaleFrameToImage"), (PyCFunction)scribus_setscaleframetoimage, METH_VARARGS, tr(scribus_setscaleframetoimage__doc__)},
-	{const_cast<char*>("setScaleImageToFrame"), (PyCFunction)scribus_setscaleimagetoframe, METH_KEYWORDS, tr(scribus_setscaleimagetoframe__doc__)},
+	{const_cast<char*>("setScaleImageToFrame"), (PyCFunction)scribus_setscaleimagetoframe, METH_VARARGS|METH_KEYWORDS, tr(scribus_setscaleimagetoframe__doc__)},
 	{const_cast<char*>("setStyle"), scribus_setstyle, METH_VARARGS, tr(scribus_setstyle__doc__)},
 	{const_cast<char*>("setCharacterStyle"), scribus_setcharstyle, METH_VARARGS, tr(scribus_setcharstyle__doc__) },
 	{const_cast<char*>("setTableStyle"), scribus_settablestyle, METH_VARARGS, tr(scribus_settablestyle__doc__)},
@@ -558,7 +558,7 @@
 	{const_cast<char*>("sizeObject"), scribus_sizeobjabs, METH_VARARGS, tr(scribus_sizeobjabs__doc__)},
 	{const_cast<char*>("statusMessage"), scribus_messagebartext, METH_VARARGS, tr(scribus_messagebartext__doc__)},
 	{const_cast<char*>("textFlowMode"), scribus_textflow, METH_VARARGS, tr(scribus_textflow__doc__)},
-	{const_cast<char*>("textOverflows"), (PyCFunction)scribus_istextoverflowing, METH_KEYWORDS, tr(scribus_istextoverflowing__doc__) },
+	{const_cast<char*>("textOverflows"), (PyCFunction)scribus_istextoverflowing, METH_VARARGS|METH_KEYWORDS, tr(scribus_istextoverflowing__doc__) },
 	{const_cast<char*>("traceText"), scribus_tracetext, METH_VARARGS, tr(scribus_tracetext__doc__)},
 	{const_cast<char*>("unGroupObject"), scribus_ungroupobj, METH_VARARGS, tr(scribus_ungroupobj__doc__)},
 	{const_cast<char*>("unlinkTextFrames"), scribus_unlinktextframes, METH_VARARGS, tr(scribus_unlinktextframes__doc__)},
@@ -565,12 +565,12 @@
 	{const_cast<char*>("valueDialog"), scribus_valdialog, METH_VARARGS, tr(scribus_valdialog__doc__)},
 	{const_cast<char*>("zoomDocument"), scribus_zoomdocument, METH_VARARGS, tr(scribus_zoomdocument__doc__)},
 	// Property magic
-	{const_cast<char*>("getPropertyCType"), (PyCFunction)scribus_propertyctype, METH_KEYWORDS, tr(scribus_propertyctype__doc__)},
-	{const_cast<char*>("getPropertyNames"), (PyCFunction)scribus_getpropertynames, METH_KEYWORDS, tr(scribus_getpropertynames__doc__)},
-	{const_cast<char*>("getProperty"), (PyCFunction)scribus_getproperty, METH_KEYWORDS, tr(scribus_getproperty__doc__)},
-	{const_cast<char*>("setProperty"), (PyCFunction)scribus_setproperty, METH_KEYWORDS, tr(scribus_setproperty__doc__)},
-// 	{const_cast<char*>("getChildren"), (PyCFunction)scribus_getchildren, METH_KEYWORDS, tr(scribus_getchildren__doc__)},
-// 	{const_cast<char*>("getChild"), (PyCFunction)scribus_getchild, METH_KEYWORDS, tr(scribus_getchild__doc__)},
+	{const_cast<char*>("getPropertyCType"), (PyCFunction)scribus_propertyctype, METH_VARARGS|METH_KEYWORDS, tr(scribus_propertyctype__doc__)},
+	{const_cast<char*>("getPropertyNames"), (PyCFunction)scribus_getpropertynames, METH_VARARGS|METH_KEYWORDS, tr(scribus_getpropertynames__doc__)},
+	{const_cast<char*>("getProperty"), (PyCFunction)scribus_getproperty, METH_VARARGS|METH_KEYWORDS, tr(scribus_getproperty__doc__)},
+	{const_cast<char*>("setProperty"), (PyCFunction)scribus_setproperty, METH_VARARGS|METH_KEYWORDS, tr(scribus_setproperty__doc__)},
+// 	{const_cast<char*>("getChildren"), (PyCFunction)scribus_getchildren, METH_VARARGS|METH_KEYWORDS, tr(scribus_getchildren__doc__)},
+// 	{const_cast<char*>("getChild"), (PyCFunction)scribus_getchild, METH_VARARGS|METH_KEYWORDS, tr(scribus_getchild__doc__)},
 	// by Christian Hausknecht
 	{const_cast<char*>("duplicateObject"), scribus_duplicateobject, METH_VARARGS, tr(scribus_duplicateobject__doc__)},
 	{const_cast<char*>("copyObject"), scribus_copyobject, METH_VARARGS, tr(scribus_copyobject__doc__)},
@@ -591,6 +591,36 @@
 	{nullptr, (PyCFunction)(nullptr), 0, nullptr} /* sentinel */
 };
 
+struct scribus_module_state
+{
+    PyObject *error;
+};
+#define GETSTATE(m) ((struct scribus_module_state*) PyModule_GetState(m))
+
+static int scribus_extension_traverse(PyObject *m, visitproc visit, void *arg)
+{
+	Py_VISIT(GETSTATE(m)->error);
+	return 0;
+}
+
+static int scribus_extension_clear(PyObject *m)
+{
+	Py_CLEAR(GETSTATE(m)->error);
+	return 0;
+}
+
+static struct PyModuleDef scribus_module_def = {
+        PyModuleDef_HEAD_INIT,
+        "scribus",
+        NULL,
+        sizeof(struct scribus_module_state),
+        scribus_methods,
+        NULL,
+        scribus_extension_traverse,
+        scribus_extension_clear,
+        NULL
+};
+
 void initscribus_failed(const char* fileName, int lineNo)
 {
 	qDebug("Scripter setup failed (%s:%i)", fileName, lineNo);
@@ -598,68 +628,78 @@
 		PyErr_Print();
 }
 
-void initscribus(ScribusMainWindow *mainWin)
+PyObject* PyInit_scribus(void)
 {
+	ScribusMainWindow* mainWin = ScCore->primaryMainWindow();
 	if (!scripterCore)
 	{
 		qWarning("scriptplugin: Tried to init scribus module, but no scripter core. Aborting.");
-		return;
+		return nullptr;
 	}
+
+	int result;
 	PyObject *m, *d;
-	PyImport_AddModule((char*)"scribus");
 
 	PyType_Ready(&Printer_Type);
 	PyType_Ready(&PDFfile_Type);
 	PyType_Ready(&ImageExport_Type);
-	m = Py_InitModule((char*)"scribus", scribus_methods);
+
+	m = PyModule_Create(&scribus_module_def);
+
 	Py_INCREF(&Printer_Type);
-	PyModule_AddObject(m, (char*)"Printer", (PyObject *) &Printer_Type);
+	result = PyModule_AddObject(m, (char*) "Printer", (PyObject *) &Printer_Type);
+	if (result != 0)
+		qDebug("scriptplugin: Could not create scribus.Printer module");
 	Py_INCREF(&PDFfile_Type);
-	PyModule_AddObject(m, (char*)"PDFfile", (PyObject *) &PDFfile_Type);
+	result = PyModule_AddObject(m, (char*) "PDFfile", (PyObject *) &PDFfile_Type);
+	if (result != 0)
+		qDebug("scriptplugin: Could not create scribus.PDFfile module");
 	Py_INCREF(&ImageExport_Type);
-	PyModule_AddObject(m, (char*)"ImageExport", (PyObject *) &ImageExport_Type);
+	PyModule_AddObject(m, (char*) "ImageExport", (PyObject *) &ImageExport_Type);
+	if (result != 0)
+		qDebug("scriptplugin: Could not create scribus.ImageExport module");
 	d = PyModule_GetDict(m);
 
 	// Set up the module exceptions
 	// common exc.
-	ScribusException = PyErr_NewException((char*)"scribus.ScribusException", nullptr, nullptr);
+	ScribusException = PyErr_NewException((char*) "scribus.ScribusException", nullptr, nullptr);
 	Py_INCREF(ScribusException);
-	PyModule_AddObject(m, (char*)"ScribusException", ScribusException);
+	PyModule_AddObject(m, (char*) "ScribusException", ScribusException);
 	// no doc open
-	NoDocOpenError = PyErr_NewException((char*)"scribus.NoDocOpenError", ScribusException, nullptr);
+	NoDocOpenError = PyErr_NewException((char*) "scribus.NoDocOpenError", ScribusException, nullptr);
 	Py_INCREF(NoDocOpenError);
-	PyModule_AddObject(m, (char*)"NoDocOpenError", NoDocOpenError);
+	PyModule_AddObject(m, (char*) "NoDocOpenError", NoDocOpenError);
 	// wrong type of frame for operation
-	WrongFrameTypeError = PyErr_NewException((char*)"scribus.WrongFrameTypeError", ScribusException, nullptr);
+	WrongFrameTypeError = PyErr_NewException((char*) "scribus.WrongFrameTypeError", ScribusException, nullptr);
 	Py_INCREF(WrongFrameTypeError);
-	PyModule_AddObject(m, (char*)"WrongFrameTypeError", WrongFrameTypeError);
+	PyModule_AddObject(m, (char*) "WrongFrameTypeError", WrongFrameTypeError);
 	// Couldn't find named object, or no named object and no selection
-	NoValidObjectError = PyErr_NewException((char*)"scribus.NoValidObjectError", ScribusException, nullptr);
+	NoValidObjectError = PyErr_NewException((char*) "scribus.NoValidObjectError", ScribusException, nullptr);
 	Py_INCREF(NoValidObjectError);
-	PyModule_AddObject(m, (char*)"NoValidObjectError", NoValidObjectError);
+	PyModule_AddObject(m, (char*) "NoValidObjectError", NoValidObjectError);
 	// Couldn't find the specified resource - font, color, etc.
-	NotFoundError = PyErr_NewException((char*)"scribus.NotFoundError", ScribusException, nullptr);
+	NotFoundError = PyErr_NewException((char*) "scribus.NotFoundError", ScribusException, nullptr);
 	Py_INCREF(NotFoundError);
-	PyModule_AddObject(m, (char*)"NotFoundError", NotFoundError);
+	PyModule_AddObject(m, (char*) "NotFoundError", NotFoundError);
 	// Tried to create an object with the same name as one that already exists
-	NameExistsError = PyErr_NewException((char*)"scribus.NameExistsError", ScribusException, nullptr);
+	NameExistsError = PyErr_NewException((char*) "scribus.NameExistsError", ScribusException, nullptr);
 	Py_INCREF(NameExistsError);
-	PyModule_AddObject(m, (char*)"NameExistsError", NameExistsError);
+	PyModule_AddObject(m, (char*) "NameExistsError", NameExistsError);
 	// Done with exception setup
 
 	// CONSTANTS
-	PyDict_SetItemString(d, const_cast<char*>("UNIT_POINTS"), PyInt_FromLong(unitIndexFromString("pt")));
-	PyDict_SetItemString(d, const_cast<char*>("UNIT_MILLIMETERS"), PyInt_FromLong(unitIndexFromString("mm")));
-	PyDict_SetItemString(d, const_cast<char*>("UNIT_INCHES"), PyInt_FromLong(unitIndexFromString("in")));
-	PyDict_SetItemString(d, const_cast<char*>("UNIT_PICAS"), PyInt_FromLong(unitIndexFromString("p")));
-	PyDict_SetItemString(d, const_cast<char*>("UNIT_CENTIMETRES"), PyInt_FromLong(unitIndexFromString("cm")));
-	PyDict_SetItemString(d, const_cast<char*>("UNIT_CICERO"), PyInt_FromLong(unitIndexFromString("c")));
-	PyDict_SetItemString(d, const_cast<char*>("UNIT_PT"), PyInt_FromLong(unitIndexFromString("pt")));
-	PyDict_SetItemString(d, const_cast<char*>("UNIT_MM"), PyInt_FromLong(unitIndexFromString("mm")));
-	PyDict_SetItemString(d, const_cast<char*>("UNIT_IN"), PyInt_FromLong(unitIndexFromString("in")));
-	PyDict_SetItemString(d, const_cast<char*>("UNIT_P"), PyInt_FromLong(unitIndexFromString("p")));
-	PyDict_SetItemString(d, const_cast<char*>("UNIT_CM"), PyInt_FromLong(unitIndexFromString("cm")));
-	PyDict_SetItemString(d, const_cast<char*>("UNIT_C"), PyInt_FromLong(unitIndexFromString("c")));
+	PyDict_SetItemString(d, const_cast<char*>("UNIT_POINTS"), PyLong_FromLong(unitIndexFromString("pt")));
+	PyDict_SetItemString(d, const_cast<char*>("UNIT_MILLIMETERS"), PyLong_FromLong(unitIndexFromString("mm")));
+	PyDict_SetItemString(d, const_cast<char*>("UNIT_INCHES"), PyLong_FromLong(unitIndexFromString("in")));
+	PyDict_SetItemString(d, const_cast<char*>("UNIT_PICAS"), PyLong_FromLong(unitIndexFromString("p")));
+	PyDict_SetItemString(d, const_cast<char*>("UNIT_CENTIMETRES"), PyLong_FromLong(unitIndexFromString("cm")));
+	PyDict_SetItemString(d, const_cast<char*>("UNIT_CICERO"), PyLong_FromLong(unitIndexFromString("c")));
+	PyDict_SetItemString(d, const_cast<char*>("UNIT_PT"), PyLong_FromLong(unitIndexFromString("pt")));
+	PyDict_SetItemString(d, const_cast<char*>("UNIT_MM"), PyLong_FromLong(unitIndexFromString("mm")));
+	PyDict_SetItemString(d, const_cast<char*>("UNIT_IN"), PyLong_FromLong(unitIndexFromString("in")));
+	PyDict_SetItemString(d, const_cast<char*>("UNIT_P"), PyLong_FromLong(unitIndexFromString("p")));
+	PyDict_SetItemString(d, const_cast<char*>("UNIT_CM"), PyLong_FromLong(unitIndexFromString("cm")));
+	PyDict_SetItemString(d, const_cast<char*>("UNIT_C"), PyLong_FromLong(unitIndexFromString("c")));
 	PyDict_SetItemString(d, const_cast<char*>("PORTRAIT"), Py_BuildValue(const_cast<char*>("i"), portraitPage));
 	PyDict_SetItemString(d, const_cast<char*>("LANDSCAPE"), Py_BuildValue(const_cast<char*>("i"), landscapePage));
 	PyDict_SetItemString(d, const_cast<char*>("NOFACINGPAGES"), Py_BuildValue(const_cast<char*>("i"), 0));
@@ -799,28 +839,28 @@
 		if (!value)
 		{
 			initscribus_failed(__FILE__, __LINE__);
-			return;
+			return nullptr;
 		}
 		// `in' is a reserved word in Python so we must replace it
 		PyObject* name;
 		if (unitGetUntranslatedStrFromIndex(i) == "in")
-			name = PyString_FromString("inch");
+			name = PyUnicode_FromString("inch");
 		else
-			name = PyString_FromString(unitGetUntranslatedStrFromIndex(i).toLatin1().constData());
+			name = PyUnicode_FromString(unitGetUntranslatedStrFromIndex(i).toUtf8().constData());
 		if (!name)
 		{
 			initscribus_failed(__FILE__, __LINE__);
-			return;
+			return nullptr;
 		}
 		if (PyDict_SetItem(d, name, value))
 		{
 			initscribus_failed(__FILE__, __LINE__);
-			return;
+			return nullptr;
 		}
 	}
 
 	// Export the Scribus version into the module namespace so scripts know what they're running in
-	PyDict_SetItemString(d, const_cast<char*>("scribus_version"), PyString_FromString(const_cast<char*>(VERSION)));
+	PyDict_SetItemString(d, const_cast<char*>("scribus_version"), PyUnicode_FromString(const_cast<char*>(VERSION)));
 	// Now build a version tuple like that provided by Python in sys.version_info
 	// The tuple is of the form (major, minor, patchlevel, extraversion, reserved)
 	QRegExp version_re("(\\d+)\\.(\\d+)\\.(\\d+)(.*)");
@@ -848,28 +888,20 @@
 	// the generated Python functions from inside the `scribus' module's context.
 	// This code makes it possible to extend the `scribus' module by running Python code
 	// from C in other ways too.
-	PyObject* builtinModule = PyImport_ImportModuleEx(const_cast<char*>("__builtin__"),
+	PyObject* builtinModule = PyImport_ImportModuleEx(const_cast<char*>("builtins"),
 			d, d, Py_BuildValue(const_cast<char*>("[]")));
 	if (builtinModule == nullptr)
 	{
-		qDebug("Failed to import __builtin__ module. Something is probably broken with your Python.");
-		return;
+		qDebug("Failed to import builtins module. Something is probably broken with your Python.");
+		return nullptr;
 	}
-	PyDict_SetItemString(d, const_cast<char*>("__builtin__"), builtinModule);
-	PyObject* exceptionsModule = PyImport_ImportModuleEx(const_cast<char*>("exceptions"),
-			d, d, Py_BuildValue(const_cast<char*>("[]")));
-	if (exceptionsModule == nullptr)
-	{
-		qDebug("Failed to import exceptions module. Something is probably broken with your Python.");
-		return;
-	}
-	PyDict_SetItemString(d, const_cast<char*>("exceptions"), exceptionsModule);
+	PyDict_SetItemString(d, const_cast<char*>("builtins"), builtinModule);
 	PyObject* warningsModule = PyImport_ImportModuleEx(const_cast<char*>("warnings"),
 			d, d, Py_BuildValue(const_cast<char*>("[]")));
 	if (warningsModule == nullptr)
 	{
 		qDebug("Failed to import warnings module. Something is probably broken with your Python.");
-		return;
+		return nullptr;
 	}
 	PyDict_SetItemString(d, const_cast<char*>("warnings"), warningsModule);
 	// Create the module-level docstring. This can be a proper unicode string, unlike
@@ -907,21 +939,11 @@
 is not exhaustive due to exceptions from called functions.\n\
 ");
 
-	PyObject* docStr = PyString_FromString(docstring.toUtf8().data());
+	PyObject* docStr = PyUnicode_FromString(docstring.toUtf8().data());
 	if (!docStr)
 		qDebug("Failed to create module-level docstring (couldn't make str)");
 	else
-	{
-		PyObject* uniDocStr = PyUnicode_FromEncodedObject(docStr, "utf-8", nullptr);
-		Py_DECREF(docStr);
-		docStr = nullptr;
-		if (!uniDocStr)
-			qDebug("Failed to create module-level docstring object (couldn't make unicode)");
-		else
-			PyDict_SetItemString(d, const_cast<char*>("__doc__"), uniDocStr);
-		Py_DECREF(uniDocStr);
-		uniDocStr = nullptr;
-	}
+		PyDict_SetItemString(d, const_cast<char*>("__doc__"), docStr);
 
 	// Wrap up pointers to the the QApp and main window and push them out
 	// to Python.
@@ -946,6 +968,8 @@
 	PyDict_SetItemString(d, const_cast<char*>("mainWindow"), wrappedMainWindow);
 	Py_DECREF(wrappedMainWindow);
 	wrappedMainWindow = nullptr;
+
+	return m;
 }
 
 /*! HACK: this removes "warning: 'blah' defined but not used" compiler warnings
Index: scribus/plugins/scriptplugin/scripts/Align_image_in_frame.py
===================================================================
--- scribus/plugins/scriptplugin/scripts/Align_image_in_frame.py	(revision 23269)
+++ scribus/plugins/scriptplugin/scripts/Align_image_in_frame.py	(working copy)
@@ -22,10 +22,9 @@
 import scribus
  
 try:
-    from Tkinter import *
-    from tkFont import Font
+    from tkinter import *
 except ImportError:
-    print "This script requires Python's Tkinter properly installed."
+    print ("This script requires Python's Tkinter properly installed.")
     scribus.messageBox('Script failed',
                'This script requires Python\'s Tkinter properly installed.',
                scribus.ICON_CRITICAL)
@@ -83,8 +82,8 @@
  
     def alignImage(self):
         if scribus.haveDoc():
-	    restore_units = scribus.getUnit()   # since there is an issue with units other than points,
-	    scribus.setUnit(0)			# we switch to points then restore later.
+            restore_units = scribus.getUnit()   # since there is an issue with units other than points,
+            scribus.setUnit(0)			# we switch to points then restore later.
             nbrSelected = scribus.selectionCount()
             objList = []
             for i in range(nbrSelected):
@@ -124,9 +123,9 @@
                     scribus.deselectAll()
                 except:
                     nothing = "nothing"
-	    scribus.setUnit(restore_units)
-	    
-	    self.master.destroy()
+            scribus.setUnit(restore_units)
+            
+            self.master.destroy()
  
  
 def main():
Index: scribus/plugins/scriptplugin/scripts/CalendarWizard.py
===================================================================
--- scribus/plugins/scriptplugin/scripts/CalendarWizard.py	(revision 23269)
+++ scribus/plugins/scriptplugin/scripts/CalendarWizard.py	(working copy)
@@ -54,16 +54,16 @@
 try:
     from scribus import *
 except ImportError:
-    print "This Python script is written for the Scribus scripting interface."
-    print "It can only be run from within Scribus."
+    print ("This Python script is written for the Scribus scripting interface.")
+    print ("It can only be run from within Scribus.")
     sys.exit(1)
 
 try:
     # I wish PyQt installed everywhere :-/
-    from Tkinter import *
-    from tkFont import Font
+    from tkinter import *
+    from tkinter import font
 except ImportError:
-    print "This script requires Python's Tkinter properly installed."
+    print ("This script requires Python's Tkinter properly installed.")
     messageBox('Script failed',
                'This script requires Python\'s Tkinter properly installed.',
                ICON_CRITICAL)
@@ -307,14 +307,14 @@
         ScCalendar.__init__(self, year, months, firstDay, drawSauce, sepMonths, lang)
 
     def printMonth(self, cal, month, week):
-	    """ Print the month name(s) """
-	    if week[6].day < 7:
-		    if (week == cal[len(cal)-1]):
-			    self.createHeader(localization[self.lang][0][month] + self.sepMonths + localization[self.lang][0][(month+1)%12])
-		    elif ((month-1) not in self.months):
-			    self.createHeader(localization[self.lang][0][(month-1)%12] + self.sepMonths + localization[self.lang][0][month])
-	    else:
-		    self.createHeader(localization[self.lang][0][month])
+        """ Print the month name(s) """
+        if week[6].day < 7:
+            if (week == cal[len(cal)-1]):
+                self.createHeader(localization[self.lang][0][month] + self.sepMonths + localization[self.lang][0][(month+1)%12])
+            elif ((month-1) not in self.months):
+                self.createHeader(localization[self.lang][0][(month-1)%12] + self.sepMonths + localization[self.lang][0][month])
+        else:
+            self.createHeader(localization[self.lang][0][month])
 
     def createMonthCalendar(self, month, cal):
         """ Draw one week calendar per page """
@@ -325,12 +325,12 @@
             # * If it starts on the first weekday
             # * If the month before it isn't included
             if (week != cal[0]) or (week[0].day == 1) or ((month-1) not in self.months):
-				self.createLayout()
-				self.printMonth(cal, month, week)
-				self.printWeekNo(week)
+                self.createLayout()
+                self.printMonth(cal, month, week)
+                self.printWeekNo(week)
 
-				for day in week:
-				    self.printDay(day)
+                for day in week:
+                    self.printDay(day)
 
 class ScHorizontalEventCalendar(ScEventCalendar):
     """ One day = one row calendar. I suggest LANDSCAPE orientation.\
@@ -445,11 +445,11 @@
                 cel = createText(self.marginl + colCnt * self.colSize,
                                  self.calHeight + rowCnt * self.rowSize,
                                  self.colSize, self.rowSize)
-		setLineColor("Black", cel)  # comment this out if you do not want border to cells
+                setLineColor("Black", cel)  # comment this out if you do not want border to cells
                 colCnt += 1
                 if day.month == month + 1:
-					setText(str(day.day), cel)
-					setStyle(self.pStyleDate, cel)
+                    setText(str(day.day), cel)
+                    setStyle(self.pStyleDate, cel)
             rowCnt += 1
 
 class ScVerticalEventCalendar(ScVerticalCalendar, ScEventCalendar):
@@ -507,7 +507,7 @@
         self.langScrollbar.config(command=self.langListbox.yview)
 
         keys = localization.keys()
-        keys.sort()
+        sorted(keys)
         for i in keys:
             self.langListbox.insert(END, i)
         self.langButton = Button(self, text='Change language', command=self.languageChange)
Index: scribus/plugins/scriptplugin/scripts/Caption.py
===================================================================
--- scribus/plugins/scriptplugin/scripts/Caption.py	(revision 23269)
+++ scribus/plugins/scriptplugin/scripts/Caption.py	(working copy)
@@ -47,8 +47,8 @@
 try:
     import scribus
 except ImportError:
-    print "Unable to import the 'scribus' module. This script will only run within"
-    print "the Python interpreter embedded in Scribus. Try Script->Execute Script."
+    print ("Unable to import the 'scribus' module. This script will only run within")
+    print ("the Python interpreter embedded in Scribus. Try Script->Execute Script.")
     sys.exit(1)
 
 numselect = scribus.selectionCount()
Index: scribus/plugins/scriptplugin/scripts/color2csv.py
===================================================================
--- scribus/plugins/scriptplugin/scripts/color2csv.py	(revision 23269)
+++ scribus/plugins/scriptplugin/scripts/color2csv.py	(working copy)
@@ -46,8 +46,8 @@
     # as commonly used constants.
     import scribus
 except ImportError,err:
-    print "This Python script is written for the Scribus scripting interface."
-    print "It can only be run from within Scribus."
+    print ("This Python script is written for the Scribus scripting interface.")
+    print ("It can only be run from within Scribus.")
     sys.exit(1)
 
 #########################
Index: scribus/plugins/scriptplugin/scripts/ColorChart.py
===================================================================
--- scribus/plugins/scriptplugin/scripts/ColorChart.py	(revision 23269)
+++ scribus/plugins/scriptplugin/scripts/ColorChart.py	(working copy)
@@ -48,8 +48,8 @@
     # as commonly used constants.
     import scribus
 except ImportError,err:
-    print "This Python script is written for the Scribus scripting interface."
-    print "It can only be run from within Scribus."
+    print ("This Python script is written for the Scribus scripting interface.")
+    print ("It can only be run from within Scribus.")
     sys.exit(1)
 
 ####################
Index: scribus/plugins/scriptplugin/scripts/csv2color.py
===================================================================
--- scribus/plugins/scriptplugin/scripts/csv2color.py	(revision 23269)
+++ scribus/plugins/scriptplugin/scripts/csv2color.py	(working copy)
@@ -52,8 +52,8 @@
     # as commonly used constants.
     import scribus
 except ImportError,err:
-    print "This Python script is written for the Scribus scripting interface."
-    print "It can only be run from within Scribus."
+    print ("This Python script is written for the Scribus scripting interface.")
+    print ("It can only be run from within Scribus.")
     sys.exit(1)
 
 #########################
Index: scribus/plugins/scriptplugin/scripts/DirectImageImport.py
===================================================================
--- scribus/plugins/scriptplugin/scripts/DirectImageImport.py	(revision 23269)
+++ scribus/plugins/scriptplugin/scripts/DirectImageImport.py	(working copy)
@@ -54,7 +54,7 @@
     from scribus import *
     
 except ImportError:
-    print "This script only runs from within Scribus."
+    print ("This script only runs from within Scribus.")
     sys.exit(1)
 try:
     from PIL import Image
@@ -77,8 +77,8 @@
 
 # for images taller than they are wide we want to limit height of frame to 80% of page height
     if (Hoehe > pageY * 0.8):
-	Hoehe = pageY * 0.8
-	Breite = Hoehe * xsize/ysize
+        Hoehe = pageY * 0.8
+        Breite = Hoehe * xsize/ysize
 
     ImageFrame = createImage(pageX/2 - Breite/2, pageY/2 - Hoehe/2, Breite, Hoehe)
     loadImage(ImageFileName, ImageFrame)
Index: scribus/plugins/scriptplugin/scripts/FontSample.py
===================================================================
--- scribus/plugins/scriptplugin/scripts/FontSample.py	(revision 23269)
+++ scribus/plugins/scriptplugin/scripts/FontSample.py	(working copy)
@@ -112,7 +112,7 @@
 
 import sys
 import os
-import cPickle
+import pickle
 
 
 showPreviewPanel = 1 # change to 0 to permanently hide the preview
@@ -122,17 +122,17 @@
 
 try:
     import scribus
-except ImportError,err:
-    print 'This Python script is written for the Scribus scripting interface.'
-    print 'It can only be run from within Scribus.'
+except ImportError as err:
+    print ('This Python script is written for the Scribus scripting interface.')
+    print ('It can only be run from within Scribus.')
     sys.exit(1)
 
 
 try:
-    from Tkinter import *
-except ImportError,err:
-    print 'This script will not work without Tkinter'
-    scribus.messageBox('Error','This script will not work without Tkinter\nPlease install and try again',
+    from tkinter import *
+except ImportError as err:
+    print ('This script will not work without tkinter')
+    scribus.messageBox('Error','This script will not work without tkinter\nPlease install and try again',
                     scribus.ICON_WARNING)
     sys.exit(1)
 
@@ -139,43 +139,43 @@
 
 if not os.path.exists(CONFIG_PATH):
     try:
-        print 'Attempting to creating configuration file directory...'
+        print ('Attempting to creating configuration file directory...')
         os.mkdir(CONFIG_PATH)
-        print 'Success, now testing for write access of new directory...'
+        print ('Success, now testing for write access of new directory...')
         if os.access(CONFIG_PATH, os.W_OK):
-            print 'Write access ok.'
+            print ('Write access ok.')
         else:
-            print 'Error, unable to write to .scribus/fontsampler directory.'
+            print ('Error, unable to write to .scribus/fontsampler directory.')
     except:
         CONFIG_PATH = ''
-        print 'Failed to make configuration file directory,'
-        print 'do you have a .scribus directory in your home directory?'
-        print 'font sampler will not be able to save your preferences'
+        print ('Failed to make configuration file directory,')
+        print ('do you have a .scribus directory in your home directory?')
+        print ('font sampler will not be able to save your preferences')
 
 
 try:
     from PIL import Image
-except ImportError,err:
-    print 'You need to install Python Imaging Library (PIL).'
-    print 'If using gentoo then you need to emerge /dev-python/imaging'
-    print 'If using an RPM based linux distribution then you add python-imaging or similar.'
-    print 'Script will continue without the font preview panel.'
+except ImportError as err:
+    print ('You need to install Python Imaging Library (PIL).')
+    print ('If using gentoo then you need to emerge /dev-python/imaging')
+    print ('If using an RPM based linux distribution then you add python-imaging or similar.')
+    print ('Script will continue without the font preview panel.')
     showPreviewPanel = 0
 
 
 try:
     from PIL import ImageTk
-except ImportError,err:
-    print 'Module ImageTk not found, font preview disabled'
+except ImportError as err:
+    print ('Module ImageTk not found, font preview disabled')
     showPreviewPanel = 0
 
 
 if showPreviewPanel:
     if not os.path.exists(TEMP_PATH):
-        print '.scribus folder not found, disabling font preview panel'
+        print ('.scribus folder not found, disabling font preview panel')
         showPreviewPanel = 0
     if not os.access(TEMP_PATH, os.W_OK):
-        print 'Unable to write to .scribus folder, disabling font preview panel'
+        print ('Unable to write to .scribus folder, disabling font preview panel')
         showPreviewPanel = 0
 
 
@@ -369,7 +369,7 @@
         for j in fontList:
             errorList = errorList + j + '\n'
         errorMessage ='No suitable fixed width font found.\nPlease install at least one of these fixed width fonts:\n'+errorList
-        print errorMessage
+        print (errorMessage)
         raise Exception(errorMessage)
 
 
@@ -391,7 +391,7 @@
         for j in fontList:
             errorList = errorList + j + '\n'
         errorMessage = 'No suitable proportional font found.\nPlease install at least one of these proportional fonts:\n'+errorList
-        print errorMessage
+        print (errorMessage)
         raise Exception(errorMessage)
 
 
@@ -406,10 +406,10 @@
                 'a' : defaultPrefs,
                 'b' : userPrefs
             }
-            cPickle.dump(data, file)
+            pickle.dump(data, file)
             file.close()
         except:
-            print 'failed to save data'
+            print ('failed to save data')
 
 
 def restore_user_conf(path):
@@ -416,13 +416,13 @@
     """Restore the data from the save file on the path specified by CONFIG_PATH."""
     try:
         file = open(os.path.join(path,'fontsampler.conf'), 'r')
-        data = cPickle.load(file)
+        data = pickle.load(file)
         file.close()
         defaultPrefs.update(data['a'])
         userPrefs.update(data['b'])
     except:
         userPrefs.update(defaultPrefs)
-        print 'failed to load saved data so using default values defined in the script'
+        print ('failed to load saved data so using default values defined in the script')
 
 
 def set_page_geometry(dD, geometriesList, paperSize, wantBindingOffset):
@@ -464,7 +464,7 @@
         return result
     except:
         errorMessage = 'set_page_geometry() failure: %s' % sys.exc_info()[1]
-        print errorMessage
+        print (errorMessage)
 
 
 def set_odd_even(pageNum):
@@ -1227,10 +1227,10 @@
         """
         available = self.listbox1.size()
         selected = self.listbox2.size()
-        size = FloatType(selected)
+        size = float(selected)
         blocksPerSheet = draw_selection(scribus.getFontNames(), 1)
         value = size / blocksPerSheet
-        pages = IntType(value)                  # Get whole part of number
+        pages = int(value)                  # Get whole part of number
         value = value - pages                   # Remove whole number part
         if value > 0:                           # Test remainder
             pages = pages + 1                   # Had remainder so add a page
@@ -1241,7 +1241,7 @@
         self.statusPaperSize['text'] = 'Paper size: %s   ' % userPrefs['paperSize']
 
     def __listSelectionToRight(self):
-        toMoveRight = ListType(self.listbox1.curselection())
+        toMoveRight = list(self.listbox1.curselection())
         self.listbox1.selection_clear(0,END)
         toMoveRight.reverse()   # reverse list so we delete from bottom of listbox first
         tempList = []
@@ -1255,13 +1255,13 @@
         self.statusbarUpdate()
 
     def __listSelectionToLeft(self):
-        toMoveLeft = ListType(self.listbox2.curselection())
+        toMoveLeft = list(self.listbox2.curselection())
         toMoveLeft.reverse()
         self.listbox2.selection_clear(0,END)
         for i in toMoveLeft:
             self.listbox1.insert(END, self.listbox2.get(i)) # Insert it at the end
             self.listbox2.delete(i)
-        fontList = ListType(self.listbox1.get(0, END))      # Copy contents to a list type
+        fontList = list(self.listbox1.get(0, END))      # Copy contents to a list type
         self.listbox1.delete(0, END)                        # Remove all contents
         fontList.sort()                                     # Use sort method of list
         for j in fontList:
@@ -1508,7 +1508,7 @@
 
 
 def setup_tk():
-    """Create and setup the Tkinter app."""
+    """Create and setup the tkinter app."""
     root = Tk()
     app = Application(root)
     app.master.title(WINDOW_TITLE)
@@ -1540,7 +1540,7 @@
     restore_user_conf(CONFIG_PATH)
     # get and set the initial paper size to match default radiobutton selection...
     dD.update(set_page_geometry(dD, geometriesList, userPrefs['paperSize'], userPrefs['wantBindingOffset']))
-    # Made it this far so its time to create our Tkinter app...
+    # Made it this far so its time to create our tkinter app...
     app = setup_tk()
     # now show the main window and wait for user to do something...
     app.mainloop()
Index: scribus/plugins/scriptplugin/scripts/importcsv2table.py
===================================================================
--- scribus/plugins/scriptplugin/scripts/importcsv2table.py	(revision 23269)
+++ scribus/plugins/scriptplugin/scripts/importcsv2table.py	(working copy)
@@ -73,8 +73,8 @@
     # as commonly used constants.
     import scribus
 except ImportError,err:
-    print "This Python script is written for the Scribus scripting interface."
-    print "It can only be run from within Scribus."
+    print ("This Python script is written for the Scribus scripting interface.")
+    print ("It can only be run from within Scribus.")
     sys.exit(1)
 
 #########################
Index: scribus/plugins/scriptplugin/scripts/InfoBox.py
===================================================================
--- scribus/plugins/scriptplugin/scripts/InfoBox.py	(revision 23269)
+++ scribus/plugins/scriptplugin/scripts/InfoBox.py	(working copy)
@@ -60,8 +60,8 @@
 try:
     import scribus
 except ImportError:
-    print "Unable to import the 'scribus' module. This script will only run within"
-    print "the Python interpreter embedded in Scribus. Try Script->Execute Script."
+    print ("Unable to import the 'scribus' module. This script will only run within")
+    print ("the Python interpreter embedded in Scribus. Try Script->Execute Script.")
     sys.exit(1)
 
 def main(argv):
@@ -116,7 +116,7 @@
                                          str(o_cols) + ')?','1')
             column_pos = int(column_pos) - 1 
     if (o_cols == 1):
-	columns_width = 1
+        columns_width = 1
     new_height = 0
     while (new_height <= 0):
         new_height = scribus.valueDialog('Height','Your frame height is '+ str(o_height) +
Index: win32/msvc2015/scriptplugin/scriptplugin.vcxproj
===================================================================
--- win32/msvc2015/scriptplugin/scriptplugin.vcxproj	(revision 23269)
+++ win32/msvc2015/scriptplugin/scriptplugin.vcxproj	(working copy)
@@ -95,7 +95,7 @@
   <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
     <ClCompile>
       <Optimization>Disabled</Optimization>
-      <AdditionalIncludeDirectories>..;..\..\..\scribus;..\..\..\scribus\ui;$(QT5_DIR)\include\QtCore;$(QT5_DIR)\include\QtGui;$(QT5_DIR)\include\QtNetwork;$(QT5_DIR)\include\QtWidgets;$(QT5_DIR)\include\QtWebKit;$(QT5_DIR)\include\QtWebKitWidgets;$(QT5_DIR)\include\QtXml;$(QT5_DIR)\include;$(CAIRO_INCLUDE_DIR);$(FREETYPE_INCLUDE_DIR);$(ICU_INCLUDE_DIR);$(LCMS_INCLUDE_DIR);$(LIBJPEG_INCLUDE_DIR);$(LIBTIFF_INCLUDE_DIR);$(PYTHON_INCLUDE_DIR);%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+      <AdditionalIncludeDirectories>..;..\..\..\scribus;..\..\..\scribus\ui;$(QT5_DIR)\include\QtCore;$(QT5_DIR)\include\QtGui;$(QT5_DIR)\include\QtNetwork;$(QT5_DIR)\include\QtWidgets;$(QT5_DIR)\include\QtWebKit;$(QT5_DIR)\include\QtWebKitWidgets;$(QT5_DIR)\include\QtXml;$(QT5_DIR)\include;$(CAIRO_INCLUDE_DIR);$(FREETYPE_INCLUDE_DIR);$(ICU_INCLUDE_DIR);$(LCMS_INCLUDE_DIR);$(LIBJPEG_INCLUDE_DIR);$(LIBTIFF_INCLUDE_DIR);$(PYTHON3_INCLUDE_DIR);%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
       <PreprocessorDefinitions>WIN32;_DEBUG;_USE_MATH_DEFINES;_USRDLL;_WINDOWS;QT_DLL;QT_GUI_LIB;QT_CORE_LIB;QT_THREAD_SUPPORT;COMPILE_PLUGIN_AS_DLL;AVOID_WIN32_FILEIO;%(PreprocessorDefinitions)</PreprocessorDefinitions>
       <MinimalRebuild>true</MinimalRebuild>
       <BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
@@ -109,8 +109,8 @@
       <ForcedIncludeFiles>plugins_pch.h;%(ForcedIncludeFiles)</ForcedIncludeFiles>
     </ClCompile>
     <Link>
-      <AdditionalDependencies>$(QT5CORE_LIB);$(QT5GUI_LIB);$(QT5WIDGETS_LIB);$(QT5XML_LIB);$(FREETYPE_LIB);$(LIBJPEG_LIB);$(LIBTIFF_LIB);$(LCMS_LIB);$(PYTHON_LIB);scribus-api.lib;%(AdditionalDependencies)</AdditionalDependencies>
-      <AdditionalLibraryDirectories>$(LCMS_LIB_DIR);$(FREETYPE_LIB_DIR);$(LIBJPEG_LIB_DIR);$(LIBTIFF_LIB_DIR);$(PYTHON_LIB_DIR)s;$(QT5_DIR)\lib;$(OutDir)..;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
+      <AdditionalDependencies>$(QT5CORE_LIB);$(QT5GUI_LIB);$(QT5WIDGETS_LIB);$(QT5XML_LIB);$(FREETYPE_LIB);$(LIBJPEG_LIB);$(LIBTIFF_LIB);$(LCMS_LIB);$(PYTHON3_LIB);scribus-api.lib;%(AdditionalDependencies)</AdditionalDependencies>
+      <AdditionalLibraryDirectories>$(LCMS_LIB_DIR);$(FREETYPE_LIB_DIR);$(LIBJPEG_LIB_DIR);$(LIBTIFF_LIB_DIR);$(PYTHON3_LIB_DIR)s;$(QT5_DIR)\lib;$(OutDir)..;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
       <GenerateDebugInformation>true</GenerateDebugInformation>
       <SubSystem>Windows</SubSystem>
       <RandomizedBaseAddress>false</RandomizedBaseAddress>
@@ -121,7 +121,7 @@
   <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
     <ClCompile>
       <Optimization>Disabled</Optimization>
-      <AdditionalIncludeDirectories>..;..\..\..\scribus;..\..\..\scribus\ui;$(QT5_DIR)\include\QtCore;$(QT5_DIR)\include\QtGui;$(QT5_DIR)\include\QtNetwork;$(QT5_DIR)\include\QtWidgets;$(QT5_DIR)\include\QtWebKit;$(QT5_DIR)\include\QtWebKitWidgets;$(QT5_DIR)\include\QtXml;$(QT5_DIR)\include;$(CAIRO_INCLUDE_DIR);$(FREETYPE_INCLUDE_DIR);$(ICU_INCLUDE_DIR);$(LCMS_INCLUDE_DIR);$(LIBJPEG_INCLUDE_DIR);$(LIBTIFF_INCLUDE_DIR);$(PYTHON_INCLUDE_DIR);%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+      <AdditionalIncludeDirectories>..;..\..\..\scribus;..\..\..\scribus\ui;$(QT5_DIR)\include\QtCore;$(QT5_DIR)\include\QtGui;$(QT5_DIR)\include\QtNetwork;$(QT5_DIR)\include\QtWidgets;$(QT5_DIR)\include\QtWebKit;$(QT5_DIR)\include\QtWebKitWidgets;$(QT5_DIR)\include\QtXml;$(QT5_DIR)\include;$(CAIRO_INCLUDE_DIR);$(FREETYPE_INCLUDE_DIR);$(ICU_INCLUDE_DIR);$(LCMS_INCLUDE_DIR);$(LIBJPEG_INCLUDE_DIR);$(LIBTIFF_INCLUDE_DIR);$(PYTHON3_INCLUDE_DIR);%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
       <PreprocessorDefinitions>WIN32;_DEBUG;_USE_MATH_DEFINES;_USRDLL;_WINDOWS;QT_DLL;QT_GUI_LIB;QT_CORE_LIB;QT_THREAD_SUPPORT;COMPILE_PLUGIN_AS_DLL;AVOID_WIN32_FILEIO;%(PreprocessorDefinitions)</PreprocessorDefinitions>
       <BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
       <RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
@@ -134,8 +134,8 @@
       <ForcedIncludeFiles>plugins_pch.h;%(ForcedIncludeFiles)</ForcedIncludeFiles>
     </ClCompile>
     <Link>
-      <AdditionalDependencies>$(QT5CORE_LIB);$(QT5GUI_LIB);$(QT5WIDGETS_LIB);$(QT5XML_LIB);$(FREETYPE_LIB);$(LIBJPEG_LIB);$(LIBTIFF_LIB);$(LCMS_LIB);$(PYTHON_LIB);scribus-api.lib;%(AdditionalDependencies)</AdditionalDependencies>
-      <AdditionalLibraryDirectories>$(LCMS_LIB_DIR);$(FREETYPE_LIB_DIR);$(LIBJPEG_LIB_DIR);$(LIBTIFF_LIB_DIR);$(PYTHON_LIB_DIR)s;$(QT5_DIR)\lib;$(OutDir)..;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
+      <AdditionalDependencies>$(QT5CORE_LIB);$(QT5GUI_LIB);$(QT5WIDGETS_LIB);$(QT5XML_LIB);$(FREETYPE_LIB);$(LIBJPEG_LIB);$(LIBTIFF_LIB);$(LCMS_LIB);$(PYTHON3_LIB);scribus-api.lib;%(AdditionalDependencies)</AdditionalDependencies>
+      <AdditionalLibraryDirectories>$(LCMS_LIB_DIR);$(FREETYPE_LIB_DIR);$(LIBJPEG_LIB_DIR);$(LIBTIFF_LIB_DIR);$(PYTHON3_LIB_DIR)s;$(QT5_DIR)\lib;$(OutDir)..;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
       <GenerateDebugInformation>true</GenerateDebugInformation>
       <SubSystem>Windows</SubSystem>
       <RandomizedBaseAddress>false</RandomizedBaseAddress>
@@ -148,7 +148,7 @@
       <Optimization>MinSpace</Optimization>
       <InlineFunctionExpansion>OnlyExplicitInline</InlineFunctionExpansion>
       <OmitFramePointers>true</OmitFramePointers>
-      <AdditionalIncludeDirectories>..;..\..\..\scribus;..\..\..\scribus\ui;$(QT5_DIR)\include\QtCore;$(QT5_DIR)\include\QtGui;$(QT5_DIR)\include\QtNetwork;$(QT5_DIR)\include\QtWidgets;$(QT5_DIR)\include\QtWebKit;$(QT5_DIR)\include\QtWebKitWidgets;$(QT5_DIR)\include\QtXml;$(QT5_DIR)\include;$(CAIRO_INCLUDE_DIR);$(FREETYPE_INCLUDE_DIR);$(ICU_INCLUDE_DIR);$(LCMS_INCLUDE_DIR);$(LIBJPEG_INCLUDE_DIR);$(LIBTIFF_INCLUDE_DIR);$(PYTHON_INCLUDE_DIR);%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+      <AdditionalIncludeDirectories>..;..\..\..\scribus;..\..\..\scribus\ui;$(QT5_DIR)\include\QtCore;$(QT5_DIR)\include\QtGui;$(QT5_DIR)\include\QtNetwork;$(QT5_DIR)\include\QtWidgets;$(QT5_DIR)\include\QtWebKit;$(QT5_DIR)\include\QtWebKitWidgets;$(QT5_DIR)\include\QtXml;$(QT5_DIR)\include;$(CAIRO_INCLUDE_DIR);$(FREETYPE_INCLUDE_DIR);$(ICU_INCLUDE_DIR);$(LCMS_INCLUDE_DIR);$(LIBJPEG_INCLUDE_DIR);$(LIBTIFF_INCLUDE_DIR);$(PYTHON3_INCLUDE_DIR);%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
       <PreprocessorDefinitions>WIN32;NDEBUG;_USE_MATH_DEFINES;_USRDLL;_WINDOWS;QT_DLL;QT_GUI_LIB;QT_CORE_LIB;QT_THREAD_SUPPORT;COMPILE_PLUGIN_AS_DLL;AVOID_WIN32_FILEIO;%(PreprocessorDefinitions)</PreprocessorDefinitions>
       <StringPooling>true</StringPooling>
       <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
@@ -162,8 +162,8 @@
       <ForcedIncludeFiles>plugins_pch.h;%(ForcedIncludeFiles)</ForcedIncludeFiles>
     </ClCompile>
     <Link>
-      <AdditionalDependencies>$(QT5CORE_LIB);$(QT5GUI_LIB);$(QT5WIDGETS_LIB);$(QT5XML_LIB);$(FREETYPE_LIB);$(LIBJPEG_LIB);$(LIBTIFF_LIB);$(LCMS_LIB);$(PYTHON_LIB);scribus-api.lib;%(AdditionalDependencies)</AdditionalDependencies>
-      <AdditionalLibraryDirectories>$(LCMS_LIB_DIR);$(FREETYPE_LIB_DIR);$(LIBJPEG_LIB_DIR);$(LIBTIFF_LIB_DIR);$(PYTHON_LIB_DIR)s;$(QT5_DIR)\lib;$(OutDir)..;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
+      <AdditionalDependencies>$(QT5CORE_LIB);$(QT5GUI_LIB);$(QT5WIDGETS_LIB);$(QT5XML_LIB);$(FREETYPE_LIB);$(LIBJPEG_LIB);$(LIBTIFF_LIB);$(LCMS_LIB);$(PYTHON3_LIB);scribus-api.lib;%(AdditionalDependencies)</AdditionalDependencies>
+      <AdditionalLibraryDirectories>$(LCMS_LIB_DIR);$(FREETYPE_LIB_DIR);$(LIBJPEG_LIB_DIR);$(LIBTIFF_LIB_DIR);$(PYTHON3_LIB_DIR)s;$(QT5_DIR)\lib;$(OutDir)..;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
       <GenerateDebugInformation>true</GenerateDebugInformation>
       <SubSystem>Windows</SubSystem>
       <OptimizeReferences>true</OptimizeReferences>
@@ -178,7 +178,7 @@
       <Optimization>MinSpace</Optimization>
       <InlineFunctionExpansion>OnlyExplicitInline</InlineFunctionExpansion>
       <OmitFramePointers>true</OmitFramePointers>
-      <AdditionalIncludeDirectories>..;..\..\..\scribus;..\..\..\scribus\ui;$(QT5_DIR)\include\QtCore;$(QT5_DIR)\include\QtGui;$(QT5_DIR)\include\QtNetwork;$(QT5_DIR)\include\QtWidgets;$(QT5_DIR)\include\QtWebKit;$(QT5_DIR)\include\QtWebKitWidgets;$(QT5_DIR)\include\QtXml;$(QT5_DIR)\include;$(CAIRO_INCLUDE_DIR);$(FREETYPE_INCLUDE_DIR);$(ICU_INCLUDE_DIR);$(LCMS_INCLUDE_DIR);$(LIBJPEG_INCLUDE_DIR);$(LIBTIFF_INCLUDE_DIR);$(PYTHON_INCLUDE_DIR);%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+      <AdditionalIncludeDirectories>..;..\..\..\scribus;..\..\..\scribus\ui;$(QT5_DIR)\include\QtCore;$(QT5_DIR)\include\QtGui;$(QT5_DIR)\include\QtNetwork;$(QT5_DIR)\include\QtWidgets;$(QT5_DIR)\include\QtWebKit;$(QT5_DIR)\include\QtWebKitWidgets;$(QT5_DIR)\include\QtXml;$(QT5_DIR)\include;$(CAIRO_INCLUDE_DIR);$(FREETYPE_INCLUDE_DIR);$(ICU_INCLUDE_DIR);$(LCMS_INCLUDE_DIR);$(LIBJPEG_INCLUDE_DIR);$(LIBTIFF_INCLUDE_DIR);$(PYTHON3_INCLUDE_DIR);%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
       <PreprocessorDefinitions>WIN32;NDEBUG;_USE_MATH_DEFINES;_USRDLL;_WINDOWS;QT_DLL;QT_GUI_LIB;QT_CORE_LIB;QT_THREAD_SUPPORT;COMPILE_PLUGIN_AS_DLL;AVOID_WIN32_FILEIO;%(PreprocessorDefinitions)</PreprocessorDefinitions>
       <StringPooling>true</StringPooling>
       <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
@@ -192,8 +192,8 @@
       <ForcedIncludeFiles>plugins_pch.h;%(ForcedIncludeFiles)</ForcedIncludeFiles>
     </ClCompile>
     <Link>
-      <AdditionalDependencies>$(QT5CORE_LIB);$(QT5GUI_LIB);$(QT5WIDGETS_LIB);$(QT5XML_LIB);$(FREETYPE_LIB);$(LIBJPEG_LIB);$(LIBTIFF_LIB);$(LCMS_LIB);$(PYTHON_LIB);scribus-api.lib;%(AdditionalDependencies)</AdditionalDependencies>
-      <AdditionalLibraryDirectories>$(LCMS_LIB_DIR);$(FREETYPE_LIB_DIR);$(LIBJPEG_LIB_DIR);$(LIBTIFF_LIB_DIR);$(PYTHON_LIB_DIR)s;$(QT5_DIR)\lib;$(OutDir)..;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
+      <AdditionalDependencies>$(QT5CORE_LIB);$(QT5GUI_LIB);$(QT5WIDGETS_LIB);$(QT5XML_LIB);$(FREETYPE_LIB);$(LIBJPEG_LIB);$(LIBTIFF_LIB);$(LCMS_LIB);$(PYTHON3_LIB);scribus-api.lib;%(AdditionalDependencies)</AdditionalDependencies>
+      <AdditionalLibraryDirectories>$(LCMS_LIB_DIR);$(FREETYPE_LIB_DIR);$(LIBJPEG_LIB_DIR);$(LIBTIFF_LIB_DIR);$(PYTHON3_LIB_DIR)s;$(QT5_DIR)\lib;$(OutDir)..;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
       <GenerateDebugInformation>true</GenerateDebugInformation>
       <SubSystem>Windows</SubSystem>
       <OptimizeReferences>true</OptimizeReferences>
