Commit bec0b543 authored by Simon Feltman's avatar Simon Feltman
Browse files

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
parent ea194404
......@@ -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
......
......@@ -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;
......
......@@ -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
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment