From c292a0d1aaa9b6f68ec2a089d3b91914daf49ef9 Mon Sep 17 00:00:00 2001 From: "Gustavo J. A. M. Carneiro" Date: Sat, 14 Apr 2007 16:21:15 +0000 Subject: Bug 419379 – Modernize init_pygobject: use static inline functions instead of macros MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit svn path=/trunk/; revision=643 --- ChangeLog | 3 ++ gobject/pygobject.h | 140 ++++++++++++++++++++++++++++++++++++---------------- 2 files changed, 100 insertions(+), 43 deletions(-) diff --git a/ChangeLog b/ChangeLog index 03f30f6..a33c66e 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,8 @@ 2007-04-14 Gustavo J. A. M. Carneiro + * gobject/pygobject.h: Bug #419379: Modernize init_pygobject: use + static inline functions instead of macros. + * gobject/gobjectmodule.c (init_gobject): * gobject/pygobject-private.h: * gobject/pygobject.c (pygobject_data_free, pygobject_data_new), diff --git a/gobject/pygobject.h b/gobject/pygobject.h index 71c7853..045f53a 100644 --- a/gobject/pygobject.h +++ b/gobject/pygobject.h @@ -278,53 +278,107 @@ struct _PyGObject_Functions *_PyGObject_API; PyEval_RestoreThread(_save); \ } G_STMT_END -#define init_pygobject() G_STMT_START { \ - PyObject *gobject = PyImport_ImportModule("gobject"); \ - if (gobject != NULL) { \ - PyObject *mdict = PyModule_GetDict(gobject); \ - PyObject *cobject = PyDict_GetItemString(mdict, "_PyGObject_API"); \ - if (PyCObject_Check(cobject)) \ - _PyGObject_API = (struct _PyGObject_Functions *)PyCObject_AsVoidPtr(cobject); \ - else { \ - PyErr_SetString(PyExc_RuntimeError, \ - "could not find _PyGObject_API object"); \ - return; \ - } \ - } else { \ - PyErr_SetString(PyExc_ImportError, \ - "could not import gobject"); \ - return; \ - } \ + +/** + * pygobject_init: + * @req_major: minimum version major number, or -1 + * @req_minor: minimum version minor number, or -1 + * @req_micro: minimum version micro number, or -1 + * + * Imports and initializes the 'gobject' python module. Can + * optionally check for a required minimum version if @req_major, + * @req_minor, and @req_micro are all different from -1. + * + * Returns: a new reference to the gobject module on success, NULL in + * case of failure (and raises ImportError). + **/ +static inline PyObject * +pygobject_init(int req_major, int req_minor, int req_micro) +{ + PyObject *gobject, *cobject; + + gobject = PyImport_ImportModule("gobject"); + if (!gobject) { + if (PyErr_Occurred()) + { + PyObject *type, *value, *traceback; + PyObject *py_orig_exc; + PyErr_Fetch(&type, &value, &traceback); + py_orig_exc = PyObject_Repr(value); + Py_XDECREF(type); + Py_XDECREF(value); + Py_XDECREF(traceback); + PyErr_Format(PyExc_ImportError, + "could not import gobject (error was: %s)", + PyString_AsString(py_orig_exc)); + Py_DECREF(py_orig_exc); + } else { + PyErr_SetString(PyExc_ImportError, + "could not import gobject (no error given)"); + } + return NULL; + } + + cobject = PyObject_GetAttrString(gobject, "_PyGObject_API"); + if (cobject && PyCObject_Check(cobject)) + _PyGObject_API = (struct _PyGObject_Functions *) PyCObject_AsVoidPtr(cobject); + else { + PyErr_SetString(PyExc_ImportError, + "could not import gobject (could not find _PyGObject_API object)"); + Py_DECREF(gobject); + return NULL; + } + + if (req_major != -1) + { + int found_major, found_minor, found_micro; + PyObject *version; + + version = PyObject_GetAttrString(gobject, "pygobject_version"); + if (!version) + version = PyObject_GetAttrString(gobject, "pygtk_version"); + if (!version) { + PyErr_SetString(PyExc_ImportError, + "could not import gobject (version too old)"); + Py_DECREF(gobject); + return NULL; + } + if (!PyArg_ParseTuple(version, "iii", + &found_major, &found_minor, &found_micro)) { + PyErr_SetString(PyExc_ImportError, + "could not import gobject (version has invalid format)"); + Py_DECREF(version); + Py_DECREF(gobject); + return NULL; + } + Py_DECREF(version); + if (req_major != found_major || + req_minor > found_minor || + (req_minor == found_minor && req_micro > found_micro)) { + PyErr_Format(PyExc_ImportError, + "could not import gobject (version mismatch, %d.%d.%d is required, " + "found %d.%d.%d)", req_major, req_minor, req_micro, + found_major, found_minor, found_micro); + Py_DECREF(gobject); + return NULL; + } + } + return gobject; +} + +/* deprecated macro, use pygobject_init() instead. */ +#define init_pygobject() G_STMT_START { \ + if (!pygobject_init(-1, -1, -1)) \ + return; \ } G_STMT_END -#define init_pygobject_check(req_major, req_minor, req_micro) G_STMT_START { \ - PyObject *gobject, *mdict, *version; \ - int found_major, found_minor, found_micro; \ - init_pygobject(); \ - gobject = PyImport_ImportModule("gobject"); \ - mdict = PyModule_GetDict(gobject); \ - version = PyDict_GetItemString(mdict, "pygobject_version"); \ - if (!version) \ - version = PyDict_GetItemString(mdict, "pygtk_version"); \ - if (!version) { \ - PyErr_SetString(PyExc_ImportError, \ - "PyGObject version too old"); \ - return; \ - } \ - if (!PyArg_ParseTuple(version, "iii", \ - &found_major, &found_minor, &found_micro)) \ - return; \ - if (req_major != found_major || \ - req_minor > found_minor || \ - (req_minor == found_minor && req_micro > found_micro)) { \ - PyErr_Format(PyExc_ImportError, \ - "PyGObject version mismatch, %d.%d.%d is required, " \ - "found %d.%d.%d.", req_major, req_minor, req_micro, \ - found_major, found_minor, found_micro); \ - return; \ - } \ +/* deprecated macro, use pygobject_init() instead. */ +#define init_pygobject_check(req_major, req_minor, req_micro) G_STMT_START { \ + if (!pygobject_init(req_major, req_minor, req_micro)) \ + return; \ } G_STMT_END + #endif /* !_INSIDE_PYGOBJECT_ */ G_END_DECLS -- cgit