Last active
August 29, 2015 14:15
-
-
Save simonrw/30771e74f5a63630b035 to your computer and use it in GitHub Desktop.
Simple boilerplate code for wrapping C code into either python 2 or 3, taken from the porting guide: https://docs.python.org/3/howto/cporting.html
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include "Python.h" | |
/********************************************************************************* | |
* Taken from the porting guide: https://docs.python.org/3/howto/cporting.html | |
* | |
* Change all occurrences of | |
* - myextension => the extension name you want to create, | |
* - error_out => the function(s) you want to wrap | |
* - METH_NOARGS => METH_VARARGS|METH_KWARGS depending on if the function | |
* takes keyword arguments or not | |
*********************************************************************************/ | |
struct module_state { | |
PyObject *error; | |
}; | |
#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) { | |
struct module_state *st = GETSTATE(m); | |
PyErr_SetString(st->error, "something bad happened"); | |
return NULL; | |
} | |
static char module_docstring[] = "myextension docstring"; | |
static char error_out_docstring[] = "error_out docstring"; | |
static PyMethodDef myextension_methods[] = { | |
{"error_out", (PyCFunction)error_out, METH_NOARGS, error_out_docstring}, | |
{NULL, NULL} | |
}; | |
#if PY_MAJOR_VERSION >= 3 | |
static int myextension_traverse(PyObject *m, visitproc visit, void *arg) { | |
Py_VISIT(GETSTATE(m)->error); | |
return 0; | |
} | |
static int myextension_clear(PyObject *m) { | |
Py_CLEAR(GETSTATE(m)->error); | |
return 0; | |
} | |
static struct PyModuleDef moduledef = { | |
PyModuleDef_HEAD_INIT, | |
"myextension", | |
module_docstring, | |
sizeof(struct module_state), | |
myextension_methods, | |
NULL, | |
myextension_traverse, | |
myextension_clear, | |
NULL | |
}; | |
#define INITERROR return NULL | |
PyObject * | |
PyInit_myextension(void) | |
#else | |
#define INITERROR return | |
void | |
initmyextension(void) | |
#endif | |
{ | |
#if PY_MAJOR_VERSION >= 3 | |
PyObject *module = PyModule_Create(&moduledef); | |
#else | |
PyObject *module = Py_InitModule3("myextension", myextension_methods, module_docstring); | |
#endif | |
if (module == NULL) | |
INITERROR; | |
struct module_state *st = GETSTATE(module); | |
st->error = PyErr_NewException("myextension.Error", NULL, NULL); | |
if (st->error == NULL) { | |
Py_DECREF(module); | |
INITERROR; | |
} | |
#if PY_MAJOR_VERSION >= 3 | |
return module; | |
#endif | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment