summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSimon Feltman <sfeltman@src.gnome.org>2013-12-31 19:42:02 -0800
committerSimon Feltman <sfeltman@src.gnome.org>2013-12-31 19:42:02 -0800
commitcebf5314f195bf4bd6ee19a1da3bbb50c2c9bbd6 (patch)
tree945b934b759823f81116f97646a6d48cebde8c40
parent28a178e385e32c56910f1c430b370a8872218081 (diff)
downloadpygobject-cebf5314f195bf4bd6ee19a1da3bbb50c2c9bbd6.tar.gz
docs: Move GIArgInfo.get_pytype_hint into gi.docstring
Move the C implementation of pytype hinting into pure Python. Now that doc strings are lazily evaluated we can simplify this tedious bit of C code with Python. This is precursory work for getting return types into function doc strings. https://bugzilla.gnome.org/show_bug.cgi?id=697356
-rw-r--r--gi/docstring.py50
-rw-r--r--gi/pygi-info.c49
-rw-r--r--gi/pygi-type.c58
-rw-r--r--gi/pygi-type.h2
-rw-r--r--tests/test_docstring.py8
-rw-r--r--tests/test_repository.py1
6 files changed, 52 insertions, 116 deletions
diff --git a/gi/docstring.py b/gi/docstring.py
index 9b4f6404..b4ae43c4 100644
--- a/gi/docstring.py
+++ b/gi/docstring.py
@@ -23,7 +23,8 @@
from ._gi import \
VFuncInfo, \
FunctionInfo, \
- Direction
+ Direction, \
+ TypeTag
#: Module storage for currently registered doc string generator function.
@@ -74,6 +75,49 @@ def split_function_info_args(info):
return (in_args, out_args)
+_type_tag_to_py_type = {TypeTag.BOOLEAN: bool,
+ TypeTag.INT8: int,
+ TypeTag.UINT8: int,
+ TypeTag.INT16: int,
+ TypeTag.UINT16: int,
+ TypeTag.INT32: int,
+ TypeTag.UINT32: int,
+ TypeTag.INT64: int,
+ TypeTag.UINT64: int,
+ TypeTag.FLOAT: float,
+ TypeTag.DOUBLE: float,
+ TypeTag.GLIST: list,
+ TypeTag.GSLIST: list,
+ TypeTag.ARRAY: list,
+ TypeTag.GHASH: dict,
+ TypeTag.UTF8: str,
+ TypeTag.FILENAME: str,
+ TypeTag.UNICHAR: str,
+ TypeTag.INTERFACE: None,
+ TypeTag.GTYPE: None,
+ TypeTag.ERROR: None,
+ TypeTag.VOID: None,
+ }
+
+
+def _get_pytype_hint(gi_type):
+ type_tag = gi_type.get_tag()
+ py_type = _type_tag_to_py_type.get(type_tag, None)
+
+ if py_type and hasattr(py_type, '__name__'):
+ return py_type.__name__
+ elif type_tag == TypeTag.INTERFACE:
+ iface = gi_type.get_interface()
+
+ info_name = iface.get_name()
+ if not info_name:
+ return gi_type.get_tag_as_string()
+
+ return '%s.%s' % (iface.get_namespace(), info_name)
+
+ return gi_type.get_tag_as_string()
+
+
def _generate_callable_info_function_signature(info):
"""Default doc string generator"""
in_args, out_args = split_function_info_args(info)
@@ -100,7 +144,7 @@ def _generate_callable_info_function_signature(info):
if i in ignore_indices:
continue
argstr = arg.get_name()
- hint = arg.get_pytype_hint()
+ hint = _get_pytype_hint(arg.get_type())
if hint not in ('void',):
argstr += ':' + hint
if arg.may_be_null() or i in user_data_indices:
@@ -112,7 +156,7 @@ def _generate_callable_info_function_signature(info):
in_args_str = ', '.join(in_args_strs)
if out_args:
- out_args_str = ', '.join(arg.get_name() + ':' + arg.get_pytype_hint()
+ out_args_str = ', '.join(arg.get_name() + ':' + _get_pytype_hint(arg.get_type())
for arg in out_args)
return '%s(%s) -> %s' % (info.get_name(), in_args_str, out_args_str)
else:
diff --git a/gi/pygi-info.c b/gi/pygi-info.c
index 12f756c0..2f978206 100644
--- a/gi/pygi-info.c
+++ b/gi/pygi-info.c
@@ -908,54 +908,6 @@ _wrap_g_arg_info_get_type (PyGIBaseInfo *self)
return _get_child_info (self, g_arg_info_get_type);
}
-/* _g_arg_get_pytype_hint
- *
- * Returns new value reference to a string hinting at the python type
- * which can be used for the given gi argument info.
- */
-static PyObject *
-_g_arg_get_pytype_hint (PyGIBaseInfo *self)
-{
- GIArgInfo *arg_info = (GIArgInfo*)self->info;
- GITypeInfo type_info;
- GITypeTag type_tag;
- PyObject *py_type;
-
- g_arg_info_load_type(arg_info, &type_info);
- type_tag = g_type_info_get_tag(&type_info);
-
- /* First attempt getting a python type object. */
- py_type = _pygi_get_py_type_hint(type_tag);
- if (py_type != Py_None && PyObject_HasAttrString(py_type, "__name__")) {
- PyObject *name = PyObject_GetAttrString(py_type, "__name__");
- Py_DecRef(py_type);
- return name;
- } else {
- Py_DecRef(py_type);
- if (type_tag == GI_TYPE_TAG_INTERFACE) {
- const char *info_name;
- PyObject *py_string;
- GIBaseInfo *iface = g_type_info_get_interface(&type_info);
- gchar *name;
-
- info_name = _safe_base_info_get_name (iface);
- if (info_name == NULL) {
- g_base_info_unref (iface);
- return PYGLIB_PyUnicode_FromString(g_type_tag_to_string(type_tag));
- }
-
- name = g_strdup_printf("%s.%s",
- g_base_info_get_namespace(iface),
- info_name);
- g_base_info_unref(iface);
- py_string = PYGLIB_PyUnicode_FromString(name);
- g_free(name);
- return py_string;
- }
- return PYGLIB_PyUnicode_FromString(g_type_tag_to_string(type_tag));
- }
-}
-
static PyMethodDef _PyGIArgInfo_methods[] = {
{ "get_direction", (PyCFunction) _wrap_g_arg_info_get_direction, METH_NOARGS },
{ "is_caller_allocates", (PyCFunction) _wrap_g_arg_info_is_caller_allocates, METH_NOARGS },
@@ -967,7 +919,6 @@ static PyMethodDef _PyGIArgInfo_methods[] = {
{ "get_closure", (PyCFunction) _wrap_g_arg_info_get_closure, METH_NOARGS },
{ "get_destroy", (PyCFunction) _wrap_g_arg_info_get_destroy, METH_NOARGS },
{ "get_type", (PyCFunction) _wrap_g_arg_info_get_type, METH_NOARGS },
- { "get_pytype_hint", (PyCFunction) _g_arg_get_pytype_hint, METH_NOARGS },
{ NULL, NULL, 0 }
};
diff --git a/gi/pygi-type.c b/gi/pygi-type.c
index dfaadb03..95f3c2c3 100644
--- a/gi/pygi-type.c
+++ b/gi/pygi-type.c
@@ -99,61 +99,3 @@ _pygi_type_get_from_g_type (GType g_type)
return py_type;
}
-/* _pygi_get_py_type_hint
- *
- * This gives a hint to what python type might be used as
- * a particular gi type.
- */
-PyObject *
-_pygi_get_py_type_hint(GITypeTag type_tag)
-{
- PyObject *type = Py_None;
-
- switch (type_tag) {
- case GI_TYPE_TAG_BOOLEAN:
- type = (PyObject *) &PyBool_Type;
- break;
-
- case GI_TYPE_TAG_INT8:
- case GI_TYPE_TAG_UINT8:
- case GI_TYPE_TAG_INT16:
- case GI_TYPE_TAG_UINT16:
- case GI_TYPE_TAG_INT32:
- case GI_TYPE_TAG_UINT32:
- case GI_TYPE_TAG_INT64:
- case GI_TYPE_TAG_UINT64:
- type = (PyObject *) &PYGLIB_PyLong_Type;
- break;
-
- case GI_TYPE_TAG_FLOAT:
- case GI_TYPE_TAG_DOUBLE:
- type = (PyObject *) &PyFloat_Type;
- break;
-
- case GI_TYPE_TAG_GLIST:
- case GI_TYPE_TAG_GSLIST:
- case GI_TYPE_TAG_ARRAY:
- type = (PyObject *) &PyList_Type;
- break;
-
- case GI_TYPE_TAG_GHASH:
- type = (PyObject *) &PyDict_Type;
- break;
-
- case GI_TYPE_TAG_UTF8:
- case GI_TYPE_TAG_FILENAME:
- case GI_TYPE_TAG_UNICHAR:
- type = (PyObject *) &PYGLIB_PyUnicode_Type;
- break;
-
- case GI_TYPE_TAG_INTERFACE:
- case GI_TYPE_TAG_GTYPE:
- case GI_TYPE_TAG_ERROR:
- case GI_TYPE_TAG_VOID:
- break;
- }
-
- Py_INCREF(type);
- return type;
-}
-
diff --git a/gi/pygi-type.h b/gi/pygi-type.h
index 01b59947..1d225f0b 100644
--- a/gi/pygi-type.h
+++ b/gi/pygi-type.h
@@ -39,8 +39,6 @@ PyObject *_pygi_type_import_by_gi_info (GIBaseInfo *info);
PyObject *_pygi_type_get_from_g_type (GType g_type);
-PyObject *_pygi_get_py_type_hint (GITypeTag type_tag);
-
G_END_DECLS
#endif /* __PYGI_TYPE_H__ */
diff --git a/tests/test_docstring.py b/tests/test_docstring.py
index 2f176ffc..1cae95cc 100644
--- a/tests/test_docstring.py
+++ b/tests/test_docstring.py
@@ -1,6 +1,7 @@
import unittest
import gi.docstring
+from gi.docstring import _get_pytype_hint
from gi.repository import GIMarshallingTests
from gi.repository import Gio
@@ -25,15 +26,16 @@ class Test(unittest.TestCase):
in_args, out_args = gi.docstring.split_function_info_args(GIMarshallingTests.int_out_out)
self.assertEqual(len(in_args), 0)
self.assertEqual(len(out_args), 2)
- self.assertEqual(out_args[0].get_pytype_hint(), 'int')
- self.assertEqual(out_args[1].get_pytype_hint(), 'int')
+ self.assertEqual(_get_pytype_hint(out_args[0].get_type()), 'int')
+ self.assertEqual(_get_pytype_hint(out_args[1].get_type()), 'int')
def test_split_args_inout(self):
in_args, out_args = gi.docstring.split_function_info_args(GIMarshallingTests.long_inout_max_min)
self.assertEqual(len(in_args), 1)
self.assertEqual(len(out_args), 1)
self.assertEqual(in_args[0].get_name(), out_args[0].get_name())
- self.assertEqual(in_args[0].get_pytype_hint(), out_args[0].get_pytype_hint())
+ self.assertEqual(_get_pytype_hint(in_args[0].get_type()),
+ _get_pytype_hint(out_args[0].get_type()))
def test_split_args_none(self):
obj = GIMarshallingTests.Object(int=33)
diff --git a/tests/test_repository.py b/tests/test_repository.py
index 6fd79062..20602ba1 100644
--- a/tests/test_repository.py
+++ b/tests/test_repository.py
@@ -61,7 +61,6 @@ class Test(unittest.TestCase):
self.assertEqual(arg.get_direction(), GIRepository.Direction.OUT)
self.assertEqual(arg.get_name(), 'structs')
self.assertEqual(arg.get_namespace(), 'GIMarshallingTests')
- self.assertEqual(arg.get_pytype_hint(), 'list')
self.assertFalse(arg.is_caller_allocates())
self.assertFalse(arg.is_optional())
self.assertFalse(arg.is_return_value())