diff --git a/CHANGES.current b/CHANGES.current index afe54e293..94eac2347 100644 --- a/CHANGES.current +++ b/CHANGES.current @@ -5,6 +5,9 @@ See the RELEASENOTES file for a summary of changes in each release. Version 3.0.6 (in progress) =========================== +2015-04-23: vadz + [Python] Fix the use of default values for the pointer types (#365, #376). + 2015-04-23: wsfulton Fix 'make check-ccache' which is part of 'make check' when one of the CCACHE_ environment variables, for example CCACHE_DISABLE, is set. diff --git a/Examples/test-suite/default_args.i b/Examples/test-suite/default_args.i index bcb8766a8..2c1187fb5 100644 --- a/Examples/test-suite/default_args.i +++ b/Examples/test-suite/default_args.i @@ -115,6 +115,7 @@ %rename(renamed1arg) Foo::renameme() const; %inline %{ + typedef void* MyHandle; // Define a class class Foo { @@ -139,6 +140,10 @@ // test the method itself being renamed void oldname(int x = 1234) {} void renameme(int x = 1234, double d=123.4) const {} + + // test default values for pointer arguments + int double_if_void_ptr_is_null(int n, void* p = NULL) { return p ? n : 2*n; } + int double_if_handle_is_null(int n, MyHandle h = 0) { return h ? n : 2*n; } }; int Foo::bar = 1; int Foo::spam = 2; diff --git a/Examples/test-suite/python/default_args_runme.py b/Examples/test-suite/python/default_args_runme.py index 25bef14ca..62ba0ea78 100644 --- a/Examples/test-suite/python/default_args_runme.py +++ b/Examples/test-suite/python/default_args_runme.py @@ -31,6 +31,17 @@ def run(module_name): f.newname() f.newname(1) + if f.double_if_void_ptr_is_null(2, None) != 4: + raise RuntimeError + + if f.double_if_void_ptr_is_null(3) != 6: + raise RuntimeError + + if f.double_if_handle_is_null(4, None) != 8: + raise RuntimeError + + if f.double_if_handle_is_null(5) != 10: + raise RuntimeError try: f = default_args.Foo(1) diff --git a/Source/Modules/python.cxx b/Source/Modules/python.cxx index bc31c4264..17ffbbd67 100644 --- a/Source/Modules/python.cxx +++ b/Source/Modules/python.cxx @@ -1827,6 +1827,20 @@ public: return doc; } + /* ------------------------------------------------------------ + * isPointerType() + * Return true if the given type is a pointer after resolving + * it if it's a typedef. This should be typically used instead + * of SwigType_ispointer(), unless the type is already resolved. + * ------------------------------------------------------------ */ + static bool isPointerType(SwigType* t) { + SwigType* const full_type = SwigType_typedef_resolve_all(t); + bool const ispointer = SwigType_ispointer(full_type); + Delete(full_type); + + return ispointer; + } + /* ------------------------------------------------------------ * convertDoubleValue() * Check if the given string looks like a decimal floating point constant @@ -1922,7 +1936,7 @@ public: if (Len(v) == 1) { // This is just a lone 0, but it needs to be represented differently // in Python depending on whether it's a zero or a null pointer. - if (SwigType_ispointer(t)) + if (isPointerType(t)) return NewString("None"); else return v; @@ -1959,7 +1973,7 @@ public: if (Strcmp(v, "false") == 0 || Strcmp(v, "FALSE") == 0) return NewString("False"); if (Strcmp(v, "NULL") == 0 || Strcmp(v, "nullptr") == 0) - return SwigType_ispointer(t) ? NewString("None") : NewString("0"); + return isPointerType(t) ? NewString("None") : NewString("0"); // This could also be an enum type, default value of which could be // representable in Python if it doesn't include any scope (which could,