-
Notifications
You must be signed in to change notification settings - Fork 1.2k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Python docstring: argument names conflicting with python keywords, are systematically turned into argN #1272
Comments
Thanks for the report, I'll try to look at this, but it might not happen immediately. Does the problem occur only with the specified features, i.e. |
Hi @vadz, thank you very much for the help. Regarding your question: it does happen in all circumstances. Here's a combined test:
|
@vadz any chance you can look at this soon before we release SWIG 4.0.0? |
Give me until the end of the week to see if I can find time for this. If I can't, you probably shouldn't wait for me... |
Since commit fdc6bbe Python docstrings used the auto-generated parameter names of the form "argN" instead of the real parameter names, making them much less useful. Fix this by using the actual parameter name (renamed to avoid clashes with Python keywords if necessary) in the docstring. Unfortunately this means docstring is now inconsistent with the actual function definition, which still uses "argN", but this is not as simple to fix and this change could already be considered an improvement. See swig#1272.
I could make an ugly (adding yet another boolean parameter to a function already taking 3 of them) but simple (and so hopefully unlikely to break anything else) change, but it only fixes the name of the parameter in the doc string, not in the function signature itself, i.e. now def process(arg1):
r"""process(_from) -> int"""
... is generated. Fixing the name of the actual argument is less trivial, as the parameter names are not necessarily unique (e.g. So I'm going to submit this fix already, but I'm not sure if it really helps as now we have a mismatch between the docstring and the actual parameter and I guess this could be (even more?) problematic? |
Assume that only upper-case-only parameter names such as INPUT, OUTPUT, INOUT etc can be non-unique. This assumption allows to preserve the original parameters names in the generated Python code, including docstrings. See swig#1272.
I spent a bit more time on this and here is an alternative solution (i.e. at most one of #1394 and #1395 should be applied) which results in def process(_from):
r"""process(_from) -> int"""
... being generated, but it has its own problems: it assumes that only upper-case parameter names are special and can be non-unique (and hence need to be replaced with "argN"). This is not really the case in theory, i.e. nothing prevents you from using any (lower-case) "foo" twice in the parameter list neither, from SWIG point of view, but I think this shouldn't happen much in practice and, if it does, do we really need to support this, knowing that it's an error in both C and Python? |
I'd say the parameter names in the docstring should match the actual argument names. So #1394 is not ideal as it addresses half the problem (just corrects the documentation name). The base class implementation, that is, I'm not sure why check_kwargs(n) is used on the Node to override the base class implementation. Do you have an insight into that? Here are some simple tests to add in to the fix: diff --git a/Examples/test-suite/autodoc.i b/Examples/test-suite/autodoc.i
index 97c05d7..ec7307a 100644
--- a/Examples/test-suite/autodoc.i
+++ b/Examples/test-suite/autodoc.i
@@ -148,3 +148,11 @@ bool is_python_builtin() { return true; }
bool is_python_builtin() { return false; }
#endif
%}
+
+// Autodoc Python keywords
+%warnfilter(SWIGWARN_PARSE_KEYWORD) process;
+%feature(autodoc,0) process;
+%feature("compactdefaultargs") process;
+%inline %{
+int process(int from) { return from; }
+%}
diff --git a/Examples/test-suite/python/autodoc_runme.py b/Examples/test-suite/python/autodoc_runme.py
index 1350c6d..47f3a28 100644
--- a/Examples/test-suite/python/autodoc_runme.py
+++ b/Examples/test-suite/python/autodoc_runme.py
@@ -202,3 +202,7 @@ check(inspect.getdoc(banana), "banana(S a, S b, int c, Integer d)")
check(inspect.getdoc(TInteger), "Proxy of C++ T< int > class.", "::T< int >")
check(inspect.getdoc(TInteger.__init__), "__init__(TInteger self) -> TInteger", None, skip)
check(inspect.getdoc(TInteger.inout), "inout(TInteger self, TInteger t) -> TInteger")
+
+check(inspect.getdoc(process), "process(_from) -> int")
+if process(_from=10) != 10:
+ raise RuntimeError("failed!")
diff --git a/Examples/test-suite/python/keyword_rename_runme.py b/Examples/test-suite/python/keyword_re
index 5646ce7..0bdd64b 100644
--- a/Examples/test-suite/python/keyword_rename_runme.py
+++ b/Examples/test-suite/python/keyword_rename_runme.py
@@ -1,4 +1,6 @@
#!/usr/bin/env python
import keyword_rename
keyword_rename._in(1)
+keyword_rename._in(_except=1)
keyword_rename._except(1)
+keyword_rename._except(_in=1) |
OK, I'll try to do it properly. I still don't really understand what's the relationship between |
@vadz, I'm mostly concerned with fixing the regression for 4.0. From what I understand the documentation comment changed from |
Hi,
SWiG 2.0.12 used to rename python keyword-named C/C++ arguments, to an underscore-prefixed version, but SWiG 3.0.12 doesn't do than anymore (by default.)
Assuming an interface file such as:
using 2.0.12 we would get:
"""process(_from) -> int"""
But since the following changelist:
this has changed and we now get:
…which unfortunately is less useful.
Using the
-keyword
option, apparently gets us to the old behavior. But unfortunately this has side-effects, other than just making the documentation more useful (in particular, well, enabling keyword arguments, which isn't something we desire)Am I mistaken thinking that, regardless of whether or not kwargs are enabled for a given wrapper, the docstring shouldn't change? (or in any case not become less useful)
Thanks!
The text was updated successfully, but these errors were encountered: