diff --git a/CHANGES.current b/CHANGES.current index b9363f7d8..c81bdebde 100644 --- a/CHANGES.current +++ b/CHANGES.current @@ -7,6 +7,41 @@ the issue number to the end of the URL: https://github.com/swig/swig/issues/ Version 4.0.0 (in progress) =========================== +2019-01-16: wsfulton + Python static method wrapper changes + + - Static method wrappers were using the 'fastproxy' approach by default. + This is inconsistent with instance method wrappers. The fastproxy approach + is now turned off by default to be consistent with instance methods. + Static method wrappers can now also be controlled using the -fastproxy and + -olddefs options. + + Example: + + struct Klass { + static int statmethod(int a = 2); + }; + + generates by default: + + class Klass(object): + ... + @staticmethod + def statmethod(a=2): + return _example.Klass_statmethod(a) + + instead of the following (which can be restored by using -fastproxy): + + class Klass(object): + ... + statmethod = staticmethod(_example.Klass_statmethod) + + +- Modernise wrappers for static methods to use decorator syntax - @staticmethod. + +- Add missing runtime test for static class methods and using the actual class method. + + 2019-01-12: ZackerySpytz [OCaml] #1403 #1194 Fix compilation problems for OCaml >= 4.03.0 due to OCaml using int64_t instead of int64. diff --git a/Examples/test-suite/python/callback_runme.py b/Examples/test-suite/python/callback_runme.py index ef7baad4e..91518fbf2 100644 --- a/Examples/test-suite/python/callback_runme.py +++ b/Examples/test-suite/python/callback_runme.py @@ -13,6 +13,9 @@ if foobar(3, _callback.foo) != foo(3): if foobar(3, foo) != foo(3): raise RuntimeError +if foobar(3, A.bar) != A.bar(3): + raise RuntimeError + if foobar(3, A_bar) != A_bar(3): raise RuntimeError diff --git a/Source/Modules/python.cxx b/Source/Modules/python.cxx index 83858d44c..d3d157ddf 100755 --- a/Source/Modules/python.cxx +++ b/Source/Modules/python.cxx @@ -4637,10 +4637,12 @@ public: } if (shadow) { - if (!Getattr(n, "feature:python:callback") && have_addtofunc(n)) { + bool fast = (fastproxy && !have_addtofunc(n)) || Getattr(n, "feature:callback"); + if (!fast || olddefs) { int kw = (check_kwargs(n) && !Getattr(n, "sym:overloaded")) ? 1 : 0; String *parms = make_pyParmList(n, false, false, kw); String *callParms = make_pyParmList(n, false, true, kw); + Printv(f_shadow, "\n", tab4, "@staticmethod", NIL); Printv(f_shadow, "\n", tab4, "def ", symname, "(", parms, ")", returnTypeAnnotation(n), ":\n", NIL); if (have_docstring(n)) Printv(f_shadow, tab8, docstring(n, AUTODOC_STATICFUNC, tab8), "\n", NIL); @@ -4649,12 +4651,14 @@ public: if (have_pythonappend(n)) { Printv(f_shadow, tab8, "val = ", funcCall(Swig_name_member(NSPACE_TODO, class_name, symname), callParms), "\n", NIL); Printv(f_shadow, indent_pythoncode(pythonappend(n), tab8, Getfile(n), Getline(n), "%pythonappend or %feature(\"pythonappend\")"), "\n", NIL); - Printv(f_shadow, tab8, "return val\n\n", NIL); + Printv(f_shadow, tab8, "return val\n", NIL); } else { - Printv(f_shadow, tab8, "return ", funcCall(Swig_name_member(NSPACE_TODO, class_name, symname), callParms), "\n\n", NIL); + Printv(f_shadow, tab8, "return ", funcCall(Swig_name_member(NSPACE_TODO, class_name, symname), callParms), "\n", NIL); } - Printv(f_shadow, tab4, symname, " = staticmethod(", symname, ")\n", NIL); - } else { + } + + // Below may result in a 2nd definition of the method when -olddefs is used. The Python interpreter will use the second definition as it overwrites the first. + if (fast) { Printv(f_shadow, tab4, symname, " = staticmethod(", module, ".", Swig_name_member(NSPACE_TODO, class_name, symname), ")\n", NIL); }