Fix handling of NULL default argument values for pointer types.

Accept not only manifest pointer types (such as e.g. "void *") but also types
that are typedefs for pointer types when checking whether C++ value of 0 must
be represented as 0 or None in Python.

Closes #365, #376.
This commit is contained in:
Vadim Zeitlin 2015-04-22 19:30:55 +02:00
commit 0eae8a8efa
4 changed files with 35 additions and 2 deletions

View file

@ -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.

View file

@ -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;

View file

@ -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)

View file

@ -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,