Index: scribus/plugins/scriptplugin/cmdgetsetprop.cpp
===================================================================
--- scribus/plugins/scriptplugin/cmdgetsetprop.cpp	(revision 17900)
+++ scribus/plugins/scriptplugin/cmdgetsetprop.cpp	(working copy)
@@ -18,13 +18,13 @@
 	if (PyString_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)));
-	else if (PyCObject_Check(arg))
+		return getPageItemByName(PyString_AsQString(arg));
+	else if (PyCapsule_CheckExact(arg))
 	{
-		// It's a PyCObject, ie a wrapped pointer. Check it's not NULL
+		// It's a PyCapsule, ie a wrapped pointer. Check it's not NULL
 		// 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, NULL);
 		if (!tempObject)
 		{
 			PyErr_SetString(PyExc_TypeError, "INTERNAL: Passed NULL PyCObject");
@@ -44,7 +44,7 @@
 
 PyObject* wrapQObject(QObject* obj)
 {
-	return PyCObject_FromVoidPtr((void*)obj, NULL);
+	return PyCapsule_New((void*)obj, NULL, NULL);
 }
 
 
@@ -414,7 +414,7 @@
 	{
 		matched = true;
 		if (PyString_Check(objValue))
-			success = obj->setProperty(propertyName, QString::fromUtf8(PyString_AsString(objValue)));
+			success = obj->setProperty(propertyName, PyString_AsQString(objValue));
 		else if (PyUnicode_Check(objValue))
 		{
 			// Get a pointer to the internal buffer of the Py_Unicode object, which is UCS2 formatted
@@ -432,7 +432,7 @@
 		{
 			// 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 = PyString_AsQString(objValue);
 			success = obj->setProperty(propertyName, utfString.toAscii());
 		}
 		else if (PyUnicode_Check(objValue))
@@ -465,7 +465,7 @@
 		if (!objRepr)
 			return NULL;
 		// Extract the repr() string
-		QString reprString = QString::fromUtf8(PyString_AsString(objRepr));
+		QString reprString = PyString_AsQString(objRepr);
 		Py_DECREF(objRepr);
 
 		// And return an error
Index: scribus/plugins/scriptplugin/cmdmani.cpp
===================================================================
--- scribus/plugins/scriptplugin/cmdmani.cpp	(revision 17900)
+++ scribus/plugins/scriptplugin/cmdmani.cpp	(working copy)
@@ -354,7 +354,6 @@
 
 PyObject *scribus_groupobj(PyObject* /* self */, PyObject* args)
 {
-	char *Name = const_cast<char*>("");
 	PyObject *il = 0;
 	if (!PyArg_ParseTuple(args, "|O", &il))
 		return NULL;
@@ -378,8 +377,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));
-			PageItem *ic = GetUniqueItem(QString::fromUtf8(Name));
+			PageItem *ic = GetUniqueItem(PyString_AsQString(PyList_GetItem(il, i)));
 			if (ic == NULL)
 			{
 				delete tempSelection;
Index: scribus/plugins/scriptplugin/cmdvar.h
===================================================================
--- scribus/plugins/scriptplugin/cmdvar.h	(revision 17900)
+++ scribus/plugins/scriptplugin/cmdvar.h	(working copy)
@@ -36,7 +36,46 @@
 
 #include "scribus.h"
 
+#if PY_MAJOR_VERSION >= 3
+	#define PyString_Check PyUnicode_Check
+	#ifdef PyUnicode_GET_LENGTH
+		#define PyString_Size PyUnicode_GET_LENGTH
+	#else
+		#define PyString_Size PyUnicode_GET_SIZE
+	#endif
+	#define PyString_FromString PyUnicode_FromString
+	#define PyString_FromStringAndSize PyUnicode_FromStringAndSize
+	inline QString PyString_AsQString(PyObject *arg) {
+		PyObject *tmp = PyUnicode_AsUTF8String(arg);
+		QString qs = QString::fromUtf8(PyBytes_AsString(tmp));
+		Py_DECREF(tmp);
+		return qs;
+	}
+	#define PyInt_Check PyLong_Check
+	#define PyInt_FromLong PyLong_FromLong
+	#define PyInt_AsLong PyLong_AsLong
+	#if PY_MINOR_VERSION == 0
+		#define PyCapsule_Type PyCObject_Type
+		#define PyCapsule_CheckExact(capsule) PyCObject_Check(capsule)
+		#define PyCapsule_New(pointer, name, destructor) PyCObject_FromVoidPtr(pointer, destructor)
+		#define PyCapsule_GetPointer(capsule, name) PyCObject_AsVoidPtr(capsule)
+	#endif
+#else
+	#define PyString_AsQString(arg) QString::fromUtf8(PyString_AsString((arg)))
+	#if PY_MINOR_VERSION < 7
+		#define PyCapsule_Type PyCObject_Type
+		#define PyCapsule_CheckExact(capsule) PyCObject_Check(capsule)
+		#define PyCapsule_New(pointer, name, destructor) PyCObject_FromVoidPtr(pointer, destructor)
+		#define PyCapsule_GetPointer(capsule, name) PyCObject_AsVoidPtr(capsule)
 
+		#if PY_MINOR_VERSION <= 5
+			#define PyVarObject_HEAD_INIT(type, size) PyObject_HEAD_INIT(type) size,
+			#define Py_TYPE(ob) (((PyObject*)(ob))->ob_type)
+		#endif
+	#endif
+#endif
+
+
 class ScripterCore;
 
 // Globals for testing Qt properties and probably other more intresting future
Index: scribus/plugins/scriptplugin/objimageexport.cpp
===================================================================
--- scribus/plugins/scriptplugin/objimageexport.cpp	(revision 17900)
+++ scribus/plugins/scriptplugin/objimageexport.cpp	(working copy)
@@ -32,7 +32,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*/)
@@ -154,11 +154,22 @@
 	int dpi = qRound(100.0 / 2.54 * self->dpi);
 	im.setDotsPerMeterY(dpi);
 	im.setDotsPerMeterX(dpi);
+#if PY_MAJOR_VERSION >= 3
+	PyObject *type = PyUnicode_AsUTF8String(self->type);
+	if (!im.save(PyString_AsQString(self->name), PyBytes_AsString(type)))
+	{
+	        Py_DECREF(type);
+		PyErr_SetString(ScribusException, QObject::tr("Failed to export image", "python error").toLocal8Bit().constData());
+		return NULL;
+	}
+        Py_DECREF(type);
+#else
 	if (!im.save(PyString_AsString(self->name), PyString_AsString(self->type)))
 	{
 		PyErr_SetString(ScribusException, QObject::tr("Failed to export image", "python error").toLocal8Bit().constData());
 		return NULL;
 	}
+#endif
 // 	Py_INCREF(Py_True); // return True not None for backward compat
  //	return Py_True;
 //	Py_RETURN_TRUE;
@@ -185,11 +196,22 @@
 	int dpi = qRound(100.0 / 2.54 * self->dpi);
 	im.setDotsPerMeterY(dpi);
 	im.setDotsPerMeterX(dpi);
+#if PY_MAJOR_VERSION >= 3
+	PyObject *type = PyUnicode_AsUTF8String(self->type);
+	if (!im.save(value, PyBytes_AsString(type)))
+	{
+	        Py_DECREF(type);
+		PyErr_SetString(ScribusException, QObject::tr("Failed to export image", "python error").toLocal8Bit().constData());
+		return NULL;
+	}
+        Py_DECREF(type);
+#else
 	if (!im.save(value, PyString_AsString(self->type)))
 	{
 		PyErr_SetString(ScribusException, QObject::tr("Failed to export image", "python error").toLocal8Bit().constData());
 		return NULL;
 	}
+#endif
 // 	Py_INCREF(Py_True); // return True not None for backward compat
  //	return Py_True;
 //	Py_RETURN_TRUE;
@@ -203,8 +225,7 @@
 };
 
 PyTypeObject ImageExport_Type = {
-	PyObject_HEAD_INIT(NULL)   // PyObject_VAR_HEAD
-	0,
+	PyVarObject_HEAD_INIT(NULL, 0)   // PyObject_VAR_HEAD
 	const_cast<char*>("ImageExport"), // char *tp_name; /* For printing, in format "<module>.<name>" */
 	sizeof(ImageExport),   // int tp_basicsize, /* For allocation */
 	0,  // int tp_itemsize; /* For allocation */
Index: scribus/plugins/scriptplugin/objpdffile.cpp
===================================================================
--- scribus/plugins/scriptplugin/objpdffile.cpp	(revision 17900)
+++ scribus/plugins/scriptplugin/objpdffile.cpp	(working copy)
@@ -111,7 +111,7 @@
 	Py_XDECREF(self->imagepr);
 	Py_XDECREF(self->printprofc);
 	Py_XDECREF(self->info);
-	self->ob_type->tp_free((PyObject *)self);
+	Py_TYPE(self)->tp_free((PyObject *)self);
 }
 
 static PyObject * PDFfile_new(PyTypeObject *type, PyObject * /*args*/, PyObject * /*kwds*/)
@@ -1010,12 +1010,12 @@
 	int n = PyList_Size(self->fonts);
 	for ( int i=0; i<n; ++i){
 		QString tmpFon;
-		tmpFon = QString(PyString_AsString(PyList_GetItem(self->fonts, i)));
+		tmpFon = PyString_AsQString(PyList_GetItem(self->fonts, i));
 		ScCore->primaryMainWindow()->doc->pdfOptions().EmbedList.append(tmpFon);
 	}
 // apply file attribute
 	QString fn;
-	fn = QString(PyString_AsString(self->file));
+	fn = PyString_AsQString(self->file);
 	ScCore->primaryMainWindow()->doc->pdfOptions().fileName = fn;
 // apply pages attribute
 	std::vector<int> pageNs;
@@ -1107,7 +1107,7 @@
 //		 }
 //		 ScCore->primaryMainWindow()->doc->pdfOptions().LPISettings[QString(s)]=lpi;
 		QString st;
-		st = QString(PyString_AsString(PyList_GetItem(t,0)));
+		st = PyString_AsQString(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));
@@ -1136,8 +1136,8 @@
 		if (self->aanot)
 			Perm += 32;
 		ScCore->primaryMainWindow()->doc->pdfOptions().Permissions = Perm;
-		ScCore->primaryMainWindow()->doc->pdfOptions().PassOwner = QString(PyString_AsString(self->owner));
-		ScCore->primaryMainWindow()->doc->pdfOptions().PassUser = QString(PyString_AsString(self->user));
+		ScCore->primaryMainWindow()->doc->pdfOptions().PassOwner = PyString_AsQString(self->owner);
+		ScCore->primaryMainWindow()->doc->pdfOptions().PassUser = PyString_AsQString(self->user);
 	}
 	if (self->outdst == 0)
 	{
@@ -1157,9 +1157,9 @@
 			self->intenti = minmaxi(self->intenti, 0, 3);
 			ScCore->primaryMainWindow()->doc->pdfOptions().Intent2 = self->intenti;
 			ScCore->primaryMainWindow()->doc->pdfOptions().EmbeddedI = self->noembicc;
-			ScCore->primaryMainWindow()->doc->pdfOptions().SolidProf = PyString_AsString(self->solidpr);
-			ScCore->primaryMainWindow()->doc->pdfOptions().ImageProf = PyString_AsString(self->imagepr);
-			ScCore->primaryMainWindow()->doc->pdfOptions().PrintProf = PyString_AsString(self->printprofc);
+			ScCore->primaryMainWindow()->doc->pdfOptions().SolidProf = PyString_AsQString(self->solidpr);
+			ScCore->primaryMainWindow()->doc->pdfOptions().ImageProf = PyString_AsQString(self->imagepr);
+			ScCore->primaryMainWindow()->doc->pdfOptions().PrintProf = PyString_AsQString(self->printprofc);
 			if (ScCore->primaryMainWindow()->doc->pdfOptions().Version == PDFOptions::PDFVersion_X3)
 			{
 				ScColorProfile profile;
@@ -1171,7 +1171,7 @@
 					Components = 4;
 				if (profile.colorSpace() == ColorSpace_Cmy)
 					Components = 3;
-				ScCore->primaryMainWindow()->doc->pdfOptions().Info = PyString_AsString(self->info);
+				ScCore->primaryMainWindow()->doc->pdfOptions().Info = PyString_AsQString(self->info);
 				self->bleedt = minmaxd(self->bleedt, 0, ScCore->primaryMainWindow()->view->Doc->pageHeight()*ScCore->primaryMainWindow()->view->Doc->unitRatio());
 				ScCore->primaryMainWindow()->doc->pdfOptions().bleeds.Top = self->bleedt/ScCore->primaryMainWindow()->view->Doc->unitRatio();
 				self->bleedl = minmaxd(self->bleedl, 0, ScCore->primaryMainWindow()->view->Doc->pageWidth()*ScCore->primaryMainWindow()->view->Doc->unitRatio());
@@ -1219,8 +1219,7 @@
 };
 
 PyTypeObject PDFfile_Type = {
-	PyObject_HEAD_INIT(NULL) // PyObject_VAR_HEAD
-	0,		      //
+	PyVarObject_HEAD_INIT(NULL, 0) // PyObject_VAR_HEAD
 	const_cast<char*>("PDFfile"), // char *tp_name; /* For printing, in format "<module>.<name>" */
 	sizeof(PDFfile),     // int tp_basicsize, /* For allocation */
 	0,		    // int tp_itemsize; /* For allocation */
Index: scribus/plugins/scriptplugin/objprinter.cpp
===================================================================
--- scribus/plugins/scriptplugin/objprinter.cpp	(revision 17900)
+++ scribus/plugins/scriptplugin/objprinter.cpp	(working copy)
@@ -62,7 +62,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*/)
@@ -407,16 +407,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")) ? true : false;
+	prn = PyString_AsQString(self->printer);
+	fna = PyString_AsQString(self->file);
+	fil = (PyString_AsQString(self->printer) == QString("File")) ? true : false;
 	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)));
 	}
 	int Nr = (self->copies < 1) ? 1 : self->copies;
