Default values are no longer generated as Python code by default.
They must be explicitly turned on using the "python:defaultargs" feature.
Closes#294Closes#296
The problems in these two issues when "python:defaultargs" is turned
on still need to be fixed and should be addressed in separate patches.
The important thing is the default code generation is now fixed.
The original code was ported from the C# module. It looks like it
tried to avoid reading TLS data by using a shared counter. However,
without also synchronizing on the counter check (or using atomics)
the code is racy. While the races might be benign (the thread that
sets the exception also increments the counter, so when there is
actually an exception, the visible value will always be non-zero
even if it is outdated), they are still undefined behavior,
strictly speaking. Additionally, just using TLS isn't expensive
either.
There might be other cases where this happens when $dclassname
is used for code emitted into the proxy class itself, but so
far, there are none in the test suite or any bug reports.
Fixes unknown preprocessor directive error introduced in #217
commit 255c929c56
These were probably intended as script comments using # when C/C++
comments using // or /* */ should have been used.
variable. Only set the variable if another global variable is true,
but that variable is always false. The effect is that the variable is
never written, but as far as the compiler is concerned it might escape.
Also fixes li_std_vector_enum testcase when run with -threads.
Patch supplied on swig-devel mailing list on 12 Sep with details...
==============================================
I just wanted to mention that I found a crash issue in bug..
I am using SWIG 2.0.11 with python and have –threads enabled. I have a C++ std::vector that I instantiate in SWIG with %template. I also have a method in a class that returns this vector. I also include std_vector.i, btw..
When I iterate like so:
children = Action.getActionList()
for child in children:
pass
Everything is fine..
When I iterate like this:
for child in Action.getActionList()
pass
Product crashes.
The problem is the following. This code gets called first:
SWIGINTERN PyObject *_wrap_delete_SwigPyIterator(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
PyObject *resultobj = 0;
swig::SwigPyIterator *arg1 = (swig::SwigPyIterator *) 0 ;
void *argp1 = 0 ;
int res1 = 0 ;
PyObject * obj0 = 0 ;
if(!PyArg_UnpackTuple(args,(char *)"delete_SwigPyIterator",1,1,&obj0)) SWIG_fail;
res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_swig__SwigPyIterator, SWIG_POINTER_DISOWN | 0 );
if (!SWIG_IsOK(res1)) {
SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "delete_SwigPyIterator" "', argument " "1"" of type '" "swig::SwigPyIterator *""'");
}
arg1 = reinterpret_cast< swig::SwigPyIterator * >(argp1);
{
SWIG_PYTHON_THREAD_BEGIN_ALLOW;
delete arg1;
SWIG_PYTHON_THREAD_END_ALLOW;
}
resultobj = SWIG_Py_Void();
return resultobj;
fail:
return NULL;
}
Note the SWIG_PYTHON_THREAD_BEGIN_ALLOW/END_ALLOW. In between those two statements, we delete arg1. That in turn will eventually end up in this code:
namespace swig {
class SwigPtr_PyObject {
protected:
PyObject *_obj;
public:
… snip! …
~SwigPtr_PyObject()
{
Py_XDECREF(_obj);
}
Uh-oh! We call Py_XDECREF when we aren’t supposed to because we are in a SWIG_PYTHON_THREAD_BEGIN_ALLOW/END_ALLOW section!
This takes care of the issue:
namespace swig {
class SwigPtr_PyObject {
protected:
PyObject *_obj;
public:
… snip! …
~SwigPtr_PyObject()
{
SWIG_PYTHON_THREAD_BEGIN_BLOCK;
Py_XDECREF(_obj);
SWIG_PYTHON_THREAD_END_BLOCK;
}
There are several other methods in this class that use the Python API, but don’t have the BEGIN/END block defined. I’m not sure if they are required for all of them, but I believe they are..
I have attached a modified pyclasses.swg with what I believe are the correct changes. This code is from 2.0.11, but as far as I can tell, it’s the same as what is in 3.0.2…
Apologies for not doing more here (making/running tests, getting it in the code repository, etc..), but I’m under some pressure to get some unrelated things done…