summaryrefslogtreecommitdiffstats
path: root/libmount/python/pylibmount.c
diff options
context:
space:
mode:
authorOndrej Oprala2013-08-29 14:57:04 +0200
committerKarel Zak2013-09-20 12:48:53 +0200
commit464074532c0d1898f945a00c2f143e5b3ca59601 (patch)
treebeb19a7e647b6738c57a822d7c4fdb8992042bb0 /libmount/python/pylibmount.c
parentbuild-sys: support --with-python[={2,3}] (diff)
downloadkernel-qcow2-util-linux-464074532c0d1898f945a00c2f143e5b3ca59601.tar.gz
kernel-qcow2-util-linux-464074532c0d1898f945a00c2f143e5b3ca59601.tar.xz
kernel-qcow2-util-linux-464074532c0d1898f945a00c2f143e5b3ca59601.zip
pylibmount: rewrite to be py2/py3 universal
Signed-off-by: Ondrej Oprala <ooprala@redhat.com> Signed-off-by: Karel Zak <kzak@redhat.com>
Diffstat (limited to 'libmount/python/pylibmount.c')
-rw-r--r--libmount/python/pylibmount.c89
1 files changed, 81 insertions, 8 deletions
diff --git a/libmount/python/pylibmount.c b/libmount/python/pylibmount.c
index d2e79fbcc..1403bfe3c 100644
--- a/libmount/python/pylibmount.c
+++ b/libmount/python/pylibmount.c
@@ -24,13 +24,21 @@
PyObject *LibmountError;
int pylibmount_debug_mask;
-
PyObject *UL_IncRef(void *killme)
{
Py_INCREF(killme);
return killme;
}
+void PyFree(void *o)
+{
+#if PY_MAJOR_VERSION >= 3
+ Py_TYPE(o)->tp_free((PyObject *)o);
+#else
+ ((PyObject *)o)->ob_type->tp_free((PyObject *)o);
+#endif
+}
+
/* Demultiplexer for various possible error conditions across the libmount library */
void *UL_RaiseExc(int e)
{
@@ -95,14 +103,22 @@ PyObject *PyObjectResultStr(const char *s)
return result;
}
-/* wrapper around a common use case for PyString_AsString() */
+/* wrapper around a common use case for PyUnicode_AsASCIIString() */
char *pystos(PyObject *pys)
{
+#if PY_MAJOR_VERSION >= 3
+ if (!PyUnicode_Check(pys)) {
+ PyErr_SetString(PyExc_TypeError, ARG_ERR);
+ return NULL;
+ }
+ return (char *)PyUnicode_1BYTE_DATA(pys);
+#else
if (!PyString_Check(pys)) {
PyErr_SetString(PyExc_TypeError, ARG_ERR);
return NULL;
}
return PyString_AsString(pys);
+#endif
}
/*
@@ -118,20 +134,73 @@ char *pystos(PyObject *pys)
"and returns a (tag, value) tuple. Every attribute is \"filtered\"" \
"through appropriate getters/setters, no values are set directly."
-static PyMethodDef libmount_methods[] = {
- {NULL} /* Sentinel */
+
+struct module_state {
+ PyObject *error;
};
-#ifndef PyMODINIT_FUNC
-# define PyMODINIT_FUNC void
+#if PY_MAJOR_VERSION >= 3
+#define GETSTATE(m) ((struct module_state*)PyModule_GetState(m))
+#else
+#define GETSTATE(m) (&_state)
+static struct module_state _state;
#endif
+
+static PyObject *
+error_out(PyObject *m __attribute__((unused))) {
+ struct module_state *st = GETSTATE(m);
+ PyErr_SetString(st->error, "something bad happened");
+ return NULL;
+}
+
+static PyMethodDef pylibmount_methods[] = {
+ {"error_out", (PyCFunction)error_out, METH_NOARGS, NULL},
+ {NULL, NULL}
+};
+
+#if PY_MAJOR_VERSION >= 3
+
+static int pylibmount_traverse(PyObject *m, visitproc visit, void *arg) {
+ Py_VISIT(GETSTATE(m)->error);
+ return 0;
+}
+
+static int pylibmount_clear(PyObject *m) {
+ Py_CLEAR(GETSTATE(m)->error);
+ return 0;
+}
+
+static struct PyModuleDef moduledef = {
+ PyModuleDef_HEAD_INIT,
+ "pylibmount",
+ NULL,
+ sizeof(struct module_state),
+ pylibmount_methods,
+ NULL,
+ pylibmount_traverse,
+ pylibmount_clear,
+ NULL
+};
+#define INITERROR return NULL
+PyObject * PyInit_pylibmount(void);
+PyObject * PyInit_pylibmount(void)
+#else
+#define INITERROR return
+# ifndef PyMODINIT_FUNC
+# define PyMODINIT_FUNC void
+# endif
PyMODINIT_FUNC initpylibmount(void);
PyMODINIT_FUNC initpylibmount(void)
+#endif
{
- PyObject *m = Py_InitModule3("pylibmount", libmount_methods, PYLIBMOUNT_DESC);
+#if PY_MAJOR_VERSION >= 3
+ PyObject *m = PyModule_Create(&moduledef);
+#else
+ PyObject *m = Py_InitModule3("pylibmount", pylibmount_methods, PYLIBMOUNT_DESC);
+#endif
if (!m)
- return;
+ INITERROR;
/*
* init debug stuff
*/
@@ -223,5 +292,9 @@ PyMODINIT_FUNC initpylibmount(void)
/* Still useful for functions using iterators internally */
PyModule_AddIntConstant(m, "MNT_ITER_FORWARD", MNT_ITER_FORWARD);
PyModule_AddIntConstant(m, "MNT_ITER_BACKWARD", MNT_ITER_BACKWARD);
+
+#if PY_MAJOR_VERSION >= 3
+ return m;
+#endif
}