-	SepName = QString(PyString_AsString(self->separation));
+	SepName = PyString_AsQString(self->separation);
 	options.printer   = prn;
 	options.prnEngine = (PrintEngine) self->pslevel;
 	options.toFile    = fil;
@@ -438,7 +438,7 @@
 	options.bleeds.Bottom = 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 = PyString_AsQString(self->cmd);
 	QMap<QString, QMap<uint, FPointArray> > ReallyUsed;
 	ReallyUsed.clear();
 	ScCore->primaryMainWindow()->doc->getUsedFonts(ReallyUsed);
@@ -527,8 +527,7 @@
 };
 
 PyTypeObject Printer_Type = {
-	PyObject_HEAD_INIT(NULL)   // PyObject_VAR_HEAD
-	0,			 //
+	PyVarObject_HEAD_INIT(NULL, 0)   // PyObject_VAR_HEAD
 	const_cast<char*>("Printer"), // char *tp_name; /* For printing, in format "<module>.<name>" */
 	sizeof(Printer),   // int tp_basicsize, /* For allocation */
 	0,		       // int tp_itemsize; /* For allocation */
Index: scribus/plugins/scriptplugin/scriptercore.cpp
===================================================================
--- scribus/plugins/scriptplugin/scriptercore.cpp	(revision 17900)
+++ scribus/plugins/scriptplugin/scriptercore.cpp	(working copy)
@@ -253,7 +253,6 @@
 
 	PyThreadState *state = NULL;
 	QFileInfo fi(fileName);
-	QByteArray na = fi.fileName().toLocal8Bit();
 	// Set up a sub-interpreter if needed:
 	PyThreadState* global_state = NULL;
 	if (!inMainInterpreter)
@@ -272,8 +271,21 @@
 		// Init the scripter module in the sub-interpreter
 		initscribus(ScCore->primaryMainWindow());
 	}
