From bfde14888745fb3f8d83bd7e8d8f1b8df1826db8 Mon Sep 17 00:00:00 2001
From: William S Fulton
Date: Tue, 21 Oct 2014 07:32:45 +0100
Subject: [PATCH] The kwargs feature no longer turns on compactdefaultargs for
languages that don't support kwargs.
Affects all languages except Python and Ruby.
Closes #242
---
CHANGES.current | 7 ++++++
Doc/Manual/SWIGPlus.html | 6 +++--
Examples/test-suite/common.mk | 1 +
.../test-suite/java/kwargs_feature_runme.java | 23 +++++++++++++++++++
Examples/test-suite/kwargs_feature.i | 18 ++++-----------
Examples/test-suite/python/Makefile.in | 1 -
.../test-suite/python/kwargs_feature_runme.py | 4 ++--
Examples/test-suite/ruby/Makefile.in | 1 -
Source/CParse/parser.y | 3 ++-
Source/Modules/lang.cxx | 8 +++++++
Source/Modules/main.cxx | 3 +++
Source/Modules/python.cxx | 7 ++++++
Source/Modules/ruby.cxx | 8 +++++++
Source/Modules/swigmod.h | 3 +++
14 files changed, 72 insertions(+), 21 deletions(-)
create mode 100644 Examples/test-suite/java/kwargs_feature_runme.java
diff --git a/CHANGES.current b/CHANGES.current
index cc8406221..85f9a0110 100644
--- a/CHANGES.current
+++ b/CHANGES.current
@@ -5,6 +5,13 @@ See the RELEASENOTES file for a summary of changes in each release.
Version 3.0.3 (in progress)
===========================
+2014-10-21: wsfulton
+ Fix issue #242 - Use of the "kwargs" feature no longer automatically turns on the
+ "compactdefaultargs" feature if the target language does not support kwargs.
+ Only Java and Python support kwargs, so this affects all the other languages.
+
+ *** POTENTIAL INCOMPATIBILITY ***
+
2014-10-10: diorcety
[Python] Patch #232 Fix property access using directors
diff --git a/Doc/Manual/SWIGPlus.html b/Doc/Manual/SWIGPlus.html
index 9589bf16c..6aaef07b4 100644
--- a/Doc/Manual/SWIGPlus.html
+++ b/Doc/Manual/SWIGPlus.html
@@ -1191,8 +1191,10 @@ values have to be public).
-This feature is automatically turned on when wrapping C code with default arguments
-and whenever keyword arguments (kwargs) are specified for either C or C++ code.
+The compactdefaultargs feature is automatically turned on when wrapping C code with default arguments.
+Some target languages will also automatically turn on this feature
+if the keyword arguments feature (kwargs) is specified for either C or C++ functions, and the target language supports kwargs,
+the compactdefaultargs feature is also automatically turned on.
Keyword arguments are a language feature of some scripting languages, for example Ruby and Python.
SWIG is unable to support kwargs when wrapping overloaded methods, so the default approach cannot be used.
diff --git a/Examples/test-suite/common.mk b/Examples/test-suite/common.mk
index c8a67283c..f985b55d1 100644
--- a/Examples/test-suite/common.mk
+++ b/Examples/test-suite/common.mk
@@ -249,6 +249,7 @@ CPP_TEST_CASES += \
insert_directive \
keyword_rename \
kind \
+ kwargs_feature \
langobj \
li_attribute \
li_attribute_template \
diff --git a/Examples/test-suite/java/kwargs_feature_runme.java b/Examples/test-suite/java/kwargs_feature_runme.java
new file mode 100644
index 000000000..ba742d9ec
--- /dev/null
+++ b/Examples/test-suite/java/kwargs_feature_runme.java
@@ -0,0 +1,23 @@
+import kwargs_feature.*;
+
+public class kwargs_feature_runme {
+
+ static {
+ try {
+ System.loadLibrary("kwargs_feature");
+ } catch (UnsatisfiedLinkError e) {
+ System.err.println("Native code library failed to load. See the chapter on Dynamic Linking Problems in the SWIG Java documentation for help.\n" + e);
+ System.exit(1);
+ }
+ }
+
+ public static void main(String argv[]) {
+ // Check normal overloading still works (no compactdefaultargs) if the kwargs feature is used,
+ // as the kwargs feature is not supported
+ Foo f = new Foo(99);
+ if (f.foo() != 1)
+ throw new RuntimeException("It went wrong");
+ if (Foo.statfoo(2) != 2)
+ throw new RuntimeException("It went wrong");
+ }
+}
diff --git a/Examples/test-suite/kwargs_feature.i b/Examples/test-suite/kwargs_feature.i
index 87153109a..a935b25f3 100644
--- a/Examples/test-suite/kwargs_feature.i
+++ b/Examples/test-suite/kwargs_feature.i
@@ -1,7 +1,7 @@
%module kwargs_feature
%nocopyctor;
-%kwargs;
+%feature("kwargs");
%rename(myDel) del;
%inline
@@ -35,9 +35,7 @@
virtual ~Foo() {
}
-
};
-
%}
@@ -64,8 +62,7 @@
// Functions
%inline %{
- int foo(int a = 1, int b = 0) {return a + b; }
-
+ int foo_fn(int a = 1, int b = 0) {return a + b; }
template T templatedfunction(T a = 1, T b = 0) { return a + b; }
%}
@@ -73,10 +70,8 @@
%template(templatedfunction) templatedfunction;
-// Deafult args with references
-%inline
-%{
-
+// Default args with references
+%inline %{
typedef int size_type;
struct Hello
@@ -84,13 +79,10 @@
static const size_type hello = 3;
};
-
-
int rfoo( const size_type& x = Hello::hello, const Hello& y = Hello() )
{
return x;
}
-
%}
%{
const int Hello::hello;
@@ -104,9 +96,7 @@
int foo_kw(int from = 1, int except = 2) {return from + except; }
-
int foo_nu(int from = 1, int = 0) {return from; }
int foo_mm(int min = 1, int max = 2) {return min + max; }
-
%}
diff --git a/Examples/test-suite/python/Makefile.in b/Examples/test-suite/python/Makefile.in
index c39a9c806..c79a786da 100644
--- a/Examples/test-suite/python/Makefile.in
+++ b/Examples/test-suite/python/Makefile.in
@@ -39,7 +39,6 @@ CPP_TEST_CASES += \
inout \
inplaceadd \
input \
- kwargs_feature \
li_cstring \
li_cwstring \
li_factory \
diff --git a/Examples/test-suite/python/kwargs_feature_runme.py b/Examples/test-suite/python/kwargs_feature_runme.py
index 5539e211d..7792e2e06 100644
--- a/Examples/test-suite/python/kwargs_feature_runme.py
+++ b/Examples/test-suite/python/kwargs_feature_runme.py
@@ -44,10 +44,10 @@ if BarInt_sbar(b=2) != 3:
if templatedfunction(b=2) != 3:
raise RuntimeError
-if foo(a=1,b=2) != 3:
+if foo_fn(a=1,b=2) != 3:
raise RuntimeError
-if foo(b=2) != 3:
+if foo_fn(b=2) != 3:
raise RuntimeError
diff --git a/Examples/test-suite/ruby/Makefile.in b/Examples/test-suite/ruby/Makefile.in
index 1a6875360..ae4995882 100644
--- a/Examples/test-suite/ruby/Makefile.in
+++ b/Examples/test-suite/ruby/Makefile.in
@@ -11,7 +11,6 @@ top_srcdir = @top_srcdir@
top_builddir = @top_builddir@
CPP_TEST_CASES = \
- kwargs_feature \
li_cdata \
li_cstring \
li_factory \
diff --git a/Source/CParse/parser.y b/Source/CParse/parser.y
index b334ace76..61b0462b5 100644
--- a/Source/CParse/parser.y
+++ b/Source/CParse/parser.y
@@ -59,6 +59,7 @@ static int compact_default_args = 0;
static int template_reduce = 0;
static int cparse_externc = 0;
int ignore_nested_classes = 0;
+int kwargs_supported = 0;
/* -----------------------------------------------------------------------------
* Assist Functions
* ----------------------------------------------------------------------------- */
@@ -1177,7 +1178,7 @@ static void default_arguments(Node *n) {
if (compact_default_args
|| is_cfunction(function)
|| GetFlag(function,"feature:compactdefaultargs")
- || GetFlag(function,"feature:kwargs")) {
+ || (GetFlag(function,"feature:kwargs") && kwargs_supported)) {
ParmList *p = Getattr(function,"parms");
if (p)
Setattr(p,"compactdefargs", "1"); /* mark parameters for special handling */
diff --git a/Source/Modules/lang.cxx b/Source/Modules/lang.cxx
index 9fa52cd2c..5b1547487 100644
--- a/Source/Modules/lang.cxx
+++ b/Source/Modules/lang.cxx
@@ -3525,6 +3525,14 @@ Language::NestedClassSupport Language::nestedClassesSupport() const {
return NCS_Unknown;
}
+/* -----------------------------------------------------------------------------
+ * Language::kwargsSupport()
+ * ----------------------------------------------------------------------------- */
+
+bool Language::kwargsSupport() const {
+ return false;
+}
+
/* -----------------------------------------------------------------------------
* Language::is_wrapping_class()
* ----------------------------------------------------------------------------- */
diff --git a/Source/Modules/main.cxx b/Source/Modules/main.cxx
index 47d0d374b..f41844d34 100644
--- a/Source/Modules/main.cxx
+++ b/Source/Modules/main.cxx
@@ -50,6 +50,7 @@ int SwigRuntime = 0; // 0 = no option, 1 = -runtime, 2 = -noruntime
extern "C" {
extern String *ModuleName;
extern int ignore_nested_classes;
+ extern int kwargs_supported;
}
/* usage string split into multiple parts otherwise string is too big for some compilers */
@@ -904,6 +905,8 @@ int SWIG_main(int argc, char *argv[], Language *l) {
// Inform the parser if the nested classes should be ignored unless explicitly told otherwise via feature:flatnested
ignore_nested_classes = l->nestedClassesSupport() == Language::NCS_Unknown ? 1 : 0;
+ kwargs_supported = l->kwargsSupport() ? 1 : 0;
+
// Create Library search directories
// Check for SWIG_LIB environment variable
diff --git a/Source/Modules/python.cxx b/Source/Modules/python.cxx
index c5e4b63f6..b14f0903d 100644
--- a/Source/Modules/python.cxx
+++ b/Source/Modules/python.cxx
@@ -4785,6 +4785,13 @@ public:
return NewString("swigpyrun.h");
}
+ /*----------------------------------------------------------------------
+ * kwargsSupport()
+ *--------------------------------------------------------------------*/
+
+ bool kwargsSupport() const {
+ return true;
+ }
};
/* ---------------------------------------------------------------
diff --git a/Source/Modules/ruby.cxx b/Source/Modules/ruby.cxx
index 6aeaae5a1..310e89b82 100644
--- a/Source/Modules/ruby.cxx
+++ b/Source/Modules/ruby.cxx
@@ -3426,6 +3426,14 @@ public:
String *defaultExternalRuntimeFilename() {
return NewString("swigrubyrun.h");
}
+
+ /*----------------------------------------------------------------------
+ * kwargsSupport()
+ *--------------------------------------------------------------------*/
+
+ bool kwargsSupport() const {
+ return true;
+ }
}; /* class RUBY */
/* -----------------------------------------------------------------------------
diff --git a/Source/Modules/swigmod.h b/Source/Modules/swigmod.h
index 63b91bae5..33fecbcc7 100644
--- a/Source/Modules/swigmod.h
+++ b/Source/Modules/swigmod.h
@@ -315,6 +315,9 @@ public:
*/
virtual NestedClassSupport nestedClassesSupport() const;
+ /* Returns true if the target language supports key word arguments (kwargs) */
+ virtual bool kwargsSupport() const;
+
protected:
/* Identifies if a protected members that are generated when the allprotected option is used.
This does not include protected virtual methods as they are turned on with the dirprot option. */