diff options
author | Simon Feltman <sfeltman@src.gnome.org> | 2013-12-31 19:42:02 -0800 |
---|---|---|
committer | Simon Feltman <sfeltman@src.gnome.org> | 2013-12-31 19:42:02 -0800 |
commit | cebf5314f195bf4bd6ee19a1da3bbb50c2c9bbd6 (patch) | |
tree | 945b934b759823f81116f97646a6d48cebde8c40 | |
parent | 28a178e385e32c56910f1c430b370a8872218081 (diff) | |
download | pygobject-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.py | 50 | ||||
-rw-r--r-- | gi/pygi-info.c | 49 | ||||
-rw-r--r-- | gi/pygi-type.c | 58 | ||||
-rw-r--r-- | gi/pygi-type.h | 2 | ||||
-rw-r--r-- | tests/test_docstring.py | 8 | ||||
-rw-r--r-- | tests/test_repository.py | 1 |
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()) |