diff options
author | Simon Feltman <sfeltman@src.gnome.org> | 2014-04-28 20:25:30 -0700 |
---|---|---|
committer | Colin Walters <walters@verbum.org> | 2015-09-29 23:16:32 -0400 |
commit | ae198873254769bd49207003d25b47d12b096e2f (patch) | |
tree | 5c192285bbcb92e400c38307ce72a1f96e1c4270 /giscanner/giscannermodule.c | |
parent | d59b3827d2bb62c1ed4db8030ed9e8e753b7f52d (diff) | |
download | gobject-introspection-ae198873254769bd49207003d25b47d12b096e2f.tar.gz |
giscanner: Port scanner extension module to work with Python 3
Define portable macros for use between Python 2 and 3.
Replace usage of PyString related functions with PyBytes.
Update pygi_source_scanner_parse_macros to support both
PyBytes and PyUnicode.
https://bugzilla.gnome.org/show_bug.cgi?id=679438
Diffstat (limited to 'giscanner/giscannermodule.c')
-rw-r--r-- | giscanner/giscannermodule.c | 104 |
1 files changed, 75 insertions, 29 deletions
diff --git a/giscanner/giscannermodule.c b/giscanner/giscannermodule.c index f6945da3..845a72f5 100644 --- a/giscanner/giscannermodule.c +++ b/giscanner/giscannermodule.c @@ -39,32 +39,38 @@ #include <glib-object.h> -DL_EXPORT(void) init_giscanner(void); +#ifndef Py_TYPE + #define Py_TYPE(ob) (((PyObject*)(ob))->ob_type) +#endif + +#if PY_MAJOR_VERSION >= 3 + #define MOD_INIT(name) PyMODINIT_FUNC PyInit_##name(void) + #define MOD_ERROR_RETURN NULL + #define PyInt_FromLong PyLong_FromLong +#else + #define MOD_INIT(name) DL_EXPORT(void) init##name(void) + #define MOD_ERROR_RETURN +#endif + +/* forward declaration */ +MOD_INIT(_giscanner); #define NEW_CLASS(ctype, name, cname, num_methods) \ static const PyMethodDef _Py##cname##_methods[num_methods]; \ PyTypeObject Py##cname##_Type = { \ - PyObject_HEAD_INIT(NULL) \ - 0, \ + PyVarObject_HEAD_INIT(NULL, 0) \ "scanner." name, \ - sizeof(ctype), \ - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, \ - 0, 0, 0, 0, 0, 0, \ - Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, \ - NULL, 0, 0, 0, \ - 0, \ - 0, 0, \ - 0, \ - 0, 0, NULL, NULL, 0, 0, \ - 0 \ + sizeof(ctype), \ + 0 \ } #define REGISTER_TYPE(d, name, type) \ - type.ob_type = &PyType_Type; \ + Py_TYPE(&type) = &PyType_Type; \ type.tp_alloc = PyType_GenericAlloc; \ type.tp_new = PyType_GenericNew; \ + type.tp_flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE; \ if (PyType_Ready (&type)) \ - return; \ + return MOD_ERROR_RETURN; \ PyDict_SetItemString (d, name, (PyObject *)&type); \ Py_INCREF (&type); @@ -402,16 +408,34 @@ pygi_source_scanner_parse_macros (PyGISourceScanner *self, for (i = 0; i < PyList_Size (list); ++i) { PyObject *obj; - char *filename; + char *filename = NULL; obj = PyList_GetItem (list, i); - filename = PyString_AsString (obj); + if (PyUnicode_Check (obj)) + { + PyObject *s = PyUnicode_AsUTF8String (obj); + filename = g_strdup (PyBytes_AsString (s)); + Py_DECREF (s); + } + else if (PyBytes_Check (obj)) + { + filename = g_strdup (PyBytes_AsString (obj)); + } + + if (filename == NULL) + { + PyErr_Format (PyExc_RuntimeError, + "Expected string but got %s", + (Py_TYPE(obj))->tp_name); + g_list_free_full (filenames, g_free); + return NULL; + } filenames = g_list_append (filenames, filename); } gi_source_scanner_parse_macros (self->scanner, filenames); - g_list_free (filenames); + g_list_free_full (filenames, g_free); Py_INCREF (Py_None); return Py_None; @@ -669,9 +693,9 @@ static int calc_attrs_length(PyObject *attributes, int indent, if (!s) { return -1; } - value = PyString_AsString(s); - } else if (PyString_Check(pyvalue)) { - value = PyString_AsString(pyvalue); + value = PyBytes_AsString(s); + } else if (PyBytes_Check(pyvalue)) { + value = PyBytes_AsString(pyvalue); } else { PyErr_SetString(PyExc_TypeError, "value must be string or unicode"); @@ -756,9 +780,9 @@ pygi_collect_attributes (PyObject *self, s = PyUnicode_AsUTF8String(pyvalue); if (!s) goto out; - value = PyString_AsString(s); - } else if (PyString_Check(pyvalue)) { - value = PyString_AsString(pyvalue); + value = PyBytes_AsString(s); + } else if (PyBytes_Check(pyvalue)) { + value = PyBytes_AsString(pyvalue); } else { PyErr_SetString(PyExc_TypeError, "value must be string or unicode"); @@ -792,25 +816,43 @@ pygi_collect_attributes (PyObject *self, /* Module */ -static const PyMethodDef pyscanner_functions[] = { +static PyMethodDef pyscanner_functions[] = { { "collect_attributes", (PyCFunction) pygi_collect_attributes, METH_VARARGS }, { NULL, NULL, 0, NULL } }; -DL_EXPORT(void) -init_giscanner(void) +#if PY_MAJOR_VERSION >= 3 +static struct PyModuleDef moduledef = { + PyModuleDef_HEAD_INIT, + NULL, /* m_name */ + NULL, /* m_doc */ + 0, + pyscanner_functions, + NULL +}; +#endif /* PY_MAJOR_VERSION >= 3 */ + + +MOD_INIT(_giscanner) { PyObject *m, *d; gboolean is_uninstalled; + const char *module_name; /* Hack to avoid having to create a fake directory structure; when * running uninstalled, the module will be in the top builddir, * with no _giscanner prefix. */ is_uninstalled = g_getenv ("UNINSTALLED_INTROSPECTION_SRCDIR") != NULL; - m = Py_InitModule (is_uninstalled ? "_giscanner" : "giscanner._giscanner", - (PyMethodDef*)pyscanner_functions); + module_name = is_uninstalled ? "_giscanner" : "giscanner._giscanner"; + +#if PY_MAJOR_VERSION >= 3 + moduledef.m_name = module_name; + m = PyModule_Create (&moduledef); +#else + m = Py_InitModule (module_name, (PyMethodDef*)pyscanner_functions); +#endif d = PyModule_GetDict (m); PyGISourceScanner_Type.tp_init = (initproc)pygi_source_scanner_init; @@ -822,4 +864,8 @@ init_giscanner(void) PyGISourceType_Type.tp_getset = (PyGetSetDef*)_PyGISourceType_getsets; REGISTER_TYPE (d, "SourceType", PyGISourceType_Type); + +#if PY_MAJOR_VERSION >= 3 + return m; +#endif } |