diff mbox

i2c-tools: add compatibility for python2/3 to py-smbus

Message ID CA+TH9VkT1K2aqAuNOLsGiU407OA4NYcMVaUakEQgSWLpMBBg2A@mail.gmail.com
State Awaiting Upstream
Headers show

Commit Message

Angelo Compagnucci Jan. 19, 2015, 3:13 p.m. UTC
Dear Jean Delvare,

Attached you can find a patch that implements py-smbus for python3
with python2 backward compatibility.
This patch is not heavily tested, but it wors well for me.

Unfortunately, I don't know how to use svn for sharing source code, it
is so ugly compared to git and it doesn't provide a way to send
patches via email, so the best way I found was to attach the patch
file.

Hope this helps!

Sincerely, Angelo
diff mbox

Patch

Index: smbusmodule.c
===================================================================
diff --git a/i2c-tools/trunk/py-smbus/smbusmodule.c b/i2c-tools/trunk/py-smbus/smbusmodule.c
--- a/i2c-tools/trunk/py-smbus/smbusmodule.c	(revision 6261)
+++ b/i2c-tools/trunk/py-smbus/smbusmodule.c	(working copy)
@@ -18,14 +18,16 @@ 
 
 #include <Python.h>
 #include "structmember.h"
-#include <sys/ioctl.h>
 #include <stdlib.h>
 #include <stdio.h>
 #include <fcntl.h>
-#include <linux/i2c.h>
 #include <linux/i2c-dev.h>
-#include <i2c/smbus.h>
 
+/* Required for backward compatibility with python 2*/
+#if PY_MAJOR_VERSION >= 3
+#define PY3
+#endif
+
 /*
 ** These are required to build this module against Linux older than 2.6.23.
 */
@@ -35,6 +37,7 @@ 
 #define I2C_SMBUS_I2C_BLOCK_DATA	8
 #endif
 
+#ifndef PY3
 PyDoc_STRVAR(SMBus_module_doc,
 	"This module defines an object type that allows SMBus transactions\n"
 	"on hosts running the Linux kernel.  The host kernel must have I2C\n"
@@ -44,6 +47,7 @@ 
 	"\n"
 	"Because the I2C device interface is opened R/W, users of this\n"
 	"module usually must have root permissions.\n");
+#endif
 
 typedef struct {
 	PyObject_HEAD
@@ -94,7 +98,11 @@ 
 	PyObject *ref = SMBus_close(self);
 	Py_XDECREF(ref);
 
+#ifndef PY3
 	self->ob_type->tp_free((PyObject *)self);
+#else
+	Py_TYPE(self)->tp_free((PyObject *)self);
+#endif
 }
 
 #define MAXPATH 16
@@ -434,11 +442,19 @@ 
 
 	for (ii = 0; ii < len; ii++) {
 		PyObject *val = PyList_GET_ITEM(list, ii);
+#ifndef PY3
 		if (!PyInt_Check(val)) {
 			PyErr_SetString(PyExc_TypeError, msg);
 			return 0; /* fail */
 		}
 		data->block[ii+1] = (__u8)PyInt_AS_LONG(val);
+#else
+		if (!PyLong_Check(val)) {
+			PyErr_SetString(PyExc_TypeError, msg);
+			return 0; /* fail */
+		}
+		data->block[ii+1] = (__u8)PyLong_AS_LONG(val);
+#endif
 	}
 
 	return 1; /* success */
@@ -636,12 +652,18 @@ 
 	{NULL},
 };
 
+#ifndef PY3
 static PyTypeObject SMBus_type = {
 	PyObject_HEAD_INIT(NULL)
 	0,				/* ob_size */
 	"smbus.SMBus",			/* tp_name */
-	sizeof(SMBus),			/* tp_basicsize */
-	0,				/* tp_itemsize */
+#else
+static PyTypeObject SMBus_type = {
+	PyVarObject_HEAD_INIT(NULL, 0)
+	"SMBus",			/* tp_name */
+#endif
+	sizeof(SMBus),		/* tp_basicsize */
+	0,				    /* tp_itemsize */
 	(destructor)SMBus_dealloc,	/* tp_dealloc */
 	0,				/* tp_print */
 	0,				/* tp_getattr */
@@ -678,24 +700,64 @@ 
 	SMBus_new,			/* tp_new */
 };
 
+#ifndef PY3
 static PyMethodDef SMBus_module_methods[] = {
 	{NULL}
 };
+#else
+static struct PyModuleDef SMBusModule = {
+	PyModuleDef_HEAD_INIT,
+	"SMBus",	/* m_name */
+	"This module defines an object type that allows SMBus transactions\n"
+	"on hosts running the Linux kernel.  The host kernel must have I2C\n"
+	"support, I2C device interface support, and a bus adapter driver.\n"
+	"All of these can be either built-in to the kernel, or loaded from\n"
+	"modules.\n"
+	"\n"
+	"Because the I2C device interface is opened R/W, users of this\n"
+	"module usually must have root permissions.\n",  /* m_doc */
+	-1, /* m_size */
+	NULL, /* m_methods */
+	NULL, /* m_reload */
+	NULL, /* m_traverse */
+	NULL, /* m_clear */
+	NULL, /* m_free */
+};
+#endif
 
 #ifndef PyMODINIT_FUNC	/* declarations for DLL import/export */
 #define PyMODINIT_FUNC void
 #endif
 PyMODINIT_FUNC
-initsmbus(void) 
+
+#ifndef PY3
+initsmbus(void)
+#else
+PyInit_smbus(void)
+#endif 
 {
 	PyObject* m;
 
 	if (PyType_Ready(&SMBus_type) < 0)
+#ifndef PY3
 		return;
+#else
+		return NULL;
+#endif
 
+#ifndef PY3
 	m = Py_InitModule3("smbus", SMBus_module_methods, SMBus_module_doc);
+#else
+	m = PyModule_Create(&SMBusModule);
+	if (m == NULL)
+		return NULL;
+#endif
 
 	Py_INCREF(&SMBus_type);
 	PyModule_AddObject(m, "SMBus", (PyObject *)&SMBus_type);
+
+#ifdef PY3
+	return m;
+#endif
 }