diff --git a/CHANGES.current b/CHANGES.current index 94eac2347..24c36d6a0 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] Make "default" typemap work again (#330, #377). + 2015-04-23: vadz [Python] Fix the use of default values for the pointer types (#365, #376). diff --git a/Examples/test-suite/default_args.i b/Examples/test-suite/default_args.i index 2c1187fb5..4ab24d335 100644 --- a/Examples/test-suite/default_args.i +++ b/Examples/test-suite/default_args.i @@ -114,6 +114,8 @@ %rename(renamed2arg) Foo::renameme(int x) const; %rename(renamed1arg) Foo::renameme() const; +%typemap(default) double* null_by_default "$1=0;"; + %inline %{ typedef void* MyHandle; @@ -144,6 +146,8 @@ // 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 double_if_dbl_ptr_is_null(int n, double* null_by_default) + { return null_by_default ? 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 62ba0ea78..18cc2c27a 100644 --- a/Examples/test-suite/python/default_args_runme.py +++ b/Examples/test-suite/python/default_args_runme.py @@ -43,6 +43,12 @@ def run(module_name): if f.double_if_handle_is_null(5) != 10: raise RuntimeError + if f.double_if_dbl_ptr_is_null(6, None) != 12: + raise RuntimeError + + if f.double_if_dbl_ptr_is_null(7) != 14: + raise RuntimeError + try: f = default_args.Foo(1) error = 1 diff --git a/Source/Modules/python.cxx b/Source/Modules/python.cxx index 5ae4b6d55..ca9e7f2ba 100644 --- a/Source/Modules/python.cxx +++ b/Source/Modules/python.cxx @@ -1999,9 +1999,9 @@ public: * at C++ code level where they can always be handled. * ------------------------------------------------------------ */ bool is_representable_as_pyargs(Node *n) { - bool is_representable = true; - ParmList *plist = CopyParmList(Getattr(n, "parms")); + Swig_typemap_attach_parms("default", plist, NULL); + Parm *p; Parm *pnext; @@ -2017,16 +2017,23 @@ public: if (!pnext) { pnext = nextSibling(p); } + + // "default" typemap can contain arbitrary C++ code, so while it could, in + // principle, be possible to examine it and check if it's just something + // simple of the form "$1 = expression" and then use convertValue() to + // check if expression can be used in Python, but for now we just + // pessimistically give up and prefer to handle this at C++ level only. + if (Getattr(p, "tmap:default")) + return false; + if (String *value = Getattr(p, "value")) { String *type = Getattr(p, "type"); - if (!convertValue(value, type)) { - is_representable = false; - break; - } + if (!convertValue(value, type)) + return false; } } - return is_representable; + return true; }