The following patch attempt to fix a memory leak happening when a
random class attribute is set. The internal instance dictionary is
created but never freed.
This fixes the problem for me, although I am not sure the patch
is correct.
<code>
p = MySWIGClass()
p.random_attribute = 0
</code>
Valgrind report:
==18267== 280 bytes in 1 blocks are definitely lost in loss record 1,372 of 1,780
==18267== at 0x4A0645D: malloc (in /usr/lib64/valgrind/vgpreload_memcheck-amd64-linux.so)
==18267== by 0x3A90A885DC: PyObject_Malloc (in /usr/lib64/libpython2.7.so.1.0)
==18267== by 0x3A90B101A8: _PyObject_GC_Malloc (in /usr/lib64/libpython2.7.so.1.0)
==18267== by 0x3A90B102AC: _PyObject_GC_New (in /usr/lib64/libpython2.7.so.1.0)
==18267== by 0x3A90A80943: PyDict_New (in /usr/lib64/libpython2.7.so.1.0)
==18267== by 0x3A90A6E8FC: PyFrame_New (in /usr/lib64/libpython2.7.so.1.0)
==18267== by 0x3A90AE1A65: PyEval_EvalCodeEx (in /usr/lib64/libpython2.7.so.1.0)
==18267== by 0x3A90AE088E: PyEval_EvalFrameEx (in /usr/lib64/libpython2.7.so.1.0)
==18267== by 0x3A90AE21DC: PyEval_EvalCodeEx (in /usr/lib64/libpython2.7.so.1.0)
==18267== by 0x3A90AE22E1: PyEval_EvalCode (in /usr/lib64/libpython2.7.so.1.0)
==18267== by 0x3A90AFB71E: ??? (in /usr/lib64/libpython2.7.so.1.0)
==18267== by 0x3A90AFC8DD: PyRun_FileExFlags (in /usr/lib64/libpython2.7.so.1.0)
==18267==
Attribute set within instance of a SWIG Python wrapped class are
stored in SwigPyObject->dict, which tp_dictoffset slot is pointing to.
However, SWIG wrapped classes did not have a __dict__ attribute.
Inheriting subclasses did not get the attribute either because the
SWIG wrapped classes initialize the tp_dictoffset slot:
From http://bugs.python.org/issue16272:
"If a type defines a nonzero tp_dictoffset, that type is responsible for
defining a `__dict__` slot as part of the tp_getset structures. Failure to
do so will result in the dict being inaccessible from Python via
`obj.__dict__` from instances of the type or subtypes."
Provide a SwigPyObject_get___dict__() function to retrieve the dict
attribute or create it when it does not exist yet (it is normally
created when setting attribute set), and a PyGetSetDef entry pointing
to this function.
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.