diff options
author | Niels De Graef <nielsdegraef@gmail.com> | 2020-12-27 17:14:19 +0100 |
---|---|---|
committer | Niels De Graef <nielsdegraef@gmail.com> | 2021-01-31 23:06:22 +0100 |
commit | 77de3fcc616757c775895873ccabc79ce865fe9b (patch) | |
tree | 4320fbe95a9c53f615ffd6516df85dad5cc33277 | |
parent | 5ed5b1ed30938dbe70e50feffa56ee5ee47696d2 (diff) | |
download | gobject-introspection-wip/nielsdg/python-formatter-out-params.tar.gz |
docwriter: Fix (out) arguments for Pythonwip/nielsdg/python-formatter-out-params
The documentation formatter for Python3 doesn't properly deal with
`(out)` arguments, which leads to those being added as function
arguments, rather than return values. This commit fixes that by mostly
copying the logic from the GJS formatter.
For future work, it might be worth looking into whether Python type
annotations can be used to add types to arguments.
Fixes https://gitlab.gnome.org/GNOME/gobject-introspection/-/issues/235
-rw-r--r-- | giscanner/doctemplates/mallard/Python/function.tmpl | 10 | ||||
-rw-r--r-- | giscanner/docwriter.py | 44 |
2 files changed, 48 insertions, 6 deletions
diff --git a/giscanner/doctemplates/mallard/Python/function.tmpl b/giscanner/doctemplates/mallard/Python/function.tmpl index 7ad1ac04..10481a35 100644 --- a/giscanner/doctemplates/mallard/Python/function.tmpl +++ b/giscanner/doctemplates/mallard/Python/function.tmpl @@ -23,7 +23,7 @@ % if formatter.get_in_parameters(node): @accepts(${', '.join((formatter.format_type(arg.type) for arg in formatter.get_in_parameters(node)))}) % endif -@returns(${formatter.format_type(node.retval.type) | x}) +@returns(${', '.join((formatter.format_type(arg.type) for arg in formatter.get_out_parameters(node)))}) def ${node.name}(${', '.join((formatter.format_parameter_name(node, arg) for arg in formatter.get_in_parameters(node)))}): # Python wrapper for ${node.symbol}() </code></synopsis></%block> @@ -36,12 +36,12 @@ def ${node.name}(${', '.join((formatter.format_parameter_name(node, arg) for arg ${formatter.format(node, arg.doc)} </item> % endfor -% if node.retval and node.retval.type.ctype != 'void': +% for arg in formatter.get_out_parameters(node): <item> -<title><code>Returns</code></title> -{formatter.format(node, node.retval.doc)} +<title><code>${(arg.argname + ' (out)')}</code></title> +${formatter.format(node, arg.doc)} </item> -% endif +% endfor </terms> % endif </%block> diff --git a/giscanner/docwriter.py b/giscanner/docwriter.py index 786da80d..96063dc9 100644 --- a/giscanner/docwriter.py +++ b/giscanner/docwriter.py @@ -810,7 +810,49 @@ class DocFormatterPython(DocFormatterIntrospectableBase): return func.name def get_in_parameters(self, node): - return node.all_parameters + skip = set() + for param in node.all_parameters: + if param.direction == ast.PARAM_DIRECTION_OUT: + skip.add(param) + if isinstance(param.type, ast.Array) and param.type.length_param_name is not None: + skip.add(node.get_parameter(param.type.length_param_name)) + + params = [] + for param in node.parameters: + if param not in skip: + params.append(param) + return params + + def get_out_parameters(self, node): + # First make a list of parameters we should skip anyhow + skip = set() + for param in node.parameters: + if param.direction == ast.PARAM_DIRECTION_IN: + skip.add(param) + if isinstance(param.type, ast.Array) and param.type.length_param_name is not None: + skip.add(node.get_parameter(param.type.length_param_name)) + + # Now build the actual list of out parameters + params = [] + # First the return value + if node.retval.type.target_fundamental != 'none': + name = 'return_value' + if node.retval.type.target_fundamental == 'gboolean': + name = 'ok' + + ret_param = ast.Parameter(name, node.retval.type, + ast.PARAM_DIRECTION_OUT) + ret_param.doc = node.retval.doc + params.append(ret_param) + # Next, each parameter marked as (out) + for param in node.parameters: + if param not in skip: + params.append(param) + + if len(params) == 1: + params[0].argname = 'Returns' + + return params class DocFormatterGjs(DocFormatterIntrospectableBase): |