+#if PY_MAJOR_VERSION >= 3
 	// Make sure sys.argv[0] is the path to the script
+	wchar_t* comm[2];
+	std::wstring na = fi.fileName().toStdWString();
+	comm[0] = const_cast<wchar_t*>(na.c_str());
+	// and tell the script if it's running in the main intepreter or
+	// a subinterpreter using the second argument, ie sys.argv[1]
+	if (inMainInterpreter)
+		comm[1] = const_cast<wchar_t*>(L"ext");
+	else
+		comm[1] = const_cast<wchar_t*>(L"sub");
+#else
+	// Make sure sys.argv[0] is the path to the script
 	char* comm[2];
+	QByteArray na = fi.fileName().toLocal8Bit();
 	comm[0] = na.data();
 	// and tell the script if it's running in the main intepreter or
 	// a subinterpreter using the second argument, ie sys.argv[1]
@@ -281,6 +293,7 @@
 		comm[1] = const_cast<char*>("ext");
 	else
 		comm[1] = const_cast<char*>("sub");
+#endif
 	PySys_SetArgv(2, comm);
 	// call python script
 	PyObject* m = PyImport_AddModule((char*)"__main__");
@@ -344,7 +357,7 @@
 			}
 			else
 			{
-				QString errorMsg = PyString_AsString(errorMsgPyStr);
+				QString errorMsg = PyString_AsQString(errorMsgPyStr);
 				// Display a dialog to the user with the exception
 				QClipboard *cp = QApplication::clipboard();
 				cp->setText(errorMsg);
Index: scribus/plugins/scriptplugin/scriptplugin.cpp
===================================================================
--- scribus/plugins/scriptplugin/scriptplugin.cpp	(revision 17900)
+++ scribus/plugins/scriptplugin/scriptplugin.cpp	(working copy)
@@ -171,11 +171,13 @@
 	}
 #endif
 	Py_Initialize();
