[Rpm-maint] [PATCH 15/15] Hack up various dark corners so that they compile with Python 3

David Malcolm dmalcolm at redhat.com
Thu Oct 15 19:15:09 UTC 2009


---
 python/rpmds-py.c  |    3 +++
 python/rpmfd-py.c  |   23 +++++++++++++++++++++--
 python/rpmmodule.c |    3 +++
 python/rpmts-py.c  |    7 +++++++
 4 files changed, 34 insertions(+), 2 deletions(-)

diff --git a/python/rpmds-py.c b/python/rpmds-py.c
index f45c908..1b091f9 100644
--- a/python/rpmds-py.c
+++ b/python/rpmds-py.c
@@ -473,7 +473,10 @@ PyTypeObject rpmds_Type = {
 	PyObject_GenericSetAttr,	/* tp_setattro */
 	0,				/* tp_as_buffer */
 	Py_TPFLAGS_DEFAULT |		/* tp_flags */
+#if PY_MAJOR_VERSION < 3
+            /* FIXME: doublecheck this flag */
 	    Py_TPFLAGS_HAVE_RICHCOMPARE |
+#endif
 	    Py_TPFLAGS_BASETYPE,
 	rpmds_doc,			/* tp_doc */
 	0,				/* tp_traverse */
diff --git a/python/rpmfd-py.c b/python/rpmfd-py.c
index 97cd100..837cea5 100644
--- a/python/rpmfd-py.c
+++ b/python/rpmfd-py.c
@@ -9,12 +9,15 @@ int rpmFdFromPyObject(PyObject *obj, FD_t *fdp)
 
     if (PyInt_Check(obj)) {
 	fd = fdDup(PyInt_AsLong(obj));
+/* FIXME: still need to port this block to Py3k */
+#if PY_MAJOR_VERSION < 3
     } else if (PyFile_Check(obj)) {
 	FILE *fp = PyFile_AsFile(obj);
 	fd = fdDup(fileno(fp));
     } else {
 	PyErr_SetString(PyExc_TypeError, "integer or file object expected");
 	return 0;
+#endif
     }
     if (Ferror(fd)) {
 	PyErr_SetString(PyExc_IOError, Fstrerror(fd));
@@ -51,12 +54,28 @@ static PyObject *rpmfd_new(PyTypeObject *subtype,
 				     &fo, &mode, &flags))
 	return NULL;
 
-    if (PyString_Check(fo)) {
+#if PY_MAJOR_VERSION >= 3
+    /* Handle py3k unicode objects by decoding using default FS encoding */
+    if (PyUnicode_Check(fo)) {
+	PyObject *fs_encoded_bytes = NULL;
+	if (PyUnicode_FSConverter(fo, &fs_encoded_bytes)) {
 	char *m = rstrscat(NULL, mode, ".", flags, NULL);
 	Py_BEGIN_ALLOW_THREADS 
-	fd = Fopen(PyString_AsString(fo), m);
+	fd = Fopen(PyBytes_AsString(fo), m);
 	Py_END_ALLOW_THREADS 
 	free(m);
+	Py_DECREF(fs_encoded_bytes);
+      } else {
+	return NULL;
+      }
+#else
+    if (PyBytes_Check(fo)) {
+	char *m = rstrscat(NULL, mode, ".", flags, NULL);
+	Py_BEGIN_ALLOW_THREADS 
+	fd = Fopen(PyBytes_AsString(fo), m);
+	Py_END_ALLOW_THREADS 
+	free(m);
+#endif
     } else if (!rpmFdFromPyObject(fo, &fd)) {
 	return NULL;
     }
diff --git a/python/rpmmodule.c b/python/rpmmodule.c
index e0aeddc..c281db1 100644
--- a/python/rpmmodule.c
+++ b/python/rpmmodule.c
@@ -64,6 +64,8 @@ static PyObject * setLogFile (PyObject * self, PyObject * args, PyObject *kwds)
     if (!PyArg_ParseTupleAndKeywords(args, kwds, "|O:logSetFile", kwlist, &fop))
 	return NULL;
 
+/* FIXME: still need to port this block to Py3k */
+#if PY_MAJOR_VERSION < 3
     if (fop) {
 	if (!PyFile_Check(fop)) {
 	    PyErr_SetString(PyExc_TypeError, "requires file object");
@@ -71,6 +73,7 @@ static PyObject * setLogFile (PyObject * self, PyObject * args, PyObject *kwds)
 	}
 	fp = PyFile_AsFile(fop);
     }
+#endif
 
     (void) rpmlogSetFile(fp);
 
diff --git a/python/rpmts-py.c b/python/rpmts-py.c
index cc0ed00..3633d61 100644
--- a/python/rpmts-py.c
+++ b/python/rpmts-py.c
@@ -159,7 +159,14 @@ static void die(PyObject *cb)
 	PyErr_Print();
     }
     if ((r = PyObject_Repr(cb)) != NULL) { 
+#if PY_MAJOR_VERSION >= 3
+	/* FIXME: this is making assumptions about the encoding of stderr.*/
+	PyObject *utf8_bytes = PyUnicode_AsUTF8String(r);
+        pyfn = PyBytes_AsString(utf8_bytes);
+	Py_XDECREF(utf8_bytes);
+#else
 	pyfn = PyString_AsString(r);
+#endif
     }
     fprintf(stderr, _("error: python callback %s failed, aborting!\n"), 
 	    	      pyfn ? pyfn : "???");
-- 
1.6.2.5



More information about the Rpm-maint mailing list