[pygobject] docs: Move GIArgInfo.get_pytype_hint into gi.docstring



commit cebf5314f195bf4bd6ee19a1da3bbb50c2c9bbd6
Author: Simon Feltman <sfeltman src gnome org>
Date:   Tue Dec 31 19:42:02 2013 -0800

    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

 gi/docstring.py          |   50 +++++++++++++++++++++++++++++++++++++--
 gi/pygi-info.c           |   49 --------------------------------------
 gi/pygi-type.c           |   58 ----------------------------------------------
 gi/pygi-type.h           |    2 -
 tests/test_docstring.py  |    8 ++++--
 tests/test_repository.py |    1 -
 6 files changed, 52 insertions(+), 116 deletions(-)
---
diff --git a/gi/docstring.py b/gi/docstring.py
index 9b4f640..b4ae43c 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 12f756c..2f97820 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 dfaadb0..95f3c2c 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 01b5994..1d225f0 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 2f176ff..1cae95c 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 6fd7906..20602ba 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())


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]