+#if PY_MAJOR_VERSION < 3
 	if (PyUnicode_SetDefaultEncoding("utf-8"))
 	{
 		qDebug("Failed to set default encoding to utf-8.\n");
 		PyErr_Clear();
 	}
+#endif
 
 	scripterCore = new ScripterCore(ScCore->primaryMainWindow());
 	Q_CHECK_PTR(scripterCore);
@@ -564,6 +566,21 @@
 	{NULL, (PyCFunction)(0), 0, NULL} /* sentinel */
 };
 
+#if PY_MAJOR_VERSION >= 3
+static struct PyModuleDef moduledef = {
+	PyModuleDef_HEAD_INIT,
+	"scribus",           /* m_name */
+	NULL,                /* m_doc */
+	-1,                  /* m_size */
+	scribus_methods,     /* m_methods */
+	NULL,                /* m_reload */
+	NULL,                /* m_traverse */
+	NULL,                /* m_clear */
+	NULL,                /* m_free */
+};
+#endif
+
+
 void initscribus_failed(const char* fileName, int lineNo)
 {
 	qDebug("Scripter setup failed (%s:%i)", fileName, lineNo);
@@ -585,7 +602,11 @@
 	PyType_Ready(&Printer_Type);
 	PyType_Ready(&PDFfile_Type);
 	PyType_Ready(&ImageExport_Type);
+#if PY_MAJOR_VERSION >= 3
+	m = PyModule_Create(&moduledef);
+#else
 	m = Py_InitModule((char*)"scribus", scribus_methods);
+#endif
 	Py_INCREF(&Printer_Type);
 	PyModule_AddObject(m, (char*)"Printer", (PyObject *) &Printer_Type);
 	Py_INCREF(&PDFfile_Type);
