Normally, when using an interface file for python like this:
//example.i
%module example
%{
int a;
%}
int a;
the variable a is available in python via the command:
example.cvar.a
and has by default read and write access.
When using the the %immutable directive such as:
//example.i
%module example
%{
int a;
%}
%immutable
int a;
SWIG actually creates a example.cvar.a which is effectively read-only (that's what it's suppose to do)
but also create a another, separate variable example.a which has read-write permissions (not good at all !):
>>> import example
>>> example.a
0.0
>>> example.cvar.a
0.0
>>> example.cvar.a = 3
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
AttributeError: Variable a is read-only.
>>> example.a = 3
>>> example.a
3
I would say this is a feature rather than a bug. You don't actually have write access to the C++ variable. After setting example.a to 3, if you check example.cvar.a you should see that it is still 0.0. Setting example.a merely makes the python name point somewhere else (note that you can set it to anything, not just a number). It's unfortunate that this is possible, but the same is true for anything in the module (if you had a function named func, you could do example.func = 'foo').
%pythonnondynamic can be used to prevent this happening for proxy classes. I don't know of a feature for global variables though.
Yes, I agree. The same is true for anything in the module (e.g. we are allowed to do example.func = 'foo'). But then the question is: why is there 2 things created, 'example.cvar.a' *and* 'example.a' ? Without the %immutable command, there is only one variable created, 'example.cvar.a' . What is 'example.a' created for ? I ony found it by mistake as I typed too quickly and forgot the 'cvar'...and it confused me as to why it exits in the first place
This is still the case with git master.
Adding the
%immutable;
line results in this difference in the generatedexample.py
:The code that results in this seems to be the
!assignable
condition here inpython.cxx
:There's a similar issue in the
-builtin
case, but that is implemented via this code:generated by:
I think this is clearly a bug.
The idea that we can add the
example.a
wrapping because of the immutability seems flawed - it's true we don't need to relay updates to the C/C++ variable, but creating a value which is disconnected from the C/C++ value is buggy. Allowingexample.a
to be modified is one problem, but another is thata
in the C/C++ layer might change - consider this:Then: