summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNiels De Graef <nielsdegraef@gmail.com>2020-12-27 17:14:19 +0100
committerNiels De Graef <nielsdegraef@gmail.com>2021-01-31 23:06:22 +0100
commit77de3fcc616757c775895873ccabc79ce865fe9b (patch)
tree4320fbe95a9c53f615ffd6516df85dad5cc33277
parent5ed5b1ed30938dbe70e50feffa56ee5ee47696d2 (diff)
downloadgobject-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.tmpl10
-rw-r--r--giscanner/docwriter.py44
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):