SWIG-4.4.1 released
SWIG-4.4.0 released
c840bb728a886fd8b9a9f241c2d2b603f0e7a91b changed this code to make type casting threadsafe. It's hard to be sure without having a reproducer, but it looks like the problem may still exist as cast->type is still only updated here if (type == swig_module.type_initial[i]).
We're still generating the same code AFAICS. Retesting though I found it does actually work provided you use consistent naming: $ RUBY=ruby3.2 $ echo '%module OpenBabel' > test.i $ swig -ruby test.i $ g++ -shared -fPIC \ -I"`$RUBY -r rbconfig -e 'puts(RbConfig::CONFIG["rubyhdrdir"] || "")'`" \ -I"`$RUBY -r rbconfig -e 'puts(RbConfig::CONFIG["rubyarchhdrdir"] || "")'`" \ -o OpenBabel.so test_wrap.c $ $RUBY -I. -e 'require "OpenBabel"' $ So if you use %module OpenBabel then you need to name the shared...
I've merged fixes for the remaining cases here - should be released in SWIG 4.4.0.
syntax error when parsing complex default values
Moved to https://github.com/swig/swig/issues/3197 in the live tracker
templates using import fails
I'm going to close as a duplicate of the newer ticket in the live tracker, and note there that the testcase here should be checked against any candidate fix.
no warning for multiple %module statements
We also rely on this being accepted in some testcases - e.g. preproc_constants_c.i contains %include "preproc_constants.i" but both contain %module directives. I can see an argument for warning about this, but %module is both conventionally and most naturally put at the very top of the file, so in practice I don't think this situation is going to occur in a way which causes confusion in real world use. Fixing would seem to require adding a warning and adjusting all the uses in the testsuite to either...
SWIG-4.3.1 released
I can imagine a pile of difficulties in the implementation and ambiguities in cases such as: void x(int& a, int& b, int& c, int& d); and multiple variations of the multi-arg typemaps in this ticket being present. If just the first name has to match, it is unambiguous as to whether or not the multi-argument typemap matches (once the subsequent parameters are checked). I suppose some more flexible rules around such ambiguities could be defined and implemented, however, I would document it as it works...
C++ memory leak of temporaries on exception
Fix in git by c77498d5db7f661859fdc86eeb277ab6c67f7fbf.
SWIG generates invalid code for 2D array of int*
SWIG generates invalid code for 2D array of function pointers
Lifecycle of pointers to 'concrete' sub-objects (C#-binding patch included)
The solution was documented in the C# docs last year, but was only detailed for accessor methods to member variables. The same technique can be used for direct member access and I've just enhanced the docs with this, see the version in master: https://htmlpreview.github.io/?https://github.com/swig/swig/blob/master/Doc/Manual/CSharp.html#CSharp_memory_management_member_variables . I can't see the swig-2.0.4-csharp-concrete.patch being accepted as is, but maybe with improvements as some sort of special...
Reproducible with SWIG 4.3.0. Looking at the manual again, this part does actually seem to suggest that types without names should work: Each type pattern is either a simple type, a simple type and argument name, or a list of types in the case of multi-argument typemaps. @wsfulton Do you think this is a code bug or a documentation bug? I looked at the code and it makes my head spin, but I could fix the docs to clearly say this isn't supported (from my testing the first argument in a multi-argument...
Reproduced with current git master. Interestingly %typemap(default) (int &a, int &) { also works, but %typemap(default) (int &, int &b) { doesn't. I don't see where in the docs it explicitly says that omitting the parameter names should work though. I do see this text (which has been there since before 2002 it seems): Multi-argument typemaps are also more restrictive in the way that they are matched. Currently, the first argument follows the matching rules described in the previous section, but all...
OUTPUT typemap for references in Lua not working
Looking at this again in more detail, I think SWIG's default wrapping is actually reasonable here. In case of OUTPUT the wrapper routine should create the output object and send the dereferenced pointer to the C++ routine. Then the object should be returned by Lua. My filled-in reproducer above could not be automatically wrapped as you suggest because there's no default constructor for MyType so the output object creation would also need to be told how to construct a suitable dummy object. The typemap...
SWIG-4.3.0 released
@wsfulton Did your recent nested class change to -xml address this too?
Looking into this, the cause of the leak is actually quite obvious - we have this vtablearray as a member of the object and use it to cache swig::SwigVar_PyObject for each method looked up, which wraps a PyObject but we never free these anywhere. That effectively means we leak a PyObject* for each directed method per object. This isn't quite right - swig::SwigVar_PyObject is effectively a smart pointer to a PyObject which decrements the reference count on destruction. Johan's explanation in the original...
I also realised that the current -dirvtable isn't correct in the face of monkey patching of a method of an object after it has first been called - it'll cache the original version. Caching the Python string name for the object doesn't suffer from this issue. It's arguably a corner case, but it's not nice that it affects the Python semantics of calling a method. (If we did drop the caching of methods, it would also fix https://sourceforge.net/p/swig/bugs/868/)
Hmm, there seems to be a huge range of variation in the timings I get. Maybe I need to repeat using something like Python's timeit module which is designed for microbenchmarking.
If we just cache the return values from SWIG_Python_str_FromChar("foo") which avoids converting the method name to a python string on each call we seem to actually get all the gain the optimisation gives without any measurable overhead in the short-lived object case and without the leak: real 0m2.724s user 0m2.720s sys 0m0.004s (better than 3.795s; within the noise of 2.779s) real 0m2.136s user 0m2.132s sys 0m0.004s (within the noise of 2.184s; better than 3.631s) I think we should replace -dirvtable...
Oh except that can't work in the face of monkey patching, because a method can vary per-object: class A: def __init__(s): pass def t(s): print("A::t") a=A() def new_a_t(): print("new_a_t") a.t = new_a_t a2=A() a.t() a2.t() I did a quick benchmark to see how much this optimisation helps in something like the best case: from leaktest import * class Bar(Foo): def foo(self): return 0.0 b = Bar() for j in range(10000000): c = foo(b) The optimisation does make a clear difference in this case - without...
This looks promising: >>> class A: ... pass ... >>> a=A() >>> t = type(a) >>> t._swig_vtable=(None, None) >>> a2=A() >>> type(a2)._swig_vtable (None, None) If we just store the vtable as an attribute of the type then we only have one instance per Python subclass. Not sure if type objects can be deleted, but if they can then Python should automatically clean this up for us.
Still reproducible with git master shortly before 4.3.0. Looking into this, the cause of the leak is actually quite obvious - we have this vtablearray as a member of the object and use it to cache swig::SwigVar_PyObject for each method looked up, which wraps a PyObject but we never free these anywhere. That effectively means we leak a PyObject* for each directed method per object. We could probably call Py_DECREF() on these in the destructor, but it seems non-ideal that we cache per object as the...
[java] missing unsigned long long array typemaps
Looks like this was addressed in SWIG 4.1.0 so closing - this was the commit: commit 1eebc2335a7d607e3bb7466ce125a9495304c029 Author: Andy Polyakov <appro@cryptogams.org> Date: Sun Jan 24 13:01:36 2021 +0100 Lib/java/arrays_java.i: use actual C/C++ type in JAVA_ARRAYS_TYPEMAPS. long long[] map was using JNI type as C/C++ type. General spirit of JAVA_ARRAYS_TYPEMAPS is to cast individual array elements, not to rely on potentially incompatible pointer casts. diff --git a/Lib/java/arrays_java.i b/Lib/java/arrays_java.i...
Refcount (SmartPointer / Implicit conv) & threads
I'm going to close this as splitting this over two tickets doesn't seem helpful. I have copied the relevant info to the patch ticket.
FIX [ swig-Bugs-3541652 ] Refcount (SmartPointer / Implicit
[java] bad code generation for typedef'd enums
Closing in favour of https://github.com/swig/swig/issues/3012
Reproduced with current git master (6eb2560e8d7192a8302e90ca3426df9aceb6d2e2). I noticed that if we ignore the methods we don't want then it works - e.g. add this before the %include "classes.h";: %ignore return_float(float &f); This is at least consistent with how method hiding would work if the %extend method was actually added in C++, consider this: #include <iostream> class C { public: virtual void return_float(float &f) { f = 123; } float return_float() { float f; return_float(f); return f;...
The case where the value is a pointer type raised in the comments above is https://github.com/swig/swig/issues/2938 (and also https://sourceforge.net/p/swig/bugs/1235/ which I've closed as a duplicate of the ticket in the active bug tracker).
wsfulton: With the change discussed above the template would still be instantiated before being used as a base class - the idea is to allow having the %template EARLIER, in particular before the C++ template definition. This would address the current awkward situation where a %template directive needs to be in the middle of a third-party C++ header which is being wrapped. This means the %template directive would need to be stored and processed later. The exact point to process seems a bit tricky,...
The documentation, https://swig.org/Doc4.1/SWIGPlus.html#SWIGPlus_template_class_inheritance, does clearly state that you need to instantiate a template before it is used as a base class. Any change from this behaviour will be a major change.
Python, map of pointer
Same problem was reported in the github tracker so closing this as a duplicate: https://github.com/swig/swig/issues/2938
This patch fixes the example here, but seems a bit of a hack as it just allows anything to be passed for this parameter, but with the lowest typecheck precedence. Ideally we should actually check for what's accepted her, though the in typemap allows anything so maybe that's actually correct: diff --git a/Lib/lua/lua_fnptr.i b/Lib/lua/lua_fnptr.i index b4c663c5..8e67d8fb 100644 --- a/Lib/lua/lua_fnptr.i +++ b/Lib/lua/lua_fnptr.i @@ -115,6 +115,9 @@ void swiglua_ref_get(SWIGLUA_REF* pref){ %} +%typemap(typecheck,...
[csharp] getCPtr should use object.ReferenceEquals
I'm not sure it will be easy to keep the code based maintained to always cover this corner case. The relevant typemaps can be easily changed by the user to use ReferenceEquals instead and so I'm closing as won't change. I can't there being a runtime overhead when there is no operator== overload.
SWIG-4.2.1 released
Looks like https://github.com/swig/swig/issues/197 may be the same issue.
Still reproducible with current git master. Also I came up with a much simpler reproducer: %module x %inline %{ typedef enum { BAZ1 } baz; void enumbugexample( baz const & ) { } %} Then: $ swig -c++ -python simplified.i $ grep 'enum baz' simplified_wrap.cxx enumbugexample((enum baz const &)*arg1); static swig_type_info _swigt__p_baz = {"_p_baz", "baz *|enum baz *", 0, 0, (void*)0, 0}; The const & seems to be needed. I notice the type info entry includes enum baz * which seems wrong too.
I noticed the problem reported here is actually documented in the manual: https://www.swig.org/Doc4.2/SWIGPlus.html#SWIGPlus_namespaces Because namespaces are flattened, it is possible for symbols defined in different namespaces to generate a name conflict in the target language. For example: namespace A { void foo(int); } namespace B { void foo(double); } When this conflict occurs, you will get an error message that resembles this: example.i:26. Error. 'foo' is multiply defined in the generated...
Still present in git shortly after 4.2.0. It also seems to fail even if %nspace N; is used with a target language with %nspace support.
Still reproducible with git master shortly after 4.2.0. Looking at this afresh, the two delete_v calls are OK as those are for the temporary v(1.1.1) and v(2,2,2) objects passed to the comp constructor. The essential problem here is that comp_a_get returns a Python v object which wraps a pointer to the C++ v a inside the temporary comp object, but then delete_comp is called before we call v_x_get on that v. For this to work it seems either a reference to comp needs to be kept by the v returned by...
Still happens with current git master (shortly after SWIG 4.2.0) except the error is now a TypeError: TypeError: Wrong number or type of arguments for overloaded function 'IntVec___setitem__'.
Still present in current git master (shortly after 4.2.0). SWIG now handles both these cases: void f(double param = i.d()); void f(double param = Outer::d()); However the case reported here with both a namespace and an object is still not handled.
Still present in current git master (shortly after 4.2.0). SWIG now handles both these cases, but still not the case reported here with both a namespace and an object: void f(double param = i.d()); ``` void f(double param = Outer::d()); ```
Identifier warning for friend methods in a namespace
Fixed in a6ab9145115aa124ff9c98e2b3c39fde9f205760
Namespace breaks %ignore with unbound C++ operator<<
Fixed by a6ab9145115aa124ff9c98e2b3c39fde9f205760. All 6 of the %ignore directives shown now work.
SWIG-4.2.0 released
SWIG-4.2.0 released
SWIG-4.2.0 released