1 # -*- Mode: Python; py-indent-offset: 4 -*-
2 # vim: tabstop=4 shiftwidth=4 expandtab
4 # Copyright (C) 2013 Simon Feltman <sfeltman@gnome.org>
6 # docstring.py: documentation string generator for gi.
8 # This library is free software; you can redistribute it and/or
9 # modify it under the terms of the GNU Lesser General Public
10 # License as published by the Free Software Foundation; either
11 # version 2.1 of the License, or (at your option) any later version.
13 # This library is distributed in the hope that it will be useful,
14 # but WITHOUT ANY WARRANTY; without even the implied warranty of
15 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 # Lesser General Public License for more details.
18 # You should have received a copy of the GNU Lesser General Public
19 # License along with this library; if not, write to the Free Software
20 # Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301
33 #: Module storage for currently registered doc string generator function.
34 _generate_doc_string_func
= None
37 def set_doc_string_generator(func
):
38 """Set doc string generator function
41 Callable which takes a GIInfoStruct and returns documentation for it.
43 global _generate_doc_string_func
44 _generate_doc_string_func
= func
47 def get_doc_string_generator():
48 """Returns the currently registered doc string generator."""
49 return _generate_doc_string_func
52 def generate_doc_string(info
):
53 """Generate a doc string given a GIInfoStruct.
55 :param gi.types.BaseInfo info:
56 GI info instance to generate documentation for.
58 Generated documentation as a string.
61 This passes the info struct to the currently registered doc string
62 generator and returns the result.
64 return _generate_doc_string_func(info
)
67 _type_tag_to_py_type
= {TypeTag
.BOOLEAN
: bool,
77 TypeTag
.DOUBLE
: float,
83 TypeTag
.FILENAME
: str,
85 TypeTag
.INTERFACE
: None,
92 def _get_pytype_hint(gi_type
):
93 type_tag
= gi_type
.get_tag()
94 py_type
= _type_tag_to_py_type
.get(type_tag
, None)
96 if py_type
and hasattr(py_type
, '__name__'):
97 return py_type
.__name
__
98 elif type_tag
== TypeTag
.INTERFACE
:
99 iface
= gi_type
.get_interface()
101 info_name
= iface
.get_name()
103 return gi_type
.get_tag_as_string()
105 return '%s.%s' % (iface
.get_namespace(), info_name
)
107 return gi_type
.get_tag_as_string()
110 def _generate_callable_info_doc(info
):
112 if isinstance(info
, VFuncInfo
):
113 in_args_strs
= ['self']
114 elif isinstance(info
, FunctionInfo
):
116 in_args_strs
= ['self']
118 args
= info
.get_arguments()
119 hint_blacklist
= ('void',)
121 # Build lists of indices prior to adding the docs because it is possible
122 # the index retrieved comes before input arguments being used.
123 ignore_indices
= set()
124 user_data_indices
= set()
126 ignore_indices
.add(arg
.get_destroy())
127 ignore_indices
.add(arg
.get_type().get_array_length())
128 user_data_indices
.add(arg
.get_closure())
130 # Build input argument strings
131 for i
, arg
in enumerate(args
):
132 if arg
.get_direction() == Direction
.OUT
:
133 continue # skip exclusively output args
134 if i
in ignore_indices
:
136 argstr
= arg
.get_name()
137 hint
= _get_pytype_hint(arg
.get_type())
138 if hint
not in hint_blacklist
:
140 if arg
.may_be_null() or i
in user_data_indices
:
141 # allow-none or user_data from a closure
143 elif arg
.is_optional():
144 argstr
+= '=<optional>'
145 in_args_strs
.append(argstr
)
146 in_args_str
= ', '.join(in_args_strs
)
148 # Build return + output argument strings
150 return_hint
= _get_pytype_hint(info
.get_return_type())
151 if not info
.skip_return() and return_hint
and return_hint
not in hint_blacklist
:
153 if info
.may_return_null():
155 out_args_strs
.append(argstr
)
157 for i
, arg
in enumerate(args
):
158 if arg
.get_direction() == Direction
.IN
:
159 continue # skip exclusively input args
160 if i
in ignore_indices
:
162 argstr
= arg
.get_name()
163 hint
= _get_pytype_hint(arg
.get_type())
164 if hint
not in hint_blacklist
:
166 out_args_strs
.append(argstr
)
169 return '%s(%s) -> %s' % (info
.__name
__, in_args_str
, ', '.join(out_args_strs
))
171 return '%s(%s)' % (info
.__name
__, in_args_str
)
174 def _generate_class_info_doc(info
):
175 header
= '\n:Constructors:\n\n::\n\n' # start with \n to avoid auto indent of other lines
178 if isinstance(info
, StructInfo
):
179 # Don't show default constructor for disguised (0 length) structs
180 if info
.get_size() > 0:
181 doc
+= ' ' + info
.get_name() + '()\n'
183 doc
+= ' ' + info
.get_name() + '(**properties)\n'
185 for method_info
in info
.get_methods():
186 if method_info
.is_constructor():
187 doc
+= ' ' + _generate_callable_info_doc(method_info
) + '\n'
195 def _generate_doc_dispatch(info
):
196 if isinstance(info
, (ObjectInfo
, StructInfo
)):
197 return _generate_class_info_doc(info
)
199 elif isinstance(info
, CallableInfo
):
200 return _generate_callable_info_doc(info
)
205 set_doc_string_generator(_generate_doc_dispatch
)