[pygobject] Add common attribute accessors to PyGIBaseInfo
- From: Simon Feltman <sfeltman src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [pygobject] Add common attribute accessors to PyGIBaseInfo
- Date: Fri, 26 Jul 2013 23:42:57 +0000 (UTC)
commit bec0b543be8d993996d8a17c343c3f2f33a9398f
Author: Simon Feltman <sfeltman src gnome org>
Date: Tue Jul 16 11:13:17 2013 -0700
Add common attribute accessors to PyGIBaseInfo
Add __name__, __module__, and __doc__ accessors to
PyGIBaseInfo object. This is a precursory patch for setting
up PyGICallableInfo as a directly callable object with lazy
doc string evaluation.
https://bugzilla.gnome.org/show_bug.cgi?id=704037
gi/_glib/pyglib-python-compat.h | 5 ++
gi/pygi-info.c | 83 +++++++++++++++++++++++++++++++++++++-
gi/types.py | 7 +--
3 files changed, 88 insertions(+), 7 deletions(-)
---
diff --git a/gi/_glib/pyglib-python-compat.h b/gi/_glib/pyglib-python-compat.h
index 96c27ca..7b4c595 100644
--- a/gi/_glib/pyglib-python-compat.h
+++ b/gi/_glib/pyglib-python-compat.h
@@ -87,6 +87,8 @@ static int _pyglib_init_##modname(PyObject *module)
#define PYGLIB_PyUnicode_AS_STRING PyString_AS_STRING
#define PYGLIB_PyUnicode_GET_SIZE PyString_GET_SIZE
#define PYGLIB_PyUnicode_Type PyString_Type
+#define PYGLIB_PyUnicode_InternFromString PyString_InternFromString
+#define PYGLIB_PyUnicode_InternInPlace PyString_InternInPlace
#define PYGLIB_PyBytes_FromString PyString_FromString
#define PYGLIB_PyBytes_FromStringAndSize PyString_FromStringAndSize
@@ -191,6 +193,9 @@ PyTypeObject symbol = { \
#define PYGLIB_PyUnicode_GET_SIZE PyUnicode_GET_SIZE
#define PYGLIB_PyUnicode_Resize PyUnicode_Resize
#define PYGLIB_PyUnicode_Type PyUnicode_Type
+#define PYGLIB_PyUnicode_InternFromString PyUnicode_InternFromString
+#define PYGLIB_PyUnicode_InternInPlace PyUnicode_InternInPlace
+
#define PYGLIB_PyLong_Check PyLong_Check
#define PYGLIB_PyLong_FromLong PyLong_FromLong
#define PYGLIB_PyLong_AsLong PyLong_AsLong
diff --git a/gi/pygi-info.c b/gi/pygi-info.c
index c8dfb2b..0622fc8 100644
--- a/gi/pygi-info.c
+++ b/gi/pygi-info.c
@@ -27,6 +27,33 @@
#include <pygobject.h>
#include <pyglib-python-compat.h>
+
+/* _generate_doc_string
+ *
+ * C wrapper to call Python implemented "gi.docstring.generate_doc_string"
+ */
+static PyObject *
+_generate_doc_string(PyGIBaseInfo *self)
+{
+ static PyObject *_py_generate_doc_string = NULL;
+
+ if (_py_generate_doc_string == NULL) {
+ PyObject *mod = PyImport_ImportModule ("gi.docstring");
+ if (!mod)
+ return NULL;
+
+ _py_generate_doc_string = PyObject_GetAttrString (mod, "generate_doc_string");
+ if (_py_generate_doc_string == NULL) {
+ Py_DECREF (mod);
+ return NULL;
+ }
+ Py_DECREF (mod);
+ }
+
+ return PyObject_CallFunctionObjArgs (_py_generate_doc_string, self, NULL);
+}
+
+
/* BaseInfo */
static void
@@ -170,6 +197,55 @@ static PyMethodDef _PyGIBaseInfo_methods[] = {
{ NULL, NULL, 0 }
};
+/* _base_info_getattro:
+ *
+ * The usage of __getattr__ is needed because the get/set method table
+ * does not work for __doc__.
+ */
+static PyObject *
+_base_info_getattro(PyGIBaseInfo *self, PyObject *name)
+{
+ PyObject *result;
+
+ static PyObject *docstr;
+ if (docstr == NULL) {
+ docstr= PYGLIB_PyUnicode_InternFromString("__doc__");
+ if (docstr == NULL)
+ return NULL;
+ }
+
+ Py_INCREF (name);
+ PYGLIB_PyUnicode_InternInPlace (&name);
+
+ if (name == docstr) {
+ result = _generate_doc_string (self);
+ } else {
+ result = PyObject_GenericGetAttr ((PyObject *)self, name);
+ }
+
+ Py_DECREF (name);
+ return result;
+}
+
+static PyObject *
+_base_info_attr_name(PyGIBaseInfo *self, void *closure)
+{
+ return _wrap_g_base_info_get_name (self);
+}
+
+static PyObject *
+_base_info_attr_module(PyGIBaseInfo *self, void *closure)
+{
+ return PYGLIB_PyUnicode_FromFormat ("gi.repository.%s",
+ g_base_info_get_namespace (self->info));
+}
+
+static PyGetSetDef _base_info_getsets[] = {
+ { "__name__", (getter)_base_info_attr_name, (setter)0, "Name", NULL},
+ { "__module__", (getter)_base_info_attr_module, (setter)0, "Module name", NULL},
+ { NULL, 0, 0 }
+};
+
PyObject *
_pygi_info_new (GIBaseInfo *info)
{
@@ -1742,12 +1818,13 @@ _pygi_info_register_types (PyObject *m)
PyGIBaseInfo_Type.tp_repr = (reprfunc) _base_info_repr;
PyGIBaseInfo_Type.tp_flags = (Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE);
PyGIBaseInfo_Type.tp_weaklistoffset = offsetof(PyGIBaseInfo, inst_weakreflist);
- PyGIBaseInfo_Type.tp_methods = _PyGIBaseInfo_methods;
+ PyGIBaseInfo_Type.tp_methods = _PyGIBaseInfo_methods;
PyGIBaseInfo_Type.tp_richcompare = (richcmpfunc)_base_info_richcompare;
+ PyGIBaseInfo_Type.tp_getset = _base_info_getsets;
+ PyGIBaseInfo_Type.tp_getattro = (getattrofunc) _base_info_getattro;
if (PyType_Ready(&PyGIBaseInfo_Type))
- return;
-
+ return;
if (PyModule_AddObject(m, "BaseInfo", (PyObject *)&PyGIBaseInfo_Type))
return;
diff --git a/gi/types.py b/gi/types.py
index 85eecf1..4e95ca2 100644
--- a/gi/types.py
+++ b/gi/types.py
@@ -28,7 +28,6 @@ import warnings
from . import _gobject
from ._gobject._gobject import GInterface
from ._gobject.constants import TYPE_INVALID
-from .docstring import generate_doc_string
from ._gi import \
InterfaceInfo, \
@@ -51,9 +50,9 @@ def wraps_callable_info(info):
"""Similar to functools.wraps but with specific GICallableInfo support."""
def update_func(func):
func.__info__ = info
- func.__name__ = info.get_name()
- func.__module__ = 'gi.repository.' + info.get_namespace()
- func.__doc__ = generate_doc_string(info)
+ func.__name__ = info.__name__
+ func.__module__ = info.__module__
+ func.__doc__ = info.__doc__
return func
return update_func
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]